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 ®exp)) != 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