10Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 20Sstevel@tonic-gate 30Sstevel@tonic-gate /* 40Sstevel@tonic-gate * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 50Sstevel@tonic-gate * 60Sstevel@tonic-gate * Openvision retains the copyright to derivative works of 70Sstevel@tonic-gate * this source code. Do *NOT* create a derivative of this 80Sstevel@tonic-gate * source code before consulting with your legal department. 90Sstevel@tonic-gate * Do *NOT* integrate *ANY* of this source code into another 100Sstevel@tonic-gate * product before consulting with your legal department. 110Sstevel@tonic-gate * 120Sstevel@tonic-gate * For further information, read the top-level Openvision 130Sstevel@tonic-gate * copyright which is contained in the top-level MIT Kerberos 140Sstevel@tonic-gate * copyright. 150Sstevel@tonic-gate * 160Sstevel@tonic-gate * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 170Sstevel@tonic-gate * 180Sstevel@tonic-gate */ 190Sstevel@tonic-gate 200Sstevel@tonic-gate 210Sstevel@tonic-gate /* 220Sstevel@tonic-gate * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved 230Sstevel@tonic-gate * 242881Smp153739 * $Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/svr_iters.c,v 1.6 2003/01/12 18:17:02 epeisach Exp $ 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate #if !defined(lint) && !defined(__CODECENTER__) 282881Smp153739 static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/svr_iters.c,v 1.6 2003/01/12 18:17:02 epeisach Exp $"; 290Sstevel@tonic-gate #endif 300Sstevel@tonic-gate 31*4960Swillf #include "autoconf.h" 320Sstevel@tonic-gate #if defined(HAVE_COMPILE) && defined(HAVE_STEP) 330Sstevel@tonic-gate #define SOLARIS_REGEXPS 340Sstevel@tonic-gate #elif defined(HAVE_REGCOMP) && defined(HAVE_REGEXEC) 350Sstevel@tonic-gate #define POSIX_REGEXPS 360Sstevel@tonic-gate #elif defined(HAVE_RE_COMP) && defined(HAVE_RE_EXEC) 370Sstevel@tonic-gate #define BSD_REGEXPS 380Sstevel@tonic-gate #else 390Sstevel@tonic-gate #error I cannot find any regexp functions 400Sstevel@tonic-gate #endif 410Sstevel@tonic-gate 420Sstevel@tonic-gate #include <sys/types.h> 430Sstevel@tonic-gate #include <string.h> 440Sstevel@tonic-gate #include <kadm5/admin.h> 450Sstevel@tonic-gate #ifdef SOLARIS_REGEXPS 460Sstevel@tonic-gate #include <regexpr.h> 470Sstevel@tonic-gate #endif 480Sstevel@tonic-gate #ifdef POSIX_REGEXPS 490Sstevel@tonic-gate #include <regex.h> 500Sstevel@tonic-gate #endif 510Sstevel@tonic-gate #include <stdlib.h> 520Sstevel@tonic-gate 530Sstevel@tonic-gate #include "server_internal.h" 540Sstevel@tonic-gate 550Sstevel@tonic-gate struct iter_data { 560Sstevel@tonic-gate krb5_context context; 572881Smp153739 char **names; 582881Smp153739 int n_names, sz_names; 592881Smp153739 unsigned int malloc_failed; 600Sstevel@tonic-gate char *exp; 610Sstevel@tonic-gate #ifdef SOLARIS_REGEXPS 620Sstevel@tonic-gate char *expbuf; 630Sstevel@tonic-gate #endif 640Sstevel@tonic-gate #ifdef POSIX_REGEXPS 650Sstevel@tonic-gate regex_t preg; 660Sstevel@tonic-gate #endif 670Sstevel@tonic-gate }; 680Sstevel@tonic-gate 690Sstevel@tonic-gate /* 700Sstevel@tonic-gate * Function: glob_to_regexp 710Sstevel@tonic-gate * 720Sstevel@tonic-gate * Arguments: 730Sstevel@tonic-gate * 740Sstevel@tonic-gate * glob (r) the shell-style glob (?*[]) to convert 750Sstevel@tonic-gate * realm (r) the default realm to append, or NULL 760Sstevel@tonic-gate * regexp (w) the ed-style regexp created from glob 770Sstevel@tonic-gate * 780Sstevel@tonic-gate * Effects: 790Sstevel@tonic-gate * 800Sstevel@tonic-gate * regexp is filled in with allocated memory contained a regular 810Sstevel@tonic-gate * expression to be used with re_comp/compile that matches what the 820Sstevel@tonic-gate * shell-style glob would match. If glob does not contain an "@" 830Sstevel@tonic-gate * character and realm is not NULL, "@*" is appended to the regexp. 840Sstevel@tonic-gate * 850Sstevel@tonic-gate * Conversion algorithm: 860Sstevel@tonic-gate * 870Sstevel@tonic-gate * quoted characters are copied quoted 880Sstevel@tonic-gate * ? is converted to . 890Sstevel@tonic-gate * * is converted to .* 900Sstevel@tonic-gate * active characters are quoted: ^, $, . 910Sstevel@tonic-gate * [ and ] are active but supported and have the same meaning, so 920Sstevel@tonic-gate * they are copied 930Sstevel@tonic-gate * other characters are copied 940Sstevel@tonic-gate * regexp is anchored with ^ and $ 950Sstevel@tonic-gate */ 962881Smp153739 static kadm5_ret_t glob_to_regexp(char *glob, char *realm, char **regexp) 970Sstevel@tonic-gate { 980Sstevel@tonic-gate int append_realm; 990Sstevel@tonic-gate char *p; 1000Sstevel@tonic-gate 1010Sstevel@tonic-gate /* validate the glob */ 1020Sstevel@tonic-gate if (glob[strlen(glob)-1] == '\\') 1030Sstevel@tonic-gate return EINVAL; 1040Sstevel@tonic-gate 1050Sstevel@tonic-gate /* A character of glob can turn into two in regexp, plus ^ and $ */ 1060Sstevel@tonic-gate /* and trailing null. If glob has no @, also allocate space for */ 1070Sstevel@tonic-gate /* the realm. */ 1080Sstevel@tonic-gate append_realm = (realm != NULL) && (strchr(glob, '@') == NULL); 1090Sstevel@tonic-gate p = (char *) malloc(strlen(glob)*2+ 3 + (append_realm ? 2 : 0)); 1100Sstevel@tonic-gate if (p == NULL) 1110Sstevel@tonic-gate return ENOMEM; 1120Sstevel@tonic-gate *regexp = p; 1130Sstevel@tonic-gate 1140Sstevel@tonic-gate *p++ = '^'; 1150Sstevel@tonic-gate while (*glob) { 1160Sstevel@tonic-gate switch (*glob) { 1170Sstevel@tonic-gate case '?': 1180Sstevel@tonic-gate *p++ = '.'; 1190Sstevel@tonic-gate break; 1200Sstevel@tonic-gate case '*': 1210Sstevel@tonic-gate *p++ = '.'; 1220Sstevel@tonic-gate *p++ = '*'; 1230Sstevel@tonic-gate break; 1240Sstevel@tonic-gate case '.': 1250Sstevel@tonic-gate case '^': 1260Sstevel@tonic-gate case '$': 1270Sstevel@tonic-gate *p++ = '\\'; 1280Sstevel@tonic-gate *p++ = *glob; 1290Sstevel@tonic-gate break; 1300Sstevel@tonic-gate case '\\': 1310Sstevel@tonic-gate *p++ = '\\'; 132*4960Swillf *p++ = *++glob; 1330Sstevel@tonic-gate break; 1340Sstevel@tonic-gate default: 1350Sstevel@tonic-gate *p++ = *glob; 1360Sstevel@tonic-gate break; 1370Sstevel@tonic-gate } 1380Sstevel@tonic-gate glob++; 1390Sstevel@tonic-gate } 1400Sstevel@tonic-gate 1410Sstevel@tonic-gate if (append_realm) { 1420Sstevel@tonic-gate *p++ = '@'; 1430Sstevel@tonic-gate *p++ = '*'; 1440Sstevel@tonic-gate } 1450Sstevel@tonic-gate 1460Sstevel@tonic-gate *p++ = '$'; 1470Sstevel@tonic-gate *p++ = '\0'; 1480Sstevel@tonic-gate return KADM5_OK; 1490Sstevel@tonic-gate } 1500Sstevel@tonic-gate 1512881Smp153739 static void get_either_iter(struct iter_data *data, char *name) 1520Sstevel@tonic-gate { 1532881Smp153739 int match; 1540Sstevel@tonic-gate #ifdef SOLARIS_REGEXPS 1552881Smp153739 match = (step(name, data->expbuf) != 0); 1560Sstevel@tonic-gate #endif 1570Sstevel@tonic-gate #ifdef POSIX_REGEXPS 1582881Smp153739 match = (regexec(&data->preg, name, 0, NULL, 0) == 0); 1590Sstevel@tonic-gate #endif 1600Sstevel@tonic-gate #ifdef BSD_REGEXPS 1612881Smp153739 match = (re_exec(name) != 0); 1620Sstevel@tonic-gate #endif 1632881Smp153739 if (match) { 1642881Smp153739 if (data->n_names == data->sz_names) { 1652881Smp153739 int new_sz = data->sz_names * 2; 1662881Smp153739 char **new_names = realloc(data->names, 1672881Smp153739 new_sz * sizeof(char *)); 1682881Smp153739 if (new_names) { 1692881Smp153739 data->names = new_names; 1702881Smp153739 data->sz_names = new_sz; 1712881Smp153739 } else { 1722881Smp153739 data->malloc_failed = 1; 1732881Smp153739 free(name); 1742881Smp153739 return; 1752881Smp153739 } 1762881Smp153739 } 1772881Smp153739 data->names[data->n_names++] = name; 1780Sstevel@tonic-gate } else 1790Sstevel@tonic-gate free(name); 1800Sstevel@tonic-gate } 1810Sstevel@tonic-gate 1822881Smp153739 static void get_pols_iter(void *data, osa_policy_ent_t entry) 1830Sstevel@tonic-gate { 1840Sstevel@tonic-gate char *name; 1850Sstevel@tonic-gate 1860Sstevel@tonic-gate if ((name = strdup(entry->name)) == NULL) 1870Sstevel@tonic-gate return; 1880Sstevel@tonic-gate get_either_iter(data, name); 1890Sstevel@tonic-gate } 1900Sstevel@tonic-gate 1912881Smp153739 static void get_princs_iter(void *data, krb5_principal princ) 1920Sstevel@tonic-gate { 1930Sstevel@tonic-gate struct iter_data *id = (struct iter_data *) data; 1940Sstevel@tonic-gate char *name; 1950Sstevel@tonic-gate 1960Sstevel@tonic-gate if (krb5_unparse_name(id->context, princ, &name) != 0) 1970Sstevel@tonic-gate return; 1980Sstevel@tonic-gate get_either_iter(data, name); 1990Sstevel@tonic-gate } 2000Sstevel@tonic-gate 2012881Smp153739 static kadm5_ret_t kadm5_get_either(int princ, 2020Sstevel@tonic-gate void *server_handle, 2030Sstevel@tonic-gate char *exp, 2040Sstevel@tonic-gate char ***princs, 2050Sstevel@tonic-gate int *count) 2060Sstevel@tonic-gate { 2070Sstevel@tonic-gate struct iter_data data; 2082881Smp153739 #ifdef BSD_REGEXPS 2092881Smp153739 char *msg; 2102881Smp153739 #endif 2112881Smp153739 char *regexp; 2122881Smp153739 int i, ret; 2130Sstevel@tonic-gate kadm5_server_handle_t handle = server_handle; 2140Sstevel@tonic-gate 2150Sstevel@tonic-gate *count = 0; 2160Sstevel@tonic-gate if (exp == NULL) 2170Sstevel@tonic-gate exp = "*"; 2180Sstevel@tonic-gate 2190Sstevel@tonic-gate CHECK_HANDLE(server_handle); 2200Sstevel@tonic-gate 2210Sstevel@tonic-gate if ((ret = glob_to_regexp(exp, princ ? handle->params.realm : NULL, 2220Sstevel@tonic-gate ®exp)) != KADM5_OK) 2230Sstevel@tonic-gate return ret; 2240Sstevel@tonic-gate 2250Sstevel@tonic-gate if ( 2260Sstevel@tonic-gate #ifdef SOLARIS_REGEXPS 2270Sstevel@tonic-gate ((data.expbuf = compile(regexp, NULL, NULL)) == NULL) 2280Sstevel@tonic-gate #endif 2290Sstevel@tonic-gate #ifdef POSIX_REGEXPS 2300Sstevel@tonic-gate ((regcomp(&data.preg, regexp, REG_NOSUB)) != 0) 2310Sstevel@tonic-gate #endif 2320Sstevel@tonic-gate #ifdef BSD_REGEXPS 2330Sstevel@tonic-gate ((msg = (char *) re_comp(regexp)) != NULL) 2340Sstevel@tonic-gate #endif 2350Sstevel@tonic-gate ) 2360Sstevel@tonic-gate { 2370Sstevel@tonic-gate /* XXX syslog msg or regerr(regerrno) */ 2380Sstevel@tonic-gate free(regexp); 2390Sstevel@tonic-gate return EINVAL; 2400Sstevel@tonic-gate } 2410Sstevel@tonic-gate 2422881Smp153739 data.n_names = 0; 2432881Smp153739 data.sz_names = 10; 2442881Smp153739 data.malloc_failed = 0; 2452881Smp153739 data.names = malloc(sizeof(char *) * data.sz_names); 2462881Smp153739 if (data.names == NULL) { 2470Sstevel@tonic-gate free(regexp); 2480Sstevel@tonic-gate return ENOMEM; 2490Sstevel@tonic-gate } 2500Sstevel@tonic-gate 2510Sstevel@tonic-gate if (princ) { 2520Sstevel@tonic-gate data.context = handle->context; 253*4960Swillf ret = kdb_iter_entry(handle, exp, get_princs_iter, (void *) &data); 2540Sstevel@tonic-gate } else { 255*4960Swillf ret = krb5_db_iter_policy(handle->context, exp, get_pols_iter, (void *)&data); 2560Sstevel@tonic-gate } 2570Sstevel@tonic-gate 2582881Smp153739 free(regexp); 2592881Smp153739 #ifdef POSIX_REGEXPS 2602881Smp153739 regfree(&data.preg); 2612881Smp153739 #endif 262*4960Swillf if ( !ret && data.malloc_failed) 2632881Smp153739 ret = ENOMEM; 264*4960Swillf if ( ret ) { 2652881Smp153739 for (i = 0; i < data.n_names; i++) 2662881Smp153739 free(data.names[i]); 2672881Smp153739 free(data.names); 2680Sstevel@tonic-gate return ret; 2690Sstevel@tonic-gate } 2700Sstevel@tonic-gate 2712881Smp153739 *princs = data.names; 2722881Smp153739 *count = data.n_names; 2730Sstevel@tonic-gate return KADM5_OK; 2740Sstevel@tonic-gate } 2750Sstevel@tonic-gate 2760Sstevel@tonic-gate kadm5_ret_t kadm5_get_principals(void *server_handle, 2770Sstevel@tonic-gate char *exp, 2780Sstevel@tonic-gate char ***princs, 2790Sstevel@tonic-gate int *count) 2800Sstevel@tonic-gate { 2810Sstevel@tonic-gate return kadm5_get_either(1, server_handle, exp, princs, count); 2820Sstevel@tonic-gate } 2830Sstevel@tonic-gate 2840Sstevel@tonic-gate kadm5_ret_t kadm5_get_policies(void *server_handle, 2850Sstevel@tonic-gate char *exp, 2860Sstevel@tonic-gate char ***pols, 2870Sstevel@tonic-gate int *count) 2880Sstevel@tonic-gate { 2890Sstevel@tonic-gate return kadm5_get_either(0, server_handle, exp, pols, count); 2900Sstevel@tonic-gate } 2910Sstevel@tonic-gate 292