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