xref: /onnv-gate/usr/src/lib/krb5/kadm5/srv/svr_iters.c (revision 7934:6aeeafc994de)
10Sstevel@tonic-gate 
20Sstevel@tonic-gate /*
30Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
40Sstevel@tonic-gate  *
50Sstevel@tonic-gate  *	Openvision retains the copyright to derivative works of
60Sstevel@tonic-gate  *	this source code.  Do *NOT* create a derivative of this
70Sstevel@tonic-gate  *	source code before consulting with your legal department.
80Sstevel@tonic-gate  *	Do *NOT* integrate *ANY* of this source code into another
90Sstevel@tonic-gate  *	product before consulting with your legal department.
100Sstevel@tonic-gate  *
110Sstevel@tonic-gate  *	For further information, read the top-level Openvision
120Sstevel@tonic-gate  *	copyright which is contained in the top-level MIT Kerberos
130Sstevel@tonic-gate  *	copyright.
140Sstevel@tonic-gate  *
150Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
160Sstevel@tonic-gate  *
170Sstevel@tonic-gate  */
180Sstevel@tonic-gate 
190Sstevel@tonic-gate 
200Sstevel@tonic-gate /*
210Sstevel@tonic-gate  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
220Sstevel@tonic-gate  *
23*7934SMark.Phalan@Sun.COM  * $Header$
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #if !defined(lint) && !defined(__CODECENTER__)
27*7934SMark.Phalan@Sun.COM static char *rcsid = "$Header$";
280Sstevel@tonic-gate #endif
290Sstevel@tonic-gate 
304960Swillf #include "autoconf.h"
310Sstevel@tonic-gate #if defined(HAVE_COMPILE) && defined(HAVE_STEP)
320Sstevel@tonic-gate #define SOLARIS_REGEXPS
330Sstevel@tonic-gate #elif defined(HAVE_REGCOMP) && defined(HAVE_REGEXEC)
340Sstevel@tonic-gate #define POSIX_REGEXPS
350Sstevel@tonic-gate #elif defined(HAVE_RE_COMP) && defined(HAVE_RE_EXEC)
360Sstevel@tonic-gate #define BSD_REGEXPS
370Sstevel@tonic-gate #else
380Sstevel@tonic-gate #error I cannot find any regexp functions
390Sstevel@tonic-gate #endif
400Sstevel@tonic-gate 
410Sstevel@tonic-gate #include	<sys/types.h>
420Sstevel@tonic-gate #include	<string.h>
43*7934SMark.Phalan@Sun.COM #include	"server_internal.h"
440Sstevel@tonic-gate #include	<kadm5/admin.h>
450Sstevel@tonic-gate #ifdef SOLARIS_REGEXPS
460Sstevel@tonic-gate #include	<regexpr.h>
470Sstevel@tonic-gate #endif
480Sstevel@tonic-gate #ifdef POSIX_REGEXPS
490Sstevel@tonic-gate #include	<regex.h>
500Sstevel@tonic-gate #endif
510Sstevel@tonic-gate #include <stdlib.h>
520Sstevel@tonic-gate 
530Sstevel@tonic-gate 
540Sstevel@tonic-gate struct iter_data {
550Sstevel@tonic-gate      krb5_context context;
562881Smp153739      char **names;
572881Smp153739      int n_names, sz_names;
582881Smp153739      unsigned int malloc_failed;
590Sstevel@tonic-gate      char *exp;
600Sstevel@tonic-gate #ifdef SOLARIS_REGEXPS
610Sstevel@tonic-gate      char *expbuf;
620Sstevel@tonic-gate #endif
630Sstevel@tonic-gate #ifdef POSIX_REGEXPS
640Sstevel@tonic-gate      regex_t preg;
650Sstevel@tonic-gate #endif
660Sstevel@tonic-gate };
670Sstevel@tonic-gate 
680Sstevel@tonic-gate /*
690Sstevel@tonic-gate  * Function: glob_to_regexp
700Sstevel@tonic-gate  *
710Sstevel@tonic-gate  * Arguments:
720Sstevel@tonic-gate  *
730Sstevel@tonic-gate  *	glob	(r) the shell-style glob (?*[]) to convert
740Sstevel@tonic-gate  *	realm	(r) the default realm to append, or NULL
750Sstevel@tonic-gate  *	regexp	(w) the ed-style regexp created from glob
760Sstevel@tonic-gate  *
770Sstevel@tonic-gate  * Effects:
780Sstevel@tonic-gate  *
790Sstevel@tonic-gate  * regexp is filled in with allocated memory contained a regular
800Sstevel@tonic-gate  * expression to be used with re_comp/compile that matches what the
810Sstevel@tonic-gate  * shell-style glob would match.  If glob does not contain an "@"
820Sstevel@tonic-gate  * character and realm is not NULL, "@*" is appended to the regexp.
830Sstevel@tonic-gate  *
840Sstevel@tonic-gate  * Conversion algorithm:
850Sstevel@tonic-gate  *
860Sstevel@tonic-gate  *	quoted characters are copied quoted
870Sstevel@tonic-gate  *	? is converted to .
880Sstevel@tonic-gate  *	* is converted to .*
890Sstevel@tonic-gate  * 	active characters are quoted: ^, $, .
900Sstevel@tonic-gate  *	[ and ] are active but supported and have the same meaning, so
910Sstevel@tonic-gate  *		they are copied
920Sstevel@tonic-gate  *	other characters are copied
930Sstevel@tonic-gate  *	regexp is anchored with ^ and $
940Sstevel@tonic-gate  */
glob_to_regexp(char * glob,char * realm,char ** regexp)952881Smp153739 static kadm5_ret_t glob_to_regexp(char *glob, char *realm, char **regexp)
960Sstevel@tonic-gate {
970Sstevel@tonic-gate      int append_realm;
980Sstevel@tonic-gate      char *p;
990Sstevel@tonic-gate 
1000Sstevel@tonic-gate      /* validate the glob */
1010Sstevel@tonic-gate      if (glob[strlen(glob)-1] == '\\')
1020Sstevel@tonic-gate 	  return EINVAL;
1030Sstevel@tonic-gate 
1040Sstevel@tonic-gate      /* A character of glob can turn into two in regexp, plus ^ and $ */
1050Sstevel@tonic-gate      /* and trailing null.  If glob has no @, also allocate space for */
1060Sstevel@tonic-gate      /* the realm. */
1070Sstevel@tonic-gate      append_realm = (realm != NULL) && (strchr(glob, '@') == NULL);
1080Sstevel@tonic-gate      p = (char *) malloc(strlen(glob)*2+ 3 + (append_realm ? 2 : 0));
1090Sstevel@tonic-gate      if (p == NULL)
1100Sstevel@tonic-gate 	  return ENOMEM;
1110Sstevel@tonic-gate      *regexp = p;
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate      *p++ = '^';
1140Sstevel@tonic-gate      while (*glob) {
1150Sstevel@tonic-gate 	  switch (*glob) {
1160Sstevel@tonic-gate 	  case '?':
1170Sstevel@tonic-gate 	       *p++ = '.';
1180Sstevel@tonic-gate 	       break;
1190Sstevel@tonic-gate 	  case '*':
1200Sstevel@tonic-gate 	       *p++ = '.';
1210Sstevel@tonic-gate 	       *p++ = '*';
1220Sstevel@tonic-gate 	       break;
1230Sstevel@tonic-gate 	  case '.':
1240Sstevel@tonic-gate 	  case '^':
1250Sstevel@tonic-gate 	  case '$':
1260Sstevel@tonic-gate 	       *p++ = '\\';
1270Sstevel@tonic-gate 	       *p++ = *glob;
1280Sstevel@tonic-gate 	       break;
1290Sstevel@tonic-gate 	  case '\\':
1300Sstevel@tonic-gate 	       *p++ = '\\';
1314960Swillf 	       *p++ = *++glob;
1320Sstevel@tonic-gate 	       break;
1330Sstevel@tonic-gate 	  default:
1340Sstevel@tonic-gate 	       *p++ = *glob;
1350Sstevel@tonic-gate 	       break;
1360Sstevel@tonic-gate 	  }
1370Sstevel@tonic-gate 	  glob++;
1380Sstevel@tonic-gate      }
1390Sstevel@tonic-gate 
1400Sstevel@tonic-gate      if (append_realm) {
1410Sstevel@tonic-gate 	  *p++ = '@';
1420Sstevel@tonic-gate 	  *p++ = '*';
1430Sstevel@tonic-gate      }
1440Sstevel@tonic-gate 
1450Sstevel@tonic-gate      *p++ = '$';
1460Sstevel@tonic-gate      *p++ = '\0';
1470Sstevel@tonic-gate      return KADM5_OK;
1480Sstevel@tonic-gate }
1490Sstevel@tonic-gate 
get_either_iter(struct iter_data * data,char * name)1502881Smp153739 static void get_either_iter(struct iter_data *data, char *name)
1510Sstevel@tonic-gate {
1522881Smp153739      int match;
1530Sstevel@tonic-gate #ifdef SOLARIS_REGEXPS
1542881Smp153739      match = (step(name, data->expbuf) != 0);
1550Sstevel@tonic-gate #endif
1560Sstevel@tonic-gate #ifdef POSIX_REGEXPS
1572881Smp153739      match = (regexec(&data->preg, name, 0, NULL, 0) == 0);
1580Sstevel@tonic-gate #endif
1590Sstevel@tonic-gate #ifdef BSD_REGEXPS
1602881Smp153739      match = (re_exec(name) != 0);
1610Sstevel@tonic-gate #endif
1622881Smp153739      if (match) {
1632881Smp153739 	  if (data->n_names == data->sz_names) {
1642881Smp153739 	       int new_sz = data->sz_names * 2;
1652881Smp153739 	       char **new_names = realloc(data->names,
1662881Smp153739 					  new_sz * sizeof(char *));
1672881Smp153739 	       if (new_names) {
1682881Smp153739 		    data->names = new_names;
1692881Smp153739 		    data->sz_names = new_sz;
1702881Smp153739 	       } else {
1712881Smp153739 		    data->malloc_failed = 1;
1722881Smp153739 		    free(name);
1732881Smp153739 		    return;
1742881Smp153739 	       }
1752881Smp153739 	  }
1762881Smp153739 	  data->names[data->n_names++] = name;
1770Sstevel@tonic-gate      } else
1780Sstevel@tonic-gate 	  free(name);
1790Sstevel@tonic-gate }
1800Sstevel@tonic-gate 
get_pols_iter(void * data,osa_policy_ent_t entry)1812881Smp153739 static void get_pols_iter(void *data, osa_policy_ent_t entry)
1820Sstevel@tonic-gate {
1830Sstevel@tonic-gate      char *name;
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate      if ((name = strdup(entry->name)) == NULL)
1860Sstevel@tonic-gate 	  return;
1870Sstevel@tonic-gate      get_either_iter(data, name);
1880Sstevel@tonic-gate }
1890Sstevel@tonic-gate 
get_princs_iter(void * data,krb5_principal princ)1902881Smp153739 static void get_princs_iter(void *data, krb5_principal princ)
1910Sstevel@tonic-gate {
1920Sstevel@tonic-gate      struct iter_data *id = (struct iter_data *) data;
1930Sstevel@tonic-gate      char *name;
1940Sstevel@tonic-gate 
1950Sstevel@tonic-gate      if (krb5_unparse_name(id->context, princ, &name) != 0)
1960Sstevel@tonic-gate 	  return;
1970Sstevel@tonic-gate      get_either_iter(data, name);
1980Sstevel@tonic-gate }
1990Sstevel@tonic-gate 
kadm5_get_either(int princ,void * server_handle,char * exp,char *** princs,int * count)2002881Smp153739 static kadm5_ret_t kadm5_get_either(int princ,
2010Sstevel@tonic-gate 				       void *server_handle,
2020Sstevel@tonic-gate 				       char *exp,
2030Sstevel@tonic-gate 				       char ***princs,
2040Sstevel@tonic-gate 				       int *count)
2050Sstevel@tonic-gate {
2060Sstevel@tonic-gate      struct iter_data data;
2072881Smp153739 #ifdef BSD_REGEXPS
2082881Smp153739      char *msg;
2092881Smp153739 #endif
2102881Smp153739      char *regexp;
2112881Smp153739      int i, ret;
2120Sstevel@tonic-gate      kadm5_server_handle_t handle = server_handle;
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate      *count = 0;
2150Sstevel@tonic-gate      if (exp == NULL)
2160Sstevel@tonic-gate 	  exp = "*";
2170Sstevel@tonic-gate 
2180Sstevel@tonic-gate      CHECK_HANDLE(server_handle);
2190Sstevel@tonic-gate 
2200Sstevel@tonic-gate      if ((ret = glob_to_regexp(exp, princ ? handle->params.realm : NULL,
2210Sstevel@tonic-gate 			       &regexp)) != KADM5_OK)
2220Sstevel@tonic-gate 	  return ret;
2230Sstevel@tonic-gate 
2240Sstevel@tonic-gate      if (
2250Sstevel@tonic-gate #ifdef SOLARIS_REGEXPS
2260Sstevel@tonic-gate 	 ((data.expbuf = compile(regexp, NULL, NULL)) == NULL)
2270Sstevel@tonic-gate #endif
2280Sstevel@tonic-gate #ifdef POSIX_REGEXPS
2290Sstevel@tonic-gate 	 ((regcomp(&data.preg, regexp, REG_NOSUB)) != 0)
2300Sstevel@tonic-gate #endif
2310Sstevel@tonic-gate #ifdef BSD_REGEXPS
2320Sstevel@tonic-gate 	 ((msg = (char *) re_comp(regexp)) != NULL)
2330Sstevel@tonic-gate #endif
2340Sstevel@tonic-gate 	 )
2350Sstevel@tonic-gate      {
2360Sstevel@tonic-gate 	  /* XXX syslog msg or regerr(regerrno) */
2370Sstevel@tonic-gate 	  free(regexp);
2380Sstevel@tonic-gate 	  return EINVAL;
2390Sstevel@tonic-gate      }
2400Sstevel@tonic-gate 
2412881Smp153739      data.n_names = 0;
2422881Smp153739      data.sz_names = 10;
2432881Smp153739      data.malloc_failed = 0;
2442881Smp153739      data.names = malloc(sizeof(char *) * data.sz_names);
2452881Smp153739      if (data.names == NULL) {
2460Sstevel@tonic-gate 	  free(regexp);
2470Sstevel@tonic-gate 	  return ENOMEM;
2480Sstevel@tonic-gate      }
2490Sstevel@tonic-gate 
2500Sstevel@tonic-gate      if (princ) {
2510Sstevel@tonic-gate 	  data.context = handle->context;
2524960Swillf 	  ret = kdb_iter_entry(handle, exp, get_princs_iter, (void *) &data);
2530Sstevel@tonic-gate      } else {
2544960Swillf 	  ret = krb5_db_iter_policy(handle->context, exp, get_pols_iter, (void *)&data);
2550Sstevel@tonic-gate      }
2560Sstevel@tonic-gate 
2572881Smp153739      free(regexp);
2582881Smp153739 #ifdef POSIX_REGEXPS
2592881Smp153739      regfree(&data.preg);
2602881Smp153739 #endif
2614960Swillf      if ( !ret && data.malloc_failed)
2622881Smp153739 	  ret = ENOMEM;
2634960Swillf      if ( ret ) {
2642881Smp153739 	  for (i = 0; i < data.n_names; i++)
2652881Smp153739 	       free(data.names[i]);
2662881Smp153739 	  free(data.names);
2670Sstevel@tonic-gate 	  return ret;
2680Sstevel@tonic-gate      }
2690Sstevel@tonic-gate 
2702881Smp153739      *princs = data.names;
2712881Smp153739      *count = data.n_names;
2720Sstevel@tonic-gate      return KADM5_OK;
2730Sstevel@tonic-gate }
2740Sstevel@tonic-gate 
kadm5_get_principals(void * server_handle,char * exp,char *** princs,int * count)2750Sstevel@tonic-gate kadm5_ret_t kadm5_get_principals(void *server_handle,
2760Sstevel@tonic-gate 					   char *exp,
2770Sstevel@tonic-gate 					   char ***princs,
2780Sstevel@tonic-gate 					   int *count)
2790Sstevel@tonic-gate {
2800Sstevel@tonic-gate      return kadm5_get_either(1, server_handle, exp, princs, count);
2810Sstevel@tonic-gate }
2820Sstevel@tonic-gate 
kadm5_get_policies(void * server_handle,char * exp,char *** pols,int * count)2830Sstevel@tonic-gate kadm5_ret_t kadm5_get_policies(void *server_handle,
2840Sstevel@tonic-gate 					   char *exp,
2850Sstevel@tonic-gate 					   char ***pols,
2860Sstevel@tonic-gate 					   int *count)
2870Sstevel@tonic-gate {
2880Sstevel@tonic-gate      return kadm5_get_either(0, server_handle, exp, pols, count);
2890Sstevel@tonic-gate }
2900Sstevel@tonic-gate 
291