xref: /titanic_51/usr/src/lib/krb5/kadm5/srv/svr_iters.c (revision 159d09a20817016f09b3ea28d1bdada4a336bb91)
17c478bd9Sstevel@tonic-gate 
27c478bd9Sstevel@tonic-gate /*
37c478bd9Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
47c478bd9Sstevel@tonic-gate  *
57c478bd9Sstevel@tonic-gate  *	Openvision retains the copyright to derivative works of
67c478bd9Sstevel@tonic-gate  *	this source code.  Do *NOT* create a derivative of this
77c478bd9Sstevel@tonic-gate  *	source code before consulting with your legal department.
87c478bd9Sstevel@tonic-gate  *	Do *NOT* integrate *ANY* of this source code into another
97c478bd9Sstevel@tonic-gate  *	product before consulting with your legal department.
107c478bd9Sstevel@tonic-gate  *
117c478bd9Sstevel@tonic-gate  *	For further information, read the top-level Openvision
127c478bd9Sstevel@tonic-gate  *	copyright which is contained in the top-level MIT Kerberos
137c478bd9Sstevel@tonic-gate  *	copyright.
147c478bd9Sstevel@tonic-gate  *
157c478bd9Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
167c478bd9Sstevel@tonic-gate  *
177c478bd9Sstevel@tonic-gate  */
187c478bd9Sstevel@tonic-gate 
197c478bd9Sstevel@tonic-gate 
207c478bd9Sstevel@tonic-gate /*
217c478bd9Sstevel@tonic-gate  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
227c478bd9Sstevel@tonic-gate  *
23*159d09a2SMark Phalan  * $Header$
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #if !defined(lint) && !defined(__CODECENTER__)
27*159d09a2SMark Phalan static char *rcsid = "$Header$";
287c478bd9Sstevel@tonic-gate #endif
297c478bd9Sstevel@tonic-gate 
3054925bf6Swillf #include "autoconf.h"
317c478bd9Sstevel@tonic-gate #if defined(HAVE_COMPILE) && defined(HAVE_STEP)
327c478bd9Sstevel@tonic-gate #define SOLARIS_REGEXPS
337c478bd9Sstevel@tonic-gate #elif defined(HAVE_REGCOMP) && defined(HAVE_REGEXEC)
347c478bd9Sstevel@tonic-gate #define POSIX_REGEXPS
357c478bd9Sstevel@tonic-gate #elif defined(HAVE_RE_COMP) && defined(HAVE_RE_EXEC)
367c478bd9Sstevel@tonic-gate #define BSD_REGEXPS
377c478bd9Sstevel@tonic-gate #else
387c478bd9Sstevel@tonic-gate #error I cannot find any regexp functions
397c478bd9Sstevel@tonic-gate #endif
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate #include	<sys/types.h>
427c478bd9Sstevel@tonic-gate #include	<string.h>
43*159d09a2SMark Phalan #include	"server_internal.h"
447c478bd9Sstevel@tonic-gate #include	<kadm5/admin.h>
457c478bd9Sstevel@tonic-gate #ifdef SOLARIS_REGEXPS
467c478bd9Sstevel@tonic-gate #include	<regexpr.h>
477c478bd9Sstevel@tonic-gate #endif
487c478bd9Sstevel@tonic-gate #ifdef POSIX_REGEXPS
497c478bd9Sstevel@tonic-gate #include	<regex.h>
507c478bd9Sstevel@tonic-gate #endif
517c478bd9Sstevel@tonic-gate #include <stdlib.h>
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate struct iter_data {
557c478bd9Sstevel@tonic-gate      krb5_context context;
5656a424ccSmp153739      char **names;
5756a424ccSmp153739      int n_names, sz_names;
5856a424ccSmp153739      unsigned int malloc_failed;
597c478bd9Sstevel@tonic-gate      char *exp;
607c478bd9Sstevel@tonic-gate #ifdef SOLARIS_REGEXPS
617c478bd9Sstevel@tonic-gate      char *expbuf;
627c478bd9Sstevel@tonic-gate #endif
637c478bd9Sstevel@tonic-gate #ifdef POSIX_REGEXPS
647c478bd9Sstevel@tonic-gate      regex_t preg;
657c478bd9Sstevel@tonic-gate #endif
667c478bd9Sstevel@tonic-gate };
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate /*
697c478bd9Sstevel@tonic-gate  * Function: glob_to_regexp
707c478bd9Sstevel@tonic-gate  *
717c478bd9Sstevel@tonic-gate  * Arguments:
727c478bd9Sstevel@tonic-gate  *
737c478bd9Sstevel@tonic-gate  *	glob	(r) the shell-style glob (?*[]) to convert
747c478bd9Sstevel@tonic-gate  *	realm	(r) the default realm to append, or NULL
757c478bd9Sstevel@tonic-gate  *	regexp	(w) the ed-style regexp created from glob
767c478bd9Sstevel@tonic-gate  *
777c478bd9Sstevel@tonic-gate  * Effects:
787c478bd9Sstevel@tonic-gate  *
797c478bd9Sstevel@tonic-gate  * regexp is filled in with allocated memory contained a regular
807c478bd9Sstevel@tonic-gate  * expression to be used with re_comp/compile that matches what the
817c478bd9Sstevel@tonic-gate  * shell-style glob would match.  If glob does not contain an "@"
827c478bd9Sstevel@tonic-gate  * character and realm is not NULL, "@*" is appended to the regexp.
837c478bd9Sstevel@tonic-gate  *
847c478bd9Sstevel@tonic-gate  * Conversion algorithm:
857c478bd9Sstevel@tonic-gate  *
867c478bd9Sstevel@tonic-gate  *	quoted characters are copied quoted
877c478bd9Sstevel@tonic-gate  *	? is converted to .
887c478bd9Sstevel@tonic-gate  *	* is converted to .*
897c478bd9Sstevel@tonic-gate  * 	active characters are quoted: ^, $, .
907c478bd9Sstevel@tonic-gate  *	[ and ] are active but supported and have the same meaning, so
917c478bd9Sstevel@tonic-gate  *		they are copied
927c478bd9Sstevel@tonic-gate  *	other characters are copied
937c478bd9Sstevel@tonic-gate  *	regexp is anchored with ^ and $
947c478bd9Sstevel@tonic-gate  */
9556a424ccSmp153739 static kadm5_ret_t glob_to_regexp(char *glob, char *realm, char **regexp)
967c478bd9Sstevel@tonic-gate {
977c478bd9Sstevel@tonic-gate      int append_realm;
987c478bd9Sstevel@tonic-gate      char *p;
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate      /* validate the glob */
1017c478bd9Sstevel@tonic-gate      if (glob[strlen(glob)-1] == '\\')
1027c478bd9Sstevel@tonic-gate 	  return EINVAL;
1037c478bd9Sstevel@tonic-gate 
1047c478bd9Sstevel@tonic-gate      /* A character of glob can turn into two in regexp, plus ^ and $ */
1057c478bd9Sstevel@tonic-gate      /* and trailing null.  If glob has no @, also allocate space for */
1067c478bd9Sstevel@tonic-gate      /* the realm. */
1077c478bd9Sstevel@tonic-gate      append_realm = (realm != NULL) && (strchr(glob, '@') == NULL);
1087c478bd9Sstevel@tonic-gate      p = (char *) malloc(strlen(glob)*2+ 3 + (append_realm ? 2 : 0));
1097c478bd9Sstevel@tonic-gate      if (p == NULL)
1107c478bd9Sstevel@tonic-gate 	  return ENOMEM;
1117c478bd9Sstevel@tonic-gate      *regexp = p;
1127c478bd9Sstevel@tonic-gate 
1137c478bd9Sstevel@tonic-gate      *p++ = '^';
1147c478bd9Sstevel@tonic-gate      while (*glob) {
1157c478bd9Sstevel@tonic-gate 	  switch (*glob) {
1167c478bd9Sstevel@tonic-gate 	  case '?':
1177c478bd9Sstevel@tonic-gate 	       *p++ = '.';
1187c478bd9Sstevel@tonic-gate 	       break;
1197c478bd9Sstevel@tonic-gate 	  case '*':
1207c478bd9Sstevel@tonic-gate 	       *p++ = '.';
1217c478bd9Sstevel@tonic-gate 	       *p++ = '*';
1227c478bd9Sstevel@tonic-gate 	       break;
1237c478bd9Sstevel@tonic-gate 	  case '.':
1247c478bd9Sstevel@tonic-gate 	  case '^':
1257c478bd9Sstevel@tonic-gate 	  case '$':
1267c478bd9Sstevel@tonic-gate 	       *p++ = '\\';
1277c478bd9Sstevel@tonic-gate 	       *p++ = *glob;
1287c478bd9Sstevel@tonic-gate 	       break;
1297c478bd9Sstevel@tonic-gate 	  case '\\':
1307c478bd9Sstevel@tonic-gate 	       *p++ = '\\';
13154925bf6Swillf 	       *p++ = *++glob;
1327c478bd9Sstevel@tonic-gate 	       break;
1337c478bd9Sstevel@tonic-gate 	  default:
1347c478bd9Sstevel@tonic-gate 	       *p++ = *glob;
1357c478bd9Sstevel@tonic-gate 	       break;
1367c478bd9Sstevel@tonic-gate 	  }
1377c478bd9Sstevel@tonic-gate 	  glob++;
1387c478bd9Sstevel@tonic-gate      }
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate      if (append_realm) {
1417c478bd9Sstevel@tonic-gate 	  *p++ = '@';
1427c478bd9Sstevel@tonic-gate 	  *p++ = '*';
1437c478bd9Sstevel@tonic-gate      }
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate      *p++ = '$';
1467c478bd9Sstevel@tonic-gate      *p++ = '\0';
1477c478bd9Sstevel@tonic-gate      return KADM5_OK;
1487c478bd9Sstevel@tonic-gate }
1497c478bd9Sstevel@tonic-gate 
15056a424ccSmp153739 static void get_either_iter(struct iter_data *data, char *name)
1517c478bd9Sstevel@tonic-gate {
15256a424ccSmp153739      int match;
1537c478bd9Sstevel@tonic-gate #ifdef SOLARIS_REGEXPS
15456a424ccSmp153739      match = (step(name, data->expbuf) != 0);
1557c478bd9Sstevel@tonic-gate #endif
1567c478bd9Sstevel@tonic-gate #ifdef POSIX_REGEXPS
15756a424ccSmp153739      match = (regexec(&data->preg, name, 0, NULL, 0) == 0);
1587c478bd9Sstevel@tonic-gate #endif
1597c478bd9Sstevel@tonic-gate #ifdef BSD_REGEXPS
16056a424ccSmp153739      match = (re_exec(name) != 0);
1617c478bd9Sstevel@tonic-gate #endif
16256a424ccSmp153739      if (match) {
16356a424ccSmp153739 	  if (data->n_names == data->sz_names) {
16456a424ccSmp153739 	       int new_sz = data->sz_names * 2;
16556a424ccSmp153739 	       char **new_names = realloc(data->names,
16656a424ccSmp153739 					  new_sz * sizeof(char *));
16756a424ccSmp153739 	       if (new_names) {
16856a424ccSmp153739 		    data->names = new_names;
16956a424ccSmp153739 		    data->sz_names = new_sz;
17056a424ccSmp153739 	       } else {
17156a424ccSmp153739 		    data->malloc_failed = 1;
17256a424ccSmp153739 		    free(name);
17356a424ccSmp153739 		    return;
17456a424ccSmp153739 	       }
17556a424ccSmp153739 	  }
17656a424ccSmp153739 	  data->names[data->n_names++] = name;
1777c478bd9Sstevel@tonic-gate      } else
1787c478bd9Sstevel@tonic-gate 	  free(name);
1797c478bd9Sstevel@tonic-gate }
1807c478bd9Sstevel@tonic-gate 
18156a424ccSmp153739 static void get_pols_iter(void *data, osa_policy_ent_t entry)
1827c478bd9Sstevel@tonic-gate {
1837c478bd9Sstevel@tonic-gate      char *name;
1847c478bd9Sstevel@tonic-gate 
1857c478bd9Sstevel@tonic-gate      if ((name = strdup(entry->name)) == NULL)
1867c478bd9Sstevel@tonic-gate 	  return;
1877c478bd9Sstevel@tonic-gate      get_either_iter(data, name);
1887c478bd9Sstevel@tonic-gate }
1897c478bd9Sstevel@tonic-gate 
19056a424ccSmp153739 static void get_princs_iter(void *data, krb5_principal princ)
1917c478bd9Sstevel@tonic-gate {
1927c478bd9Sstevel@tonic-gate      struct iter_data *id = (struct iter_data *) data;
1937c478bd9Sstevel@tonic-gate      char *name;
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate      if (krb5_unparse_name(id->context, princ, &name) != 0)
1967c478bd9Sstevel@tonic-gate 	  return;
1977c478bd9Sstevel@tonic-gate      get_either_iter(data, name);
1987c478bd9Sstevel@tonic-gate }
1997c478bd9Sstevel@tonic-gate 
20056a424ccSmp153739 static kadm5_ret_t kadm5_get_either(int princ,
2017c478bd9Sstevel@tonic-gate 				       void *server_handle,
2027c478bd9Sstevel@tonic-gate 				       char *exp,
2037c478bd9Sstevel@tonic-gate 				       char ***princs,
2047c478bd9Sstevel@tonic-gate 				       int *count)
2057c478bd9Sstevel@tonic-gate {
2067c478bd9Sstevel@tonic-gate      struct iter_data data;
20756a424ccSmp153739 #ifdef BSD_REGEXPS
20856a424ccSmp153739      char *msg;
20956a424ccSmp153739 #endif
21056a424ccSmp153739      char *regexp;
21156a424ccSmp153739      int i, ret;
2127c478bd9Sstevel@tonic-gate      kadm5_server_handle_t handle = server_handle;
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate      *count = 0;
2157c478bd9Sstevel@tonic-gate      if (exp == NULL)
2167c478bd9Sstevel@tonic-gate 	  exp = "*";
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate      CHECK_HANDLE(server_handle);
2197c478bd9Sstevel@tonic-gate 
2207c478bd9Sstevel@tonic-gate      if ((ret = glob_to_regexp(exp, princ ? handle->params.realm : NULL,
2217c478bd9Sstevel@tonic-gate 			       &regexp)) != KADM5_OK)
2227c478bd9Sstevel@tonic-gate 	  return ret;
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate      if (
2257c478bd9Sstevel@tonic-gate #ifdef SOLARIS_REGEXPS
2267c478bd9Sstevel@tonic-gate 	 ((data.expbuf = compile(regexp, NULL, NULL)) == NULL)
2277c478bd9Sstevel@tonic-gate #endif
2287c478bd9Sstevel@tonic-gate #ifdef POSIX_REGEXPS
2297c478bd9Sstevel@tonic-gate 	 ((regcomp(&data.preg, regexp, REG_NOSUB)) != 0)
2307c478bd9Sstevel@tonic-gate #endif
2317c478bd9Sstevel@tonic-gate #ifdef BSD_REGEXPS
2327c478bd9Sstevel@tonic-gate 	 ((msg = (char *) re_comp(regexp)) != NULL)
2337c478bd9Sstevel@tonic-gate #endif
2347c478bd9Sstevel@tonic-gate 	 )
2357c478bd9Sstevel@tonic-gate      {
2367c478bd9Sstevel@tonic-gate 	  /* XXX syslog msg or regerr(regerrno) */
2377c478bd9Sstevel@tonic-gate 	  free(regexp);
2387c478bd9Sstevel@tonic-gate 	  return EINVAL;
2397c478bd9Sstevel@tonic-gate      }
2407c478bd9Sstevel@tonic-gate 
24156a424ccSmp153739      data.n_names = 0;
24256a424ccSmp153739      data.sz_names = 10;
24356a424ccSmp153739      data.malloc_failed = 0;
24456a424ccSmp153739      data.names = malloc(sizeof(char *) * data.sz_names);
24556a424ccSmp153739      if (data.names == NULL) {
2467c478bd9Sstevel@tonic-gate 	  free(regexp);
2477c478bd9Sstevel@tonic-gate 	  return ENOMEM;
2487c478bd9Sstevel@tonic-gate      }
2497c478bd9Sstevel@tonic-gate 
2507c478bd9Sstevel@tonic-gate      if (princ) {
2517c478bd9Sstevel@tonic-gate 	  data.context = handle->context;
25254925bf6Swillf 	  ret = kdb_iter_entry(handle, exp, get_princs_iter, (void *) &data);
2537c478bd9Sstevel@tonic-gate      } else {
25454925bf6Swillf 	  ret = krb5_db_iter_policy(handle->context, exp, get_pols_iter, (void *)&data);
2557c478bd9Sstevel@tonic-gate      }
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate      free(regexp);
25856a424ccSmp153739 #ifdef POSIX_REGEXPS
25956a424ccSmp153739      regfree(&data.preg);
26056a424ccSmp153739 #endif
26154925bf6Swillf      if ( !ret && data.malloc_failed)
26256a424ccSmp153739 	  ret = ENOMEM;
26354925bf6Swillf      if ( ret ) {
26456a424ccSmp153739 	  for (i = 0; i < data.n_names; i++)
26556a424ccSmp153739 	       free(data.names[i]);
26656a424ccSmp153739 	  free(data.names);
2677c478bd9Sstevel@tonic-gate 	  return ret;
2687c478bd9Sstevel@tonic-gate      }
2697c478bd9Sstevel@tonic-gate 
27056a424ccSmp153739      *princs = data.names;
27156a424ccSmp153739      *count = data.n_names;
2727c478bd9Sstevel@tonic-gate      return KADM5_OK;
2737c478bd9Sstevel@tonic-gate }
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate kadm5_ret_t kadm5_get_principals(void *server_handle,
2767c478bd9Sstevel@tonic-gate 					   char *exp,
2777c478bd9Sstevel@tonic-gate 					   char ***princs,
2787c478bd9Sstevel@tonic-gate 					   int *count)
2797c478bd9Sstevel@tonic-gate {
2807c478bd9Sstevel@tonic-gate      return kadm5_get_either(1, server_handle, exp, princs, count);
2817c478bd9Sstevel@tonic-gate }
2827c478bd9Sstevel@tonic-gate 
2837c478bd9Sstevel@tonic-gate kadm5_ret_t kadm5_get_policies(void *server_handle,
2847c478bd9Sstevel@tonic-gate 					   char *exp,
2857c478bd9Sstevel@tonic-gate 					   char ***pols,
2867c478bd9Sstevel@tonic-gate 					   int *count)
2877c478bd9Sstevel@tonic-gate {
2887c478bd9Sstevel@tonic-gate      return kadm5_get_either(0, server_handle, exp, pols, count);
2897c478bd9Sstevel@tonic-gate }
2907c478bd9Sstevel@tonic-gate 
291