xref: /onnv-gate/usr/src/lib/krb5/kadm5/srv/svr_iters.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
2*0Sstevel@tonic-gate 
3*0Sstevel@tonic-gate /*
4*0Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
5*0Sstevel@tonic-gate  *
6*0Sstevel@tonic-gate  *	Openvision retains the copyright to derivative works of
7*0Sstevel@tonic-gate  *	this source code.  Do *NOT* create a derivative of this
8*0Sstevel@tonic-gate  *	source code before consulting with your legal department.
9*0Sstevel@tonic-gate  *	Do *NOT* integrate *ANY* of this source code into another
10*0Sstevel@tonic-gate  *	product before consulting with your legal department.
11*0Sstevel@tonic-gate  *
12*0Sstevel@tonic-gate  *	For further information, read the top-level Openvision
13*0Sstevel@tonic-gate  *	copyright which is contained in the top-level MIT Kerberos
14*0Sstevel@tonic-gate  *	copyright.
15*0Sstevel@tonic-gate  *
16*0Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
17*0Sstevel@tonic-gate  *
18*0Sstevel@tonic-gate  */
19*0Sstevel@tonic-gate 
20*0Sstevel@tonic-gate 
21*0Sstevel@tonic-gate /*
22*0Sstevel@tonic-gate  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
23*0Sstevel@tonic-gate  *
24*0Sstevel@tonic-gate  * $Header: /afs/athena.mit.edu/astaff/project/krbdev/.cvsroot/src/lib/kadm5/srv/svr_iters.c,v 1.2 1996/11/07 21:43:14 bjaspan Exp $
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #if !defined(lint) && !defined(__CODECENTER__)
28*0Sstevel@tonic-gate static char *rcsid = "$Header: /afs/athena.mit.edu/astaff/project/krbdev/.cvsroot/src/lib/kadm5/srv/svr_iters.c,v 1.2 1996/11/07 21:43:14 bjaspan Exp $";
29*0Sstevel@tonic-gate #endif
30*0Sstevel@tonic-gate 
31*0Sstevel@tonic-gate #if defined(HAVE_COMPILE) && defined(HAVE_STEP)
32*0Sstevel@tonic-gate #define SOLARIS_REGEXPS
33*0Sstevel@tonic-gate #elif defined(HAVE_REGCOMP) && defined(HAVE_REGEXEC)
34*0Sstevel@tonic-gate #define POSIX_REGEXPS
35*0Sstevel@tonic-gate #elif defined(HAVE_RE_COMP) && defined(HAVE_RE_EXEC)
36*0Sstevel@tonic-gate #define BSD_REGEXPS
37*0Sstevel@tonic-gate #else
38*0Sstevel@tonic-gate #error I cannot find any regexp functions
39*0Sstevel@tonic-gate #endif
40*0Sstevel@tonic-gate 
41*0Sstevel@tonic-gate #include	<sys/types.h>
42*0Sstevel@tonic-gate #include	<string.h>
43*0Sstevel@tonic-gate #include	<kadm5/admin.h>
44*0Sstevel@tonic-gate #include	"adb.h"
45*0Sstevel@tonic-gate #include	<dyn/dyn.h>
46*0Sstevel@tonic-gate #ifdef SOLARIS_REGEXPS
47*0Sstevel@tonic-gate #include	<regexpr.h>
48*0Sstevel@tonic-gate #endif
49*0Sstevel@tonic-gate #ifdef POSIX_REGEXPS
50*0Sstevel@tonic-gate #include	<regex.h>
51*0Sstevel@tonic-gate #endif
52*0Sstevel@tonic-gate #include <stdlib.h>
53*0Sstevel@tonic-gate 
54*0Sstevel@tonic-gate #include	"server_internal.h"
55*0Sstevel@tonic-gate 
56*0Sstevel@tonic-gate krb5_error_code
57*0Sstevel@tonic-gate kdb_iter_entry(kadm5_server_handle_t handle,
58*0Sstevel@tonic-gate 	       void (*iter_fct)(void *, krb5_principal), void *data);
59*0Sstevel@tonic-gate 
60*0Sstevel@tonic-gate struct iter_data {
61*0Sstevel@tonic-gate      krb5_context context;
62*0Sstevel@tonic-gate      DynObject matches;
63*0Sstevel@tonic-gate      char *exp;
64*0Sstevel@tonic-gate #ifdef SOLARIS_REGEXPS
65*0Sstevel@tonic-gate      char *expbuf;
66*0Sstevel@tonic-gate #endif
67*0Sstevel@tonic-gate #ifdef POSIX_REGEXPS
68*0Sstevel@tonic-gate      regex_t preg;
69*0Sstevel@tonic-gate #endif
70*0Sstevel@tonic-gate };
71*0Sstevel@tonic-gate 
72*0Sstevel@tonic-gate /*
73*0Sstevel@tonic-gate  * Function: glob_to_regexp
74*0Sstevel@tonic-gate  *
75*0Sstevel@tonic-gate  * Arguments:
76*0Sstevel@tonic-gate  *
77*0Sstevel@tonic-gate  *	glob	(r) the shell-style glob (?*[]) to convert
78*0Sstevel@tonic-gate  *	realm	(r) the default realm to append, or NULL
79*0Sstevel@tonic-gate  *	regexp	(w) the ed-style regexp created from glob
80*0Sstevel@tonic-gate  *
81*0Sstevel@tonic-gate  * Effects:
82*0Sstevel@tonic-gate  *
83*0Sstevel@tonic-gate  * regexp is filled in with allocated memory contained a regular
84*0Sstevel@tonic-gate  * expression to be used with re_comp/compile that matches what the
85*0Sstevel@tonic-gate  * shell-style glob would match.  If glob does not contain an "@"
86*0Sstevel@tonic-gate  * character and realm is not NULL, "@*" is appended to the regexp.
87*0Sstevel@tonic-gate  *
88*0Sstevel@tonic-gate  * Conversion algorithm:
89*0Sstevel@tonic-gate  *
90*0Sstevel@tonic-gate  *	quoted characters are copied quoted
91*0Sstevel@tonic-gate  *	? is converted to .
92*0Sstevel@tonic-gate  *	* is converted to .*
93*0Sstevel@tonic-gate  * 	active characters are quoted: ^, $, .
94*0Sstevel@tonic-gate  *	[ and ] are active but supported and have the same meaning, so
95*0Sstevel@tonic-gate  *		they are copied
96*0Sstevel@tonic-gate  *	other characters are copied
97*0Sstevel@tonic-gate  *	regexp is anchored with ^ and $
98*0Sstevel@tonic-gate  */
99*0Sstevel@tonic-gate kadm5_ret_t glob_to_regexp(char *glob, char *realm, char **regexp)
100*0Sstevel@tonic-gate {
101*0Sstevel@tonic-gate      int append_realm;
102*0Sstevel@tonic-gate      char *p;
103*0Sstevel@tonic-gate 
104*0Sstevel@tonic-gate      /* validate the glob */
105*0Sstevel@tonic-gate      if (glob[strlen(glob)-1] == '\\')
106*0Sstevel@tonic-gate 	  return EINVAL;
107*0Sstevel@tonic-gate 
108*0Sstevel@tonic-gate      /* A character of glob can turn into two in regexp, plus ^ and $ */
109*0Sstevel@tonic-gate      /* and trailing null.  If glob has no @, also allocate space for */
110*0Sstevel@tonic-gate      /* the realm. */
111*0Sstevel@tonic-gate      append_realm = (realm != NULL) && (strchr(glob, '@') == NULL);
112*0Sstevel@tonic-gate      p = (char *) malloc(strlen(glob)*2+ 3 + (append_realm ? 2 : 0));
113*0Sstevel@tonic-gate      if (p == NULL)
114*0Sstevel@tonic-gate 	  return ENOMEM;
115*0Sstevel@tonic-gate      *regexp = p;
116*0Sstevel@tonic-gate 
117*0Sstevel@tonic-gate      *p++ = '^';
118*0Sstevel@tonic-gate      while (*glob) {
119*0Sstevel@tonic-gate 	  switch (*glob) {
120*0Sstevel@tonic-gate 	  case '?':
121*0Sstevel@tonic-gate 	       *p++ = '.';
122*0Sstevel@tonic-gate 	       break;
123*0Sstevel@tonic-gate 	  case '*':
124*0Sstevel@tonic-gate 	       *p++ = '.';
125*0Sstevel@tonic-gate 	       *p++ = '*';
126*0Sstevel@tonic-gate 	       break;
127*0Sstevel@tonic-gate 	  case '.':
128*0Sstevel@tonic-gate 	  case '^':
129*0Sstevel@tonic-gate 	  case '$':
130*0Sstevel@tonic-gate 	       *p++ = '\\';
131*0Sstevel@tonic-gate 	       *p++ = *glob;
132*0Sstevel@tonic-gate 	       break;
133*0Sstevel@tonic-gate 	  case '\\':
134*0Sstevel@tonic-gate 	       *p++ = '\\';
135*0Sstevel@tonic-gate 	       *p++ = ++*glob;
136*0Sstevel@tonic-gate 	       break;
137*0Sstevel@tonic-gate 	  default:
138*0Sstevel@tonic-gate 	       *p++ = *glob;
139*0Sstevel@tonic-gate 	       break;
140*0Sstevel@tonic-gate 	  }
141*0Sstevel@tonic-gate 	  glob++;
142*0Sstevel@tonic-gate      }
143*0Sstevel@tonic-gate 
144*0Sstevel@tonic-gate      if (append_realm) {
145*0Sstevel@tonic-gate 	  *p++ = '@';
146*0Sstevel@tonic-gate 	  *p++ = '*';
147*0Sstevel@tonic-gate      }
148*0Sstevel@tonic-gate 
149*0Sstevel@tonic-gate      *p++ = '$';
150*0Sstevel@tonic-gate      *p++ = '\0';
151*0Sstevel@tonic-gate      return KADM5_OK;
152*0Sstevel@tonic-gate }
153*0Sstevel@tonic-gate 
154*0Sstevel@tonic-gate void get_either_iter(struct iter_data *data, char *name)
155*0Sstevel@tonic-gate {
156*0Sstevel@tonic-gate      if (
157*0Sstevel@tonic-gate #ifdef SOLARIS_REGEXPS
158*0Sstevel@tonic-gate 	 (step(name, data->expbuf) != 0)
159*0Sstevel@tonic-gate #endif
160*0Sstevel@tonic-gate #ifdef POSIX_REGEXPS
161*0Sstevel@tonic-gate 	 (regexec(&data->preg, name, 0, NULL, 0) == 0)
162*0Sstevel@tonic-gate #endif
163*0Sstevel@tonic-gate #ifdef BSD_REGEXPS
164*0Sstevel@tonic-gate 	 (re_exec(name) != 0)
165*0Sstevel@tonic-gate #endif
166*0Sstevel@tonic-gate 	 )
167*0Sstevel@tonic-gate      {
168*0Sstevel@tonic-gate 	  (void) DynAdd(data->matches, &name);
169*0Sstevel@tonic-gate      } else
170*0Sstevel@tonic-gate 	  free(name);
171*0Sstevel@tonic-gate }
172*0Sstevel@tonic-gate 
173*0Sstevel@tonic-gate void get_pols_iter(void *data, osa_policy_ent_t entry)
174*0Sstevel@tonic-gate {
175*0Sstevel@tonic-gate      char *name;
176*0Sstevel@tonic-gate 
177*0Sstevel@tonic-gate      if ((name = strdup(entry->name)) == NULL)
178*0Sstevel@tonic-gate 	  return;
179*0Sstevel@tonic-gate      get_either_iter(data, name);
180*0Sstevel@tonic-gate }
181*0Sstevel@tonic-gate 
182*0Sstevel@tonic-gate void get_princs_iter(void *data, krb5_principal princ)
183*0Sstevel@tonic-gate {
184*0Sstevel@tonic-gate      struct iter_data *id = (struct iter_data *) data;
185*0Sstevel@tonic-gate      char *name;
186*0Sstevel@tonic-gate 
187*0Sstevel@tonic-gate      if (krb5_unparse_name(id->context, princ, &name) != 0)
188*0Sstevel@tonic-gate 	  return;
189*0Sstevel@tonic-gate      get_either_iter(data, name);
190*0Sstevel@tonic-gate }
191*0Sstevel@tonic-gate 
192*0Sstevel@tonic-gate kadm5_ret_t kadm5_get_either(int princ,
193*0Sstevel@tonic-gate 				       void *server_handle,
194*0Sstevel@tonic-gate 				       char *exp,
195*0Sstevel@tonic-gate 				       char ***princs,
196*0Sstevel@tonic-gate 				       int *count)
197*0Sstevel@tonic-gate {
198*0Sstevel@tonic-gate      struct iter_data data;
199*0Sstevel@tonic-gate      char *msg, *regexp;
200*0Sstevel@tonic-gate      int ret;
201*0Sstevel@tonic-gate      kadm5_server_handle_t handle = server_handle;
202*0Sstevel@tonic-gate 
203*0Sstevel@tonic-gate      *count = 0;
204*0Sstevel@tonic-gate      if (exp == NULL)
205*0Sstevel@tonic-gate 	  exp = "*";
206*0Sstevel@tonic-gate 
207*0Sstevel@tonic-gate      CHECK_HANDLE(server_handle);
208*0Sstevel@tonic-gate 
209*0Sstevel@tonic-gate      if ((ret = glob_to_regexp(exp, princ ? handle->params.realm : NULL,
210*0Sstevel@tonic-gate 			       &regexp)) != KADM5_OK)
211*0Sstevel@tonic-gate 	  return ret;
212*0Sstevel@tonic-gate 
213*0Sstevel@tonic-gate      if (
214*0Sstevel@tonic-gate #ifdef SOLARIS_REGEXPS
215*0Sstevel@tonic-gate 	 ((data.expbuf = compile(regexp, NULL, NULL)) == NULL)
216*0Sstevel@tonic-gate #endif
217*0Sstevel@tonic-gate #ifdef POSIX_REGEXPS
218*0Sstevel@tonic-gate 	 ((regcomp(&data.preg, regexp, REG_NOSUB)) != 0)
219*0Sstevel@tonic-gate #endif
220*0Sstevel@tonic-gate #ifdef BSD_REGEXPS
221*0Sstevel@tonic-gate 	 ((msg = (char *) re_comp(regexp)) != NULL)
222*0Sstevel@tonic-gate #endif
223*0Sstevel@tonic-gate 	 )
224*0Sstevel@tonic-gate      {
225*0Sstevel@tonic-gate 	  /* XXX syslog msg or regerr(regerrno) */
226*0Sstevel@tonic-gate 	  free(regexp);
227*0Sstevel@tonic-gate 	  return EINVAL;
228*0Sstevel@tonic-gate      }
229*0Sstevel@tonic-gate 
230*0Sstevel@tonic-gate      if ((data.matches = DynCreate(sizeof(char *), -4)) == NULL) {
231*0Sstevel@tonic-gate 	  free(regexp);
232*0Sstevel@tonic-gate 	  return ENOMEM;
233*0Sstevel@tonic-gate      }
234*0Sstevel@tonic-gate 
235*0Sstevel@tonic-gate      if (princ) {
236*0Sstevel@tonic-gate 	  data.context = handle->context;
237*0Sstevel@tonic-gate 	  ret = kdb_iter_entry(handle, get_princs_iter, (void *) &data);
238*0Sstevel@tonic-gate      } else {
239*0Sstevel@tonic-gate 	  ret = osa_adb_iter_policy(handle->policy_db, get_pols_iter, (void *)&data);
240*0Sstevel@tonic-gate      }
241*0Sstevel@tonic-gate 
242*0Sstevel@tonic-gate      if (ret != OSA_ADB_OK) {
243*0Sstevel@tonic-gate 	  free(regexp);
244*0Sstevel@tonic-gate 	  DynDestroy(data.matches);
245*0Sstevel@tonic-gate 	  return ret;
246*0Sstevel@tonic-gate      }
247*0Sstevel@tonic-gate 
248*0Sstevel@tonic-gate      (*princs) = (char **) DynArray(data.matches);
249*0Sstevel@tonic-gate      *count = DynSize(data.matches);
250*0Sstevel@tonic-gate      DynRelease(data.matches);
251*0Sstevel@tonic-gate      free(regexp);
252*0Sstevel@tonic-gate      return KADM5_OK;
253*0Sstevel@tonic-gate }
254*0Sstevel@tonic-gate 
255*0Sstevel@tonic-gate kadm5_ret_t kadm5_get_principals(void *server_handle,
256*0Sstevel@tonic-gate 					   char *exp,
257*0Sstevel@tonic-gate 					   char ***princs,
258*0Sstevel@tonic-gate 					   int *count)
259*0Sstevel@tonic-gate {
260*0Sstevel@tonic-gate      return kadm5_get_either(1, server_handle, exp, princs, count);
261*0Sstevel@tonic-gate }
262*0Sstevel@tonic-gate 
263*0Sstevel@tonic-gate kadm5_ret_t kadm5_get_policies(void *server_handle,
264*0Sstevel@tonic-gate 					   char *exp,
265*0Sstevel@tonic-gate 					   char ***pols,
266*0Sstevel@tonic-gate 					   int *count)
267*0Sstevel@tonic-gate {
268*0Sstevel@tonic-gate      return kadm5_get_either(0, server_handle, exp, pols, count);
269*0Sstevel@tonic-gate }
270*0Sstevel@tonic-gate 
271