dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / krb5 / kadm5 / srv / svr_iters.c
blob5759a82aedf9922cee0bac751f1febe5283d4344
2 /*
3 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
5 * Openvision retains the copyright to derivative works of
6 * this source code. Do *NOT* create a derivative of this
7 * source code before consulting with your legal department.
8 * Do *NOT* integrate *ANY* of this source code into another
9 * product before consulting with your legal department.
11 * For further information, read the top-level Openvision
12 * copyright which is contained in the top-level MIT Kerberos
13 * copyright.
15 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
21 * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
23 * $Header$
26 static char *rcsid = "$Header$";
28 #include "autoconf.h"
29 #if defined(HAVE_COMPILE) && defined(HAVE_STEP)
30 #define SOLARIS_REGEXPS
31 #elif defined(HAVE_REGCOMP) && defined(HAVE_REGEXEC)
32 #define POSIX_REGEXPS
33 #elif defined(HAVE_RE_COMP) && defined(HAVE_RE_EXEC)
34 #define BSD_REGEXPS
35 #else
36 #error I cannot find any regexp functions
37 #endif
39 #include <sys/types.h>
40 #include <string.h>
41 #include "server_internal.h"
42 #include <kadm5/admin.h>
43 #ifdef SOLARIS_REGEXPS
44 #include <regexpr.h>
45 #endif
46 #ifdef POSIX_REGEXPS
47 #include <regex.h>
48 #endif
49 #include <stdlib.h>
52 struct iter_data {
53 krb5_context context;
54 char **names;
55 int n_names, sz_names;
56 unsigned int malloc_failed;
57 char *exp;
58 #ifdef SOLARIS_REGEXPS
59 char *expbuf;
60 #endif
61 #ifdef POSIX_REGEXPS
62 regex_t preg;
63 #endif
67 * Function: glob_to_regexp
69 * Arguments:
71 * glob (r) the shell-style glob (?*[]) to convert
72 * realm (r) the default realm to append, or NULL
73 * regexp (w) the ed-style regexp created from glob
75 * Effects:
77 * regexp is filled in with allocated memory contained a regular
78 * expression to be used with re_comp/compile that matches what the
79 * shell-style glob would match. If glob does not contain an "@"
80 * character and realm is not NULL, "@*" is appended to the regexp.
82 * Conversion algorithm:
84 * quoted characters are copied quoted
85 * ? is converted to .
86 * * is converted to .*
87 * active characters are quoted: ^, $, .
88 * [ and ] are active but supported and have the same meaning, so
89 * they are copied
90 * other characters are copied
91 * regexp is anchored with ^ and $
93 static kadm5_ret_t glob_to_regexp(char *glob, char *realm, char **regexp)
95 int append_realm;
96 char *p;
98 /* validate the glob */
99 if (glob[strlen(glob)-1] == '\\')
100 return EINVAL;
102 /* A character of glob can turn into two in regexp, plus ^ and $ */
103 /* and trailing null. If glob has no @, also allocate space for */
104 /* the realm. */
105 append_realm = (realm != NULL) && (strchr(glob, '@') == NULL);
106 p = (char *) malloc(strlen(glob)*2+ 3 + (append_realm ? 2 : 0));
107 if (p == NULL)
108 return ENOMEM;
109 *regexp = p;
111 *p++ = '^';
112 while (*glob) {
113 switch (*glob) {
114 case '?':
115 *p++ = '.';
116 break;
117 case '*':
118 *p++ = '.';
119 *p++ = '*';
120 break;
121 case '.':
122 case '^':
123 case '$':
124 *p++ = '\\';
125 *p++ = *glob;
126 break;
127 case '\\':
128 *p++ = '\\';
129 *p++ = *++glob;
130 break;
131 default:
132 *p++ = *glob;
133 break;
135 glob++;
138 if (append_realm) {
139 *p++ = '@';
140 *p++ = '*';
143 *p++ = '$';
144 *p++ = '\0';
145 return KADM5_OK;
148 static void get_either_iter(struct iter_data *data, char *name)
150 int match;
151 #ifdef SOLARIS_REGEXPS
152 match = (step(name, data->expbuf) != 0);
153 #endif
154 #ifdef POSIX_REGEXPS
155 match = (regexec(&data->preg, name, 0, NULL, 0) == 0);
156 #endif
157 #ifdef BSD_REGEXPS
158 match = (re_exec(name) != 0);
159 #endif
160 if (match) {
161 if (data->n_names == data->sz_names) {
162 int new_sz = data->sz_names * 2;
163 char **new_names = reallocarray(data->names, new_sz,
164 sizeof(char *));
165 if (new_names) {
166 data->names = new_names;
167 data->sz_names = new_sz;
168 } else {
169 data->malloc_failed = 1;
170 free(name);
171 return;
174 data->names[data->n_names++] = name;
175 } else
176 free(name);
179 static void get_pols_iter(void *data, osa_policy_ent_t entry)
181 char *name;
183 if ((name = strdup(entry->name)) == NULL)
184 return;
185 get_either_iter(data, name);
188 static void get_princs_iter(void *data, krb5_principal princ)
190 struct iter_data *id = (struct iter_data *) data;
191 char *name;
193 if (krb5_unparse_name(id->context, princ, &name) != 0)
194 return;
195 get_either_iter(data, name);
198 static kadm5_ret_t kadm5_get_either(int princ,
199 void *server_handle,
200 char *exp,
201 char ***princs,
202 int *count)
204 struct iter_data data;
205 #ifdef BSD_REGEXPS
206 char *msg;
207 #endif
208 char *regexp;
209 int i, ret;
210 kadm5_server_handle_t handle = server_handle;
212 *count = 0;
213 if (exp == NULL)
214 exp = "*";
216 CHECK_HANDLE(server_handle);
218 if ((ret = glob_to_regexp(exp, princ ? handle->params.realm : NULL,
219 &regexp)) != KADM5_OK)
220 return ret;
222 if (
223 #ifdef SOLARIS_REGEXPS
224 ((data.expbuf = compile(regexp, NULL, NULL)) == NULL)
225 #endif
226 #ifdef POSIX_REGEXPS
227 ((regcomp(&data.preg, regexp, REG_NOSUB)) != 0)
228 #endif
229 #ifdef BSD_REGEXPS
230 ((msg = (char *) re_comp(regexp)) != NULL)
231 #endif
234 /* XXX syslog msg or regerr(regerrno) */
235 free(regexp);
236 return EINVAL;
239 data.n_names = 0;
240 data.sz_names = 10;
241 data.malloc_failed = 0;
242 data.names = malloc(sizeof(char *) * data.sz_names);
243 if (data.names == NULL) {
244 free(regexp);
245 return ENOMEM;
248 if (princ) {
249 data.context = handle->context;
250 ret = kdb_iter_entry(handle, exp, get_princs_iter, (void *) &data);
251 } else {
252 ret = krb5_db_iter_policy(handle->context, exp, get_pols_iter, (void *)&data);
255 free(regexp);
256 #ifdef POSIX_REGEXPS
257 regfree(&data.preg);
258 #endif
259 if ( !ret && data.malloc_failed)
260 ret = ENOMEM;
261 if ( ret ) {
262 for (i = 0; i < data.n_names; i++)
263 free(data.names[i]);
264 free(data.names);
265 return ret;
268 *princs = data.names;
269 *count = data.n_names;
270 return KADM5_OK;
273 kadm5_ret_t kadm5_get_principals(void *server_handle,
274 char *exp,
275 char ***princs,
276 int *count)
278 return kadm5_get_either(1, server_handle, exp, princs, count);
281 kadm5_ret_t kadm5_get_policies(void *server_handle,
282 char *exp,
283 char ***pols,
284 int *count)
286 return kadm5_get_either(0, server_handle, exp, pols, count);