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