17c478bd9Sstevel@tonic-gate 27c478bd9Sstevel@tonic-gate /* 37c478bd9Sstevel@tonic-gate * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 47c478bd9Sstevel@tonic-gate * 57c478bd9Sstevel@tonic-gate * Openvision retains the copyright to derivative works of 67c478bd9Sstevel@tonic-gate * this source code. Do *NOT* create a derivative of this 77c478bd9Sstevel@tonic-gate * source code before consulting with your legal department. 87c478bd9Sstevel@tonic-gate * Do *NOT* integrate *ANY* of this source code into another 97c478bd9Sstevel@tonic-gate * product before consulting with your legal department. 107c478bd9Sstevel@tonic-gate * 117c478bd9Sstevel@tonic-gate * For further information, read the top-level Openvision 127c478bd9Sstevel@tonic-gate * copyright which is contained in the top-level MIT Kerberos 137c478bd9Sstevel@tonic-gate * copyright. 147c478bd9Sstevel@tonic-gate * 157c478bd9Sstevel@tonic-gate * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 167c478bd9Sstevel@tonic-gate * 177c478bd9Sstevel@tonic-gate */ 187c478bd9Sstevel@tonic-gate 197c478bd9Sstevel@tonic-gate 207c478bd9Sstevel@tonic-gate /* 217c478bd9Sstevel@tonic-gate * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved 227c478bd9Sstevel@tonic-gate * 23*159d09a2SMark Phalan * $Header$ 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #if !defined(lint) && !defined(__CODECENTER__) 27*159d09a2SMark Phalan static char *rcsid = "$Header$"; 287c478bd9Sstevel@tonic-gate #endif 297c478bd9Sstevel@tonic-gate 3054925bf6Swillf #include "autoconf.h" 317c478bd9Sstevel@tonic-gate #if defined(HAVE_COMPILE) && defined(HAVE_STEP) 327c478bd9Sstevel@tonic-gate #define SOLARIS_REGEXPS 337c478bd9Sstevel@tonic-gate #elif defined(HAVE_REGCOMP) && defined(HAVE_REGEXEC) 347c478bd9Sstevel@tonic-gate #define POSIX_REGEXPS 357c478bd9Sstevel@tonic-gate #elif defined(HAVE_RE_COMP) && defined(HAVE_RE_EXEC) 367c478bd9Sstevel@tonic-gate #define BSD_REGEXPS 377c478bd9Sstevel@tonic-gate #else 387c478bd9Sstevel@tonic-gate #error I cannot find any regexp functions 397c478bd9Sstevel@tonic-gate #endif 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate #include <sys/types.h> 427c478bd9Sstevel@tonic-gate #include <string.h> 43*159d09a2SMark Phalan #include "server_internal.h" 447c478bd9Sstevel@tonic-gate #include <kadm5/admin.h> 457c478bd9Sstevel@tonic-gate #ifdef SOLARIS_REGEXPS 467c478bd9Sstevel@tonic-gate #include <regexpr.h> 477c478bd9Sstevel@tonic-gate #endif 487c478bd9Sstevel@tonic-gate #ifdef POSIX_REGEXPS 497c478bd9Sstevel@tonic-gate #include <regex.h> 507c478bd9Sstevel@tonic-gate #endif 517c478bd9Sstevel@tonic-gate #include <stdlib.h> 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate struct iter_data { 557c478bd9Sstevel@tonic-gate krb5_context context; 5656a424ccSmp153739 char **names; 5756a424ccSmp153739 int n_names, sz_names; 5856a424ccSmp153739 unsigned int malloc_failed; 597c478bd9Sstevel@tonic-gate char *exp; 607c478bd9Sstevel@tonic-gate #ifdef SOLARIS_REGEXPS 617c478bd9Sstevel@tonic-gate char *expbuf; 627c478bd9Sstevel@tonic-gate #endif 637c478bd9Sstevel@tonic-gate #ifdef POSIX_REGEXPS 647c478bd9Sstevel@tonic-gate regex_t preg; 657c478bd9Sstevel@tonic-gate #endif 667c478bd9Sstevel@tonic-gate }; 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate /* 697c478bd9Sstevel@tonic-gate * Function: glob_to_regexp 707c478bd9Sstevel@tonic-gate * 717c478bd9Sstevel@tonic-gate * Arguments: 727c478bd9Sstevel@tonic-gate * 737c478bd9Sstevel@tonic-gate * glob (r) the shell-style glob (?*[]) to convert 747c478bd9Sstevel@tonic-gate * realm (r) the default realm to append, or NULL 757c478bd9Sstevel@tonic-gate * regexp (w) the ed-style regexp created from glob 767c478bd9Sstevel@tonic-gate * 777c478bd9Sstevel@tonic-gate * Effects: 787c478bd9Sstevel@tonic-gate * 797c478bd9Sstevel@tonic-gate * regexp is filled in with allocated memory contained a regular 807c478bd9Sstevel@tonic-gate * expression to be used with re_comp/compile that matches what the 817c478bd9Sstevel@tonic-gate * shell-style glob would match. If glob does not contain an "@" 827c478bd9Sstevel@tonic-gate * character and realm is not NULL, "@*" is appended to the regexp. 837c478bd9Sstevel@tonic-gate * 847c478bd9Sstevel@tonic-gate * Conversion algorithm: 857c478bd9Sstevel@tonic-gate * 867c478bd9Sstevel@tonic-gate * quoted characters are copied quoted 877c478bd9Sstevel@tonic-gate * ? is converted to . 887c478bd9Sstevel@tonic-gate * * is converted to .* 897c478bd9Sstevel@tonic-gate * active characters are quoted: ^, $, . 907c478bd9Sstevel@tonic-gate * [ and ] are active but supported and have the same meaning, so 917c478bd9Sstevel@tonic-gate * they are copied 927c478bd9Sstevel@tonic-gate * other characters are copied 937c478bd9Sstevel@tonic-gate * regexp is anchored with ^ and $ 947c478bd9Sstevel@tonic-gate */ 9556a424ccSmp153739 static kadm5_ret_t glob_to_regexp(char *glob, char *realm, char **regexp) 967c478bd9Sstevel@tonic-gate { 977c478bd9Sstevel@tonic-gate int append_realm; 987c478bd9Sstevel@tonic-gate char *p; 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate /* validate the glob */ 1017c478bd9Sstevel@tonic-gate if (glob[strlen(glob)-1] == '\\') 1027c478bd9Sstevel@tonic-gate return EINVAL; 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate /* A character of glob can turn into two in regexp, plus ^ and $ */ 1057c478bd9Sstevel@tonic-gate /* and trailing null. If glob has no @, also allocate space for */ 1067c478bd9Sstevel@tonic-gate /* the realm. */ 1077c478bd9Sstevel@tonic-gate append_realm = (realm != NULL) && (strchr(glob, '@') == NULL); 1087c478bd9Sstevel@tonic-gate p = (char *) malloc(strlen(glob)*2+ 3 + (append_realm ? 2 : 0)); 1097c478bd9Sstevel@tonic-gate if (p == NULL) 1107c478bd9Sstevel@tonic-gate return ENOMEM; 1117c478bd9Sstevel@tonic-gate *regexp = p; 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate *p++ = '^'; 1147c478bd9Sstevel@tonic-gate while (*glob) { 1157c478bd9Sstevel@tonic-gate switch (*glob) { 1167c478bd9Sstevel@tonic-gate case '?': 1177c478bd9Sstevel@tonic-gate *p++ = '.'; 1187c478bd9Sstevel@tonic-gate break; 1197c478bd9Sstevel@tonic-gate case '*': 1207c478bd9Sstevel@tonic-gate *p++ = '.'; 1217c478bd9Sstevel@tonic-gate *p++ = '*'; 1227c478bd9Sstevel@tonic-gate break; 1237c478bd9Sstevel@tonic-gate case '.': 1247c478bd9Sstevel@tonic-gate case '^': 1257c478bd9Sstevel@tonic-gate case '$': 1267c478bd9Sstevel@tonic-gate *p++ = '\\'; 1277c478bd9Sstevel@tonic-gate *p++ = *glob; 1287c478bd9Sstevel@tonic-gate break; 1297c478bd9Sstevel@tonic-gate case '\\': 1307c478bd9Sstevel@tonic-gate *p++ = '\\'; 13154925bf6Swillf *p++ = *++glob; 1327c478bd9Sstevel@tonic-gate break; 1337c478bd9Sstevel@tonic-gate default: 1347c478bd9Sstevel@tonic-gate *p++ = *glob; 1357c478bd9Sstevel@tonic-gate break; 1367c478bd9Sstevel@tonic-gate } 1377c478bd9Sstevel@tonic-gate glob++; 1387c478bd9Sstevel@tonic-gate } 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate if (append_realm) { 1417c478bd9Sstevel@tonic-gate *p++ = '@'; 1427c478bd9Sstevel@tonic-gate *p++ = '*'; 1437c478bd9Sstevel@tonic-gate } 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate *p++ = '$'; 1467c478bd9Sstevel@tonic-gate *p++ = '\0'; 1477c478bd9Sstevel@tonic-gate return KADM5_OK; 1487c478bd9Sstevel@tonic-gate } 1497c478bd9Sstevel@tonic-gate 15056a424ccSmp153739 static void get_either_iter(struct iter_data *data, char *name) 1517c478bd9Sstevel@tonic-gate { 15256a424ccSmp153739 int match; 1537c478bd9Sstevel@tonic-gate #ifdef SOLARIS_REGEXPS 15456a424ccSmp153739 match = (step(name, data->expbuf) != 0); 1557c478bd9Sstevel@tonic-gate #endif 1567c478bd9Sstevel@tonic-gate #ifdef POSIX_REGEXPS 15756a424ccSmp153739 match = (regexec(&data->preg, name, 0, NULL, 0) == 0); 1587c478bd9Sstevel@tonic-gate #endif 1597c478bd9Sstevel@tonic-gate #ifdef BSD_REGEXPS 16056a424ccSmp153739 match = (re_exec(name) != 0); 1617c478bd9Sstevel@tonic-gate #endif 16256a424ccSmp153739 if (match) { 16356a424ccSmp153739 if (data->n_names == data->sz_names) { 16456a424ccSmp153739 int new_sz = data->sz_names * 2; 16556a424ccSmp153739 char **new_names = realloc(data->names, 16656a424ccSmp153739 new_sz * sizeof(char *)); 16756a424ccSmp153739 if (new_names) { 16856a424ccSmp153739 data->names = new_names; 16956a424ccSmp153739 data->sz_names = new_sz; 17056a424ccSmp153739 } else { 17156a424ccSmp153739 data->malloc_failed = 1; 17256a424ccSmp153739 free(name); 17356a424ccSmp153739 return; 17456a424ccSmp153739 } 17556a424ccSmp153739 } 17656a424ccSmp153739 data->names[data->n_names++] = name; 1777c478bd9Sstevel@tonic-gate } else 1787c478bd9Sstevel@tonic-gate free(name); 1797c478bd9Sstevel@tonic-gate } 1807c478bd9Sstevel@tonic-gate 18156a424ccSmp153739 static void get_pols_iter(void *data, osa_policy_ent_t entry) 1827c478bd9Sstevel@tonic-gate { 1837c478bd9Sstevel@tonic-gate char *name; 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate if ((name = strdup(entry->name)) == NULL) 1867c478bd9Sstevel@tonic-gate return; 1877c478bd9Sstevel@tonic-gate get_either_iter(data, name); 1887c478bd9Sstevel@tonic-gate } 1897c478bd9Sstevel@tonic-gate 19056a424ccSmp153739 static void get_princs_iter(void *data, krb5_principal princ) 1917c478bd9Sstevel@tonic-gate { 1927c478bd9Sstevel@tonic-gate struct iter_data *id = (struct iter_data *) data; 1937c478bd9Sstevel@tonic-gate char *name; 1947c478bd9Sstevel@tonic-gate 1957c478bd9Sstevel@tonic-gate if (krb5_unparse_name(id->context, princ, &name) != 0) 1967c478bd9Sstevel@tonic-gate return; 1977c478bd9Sstevel@tonic-gate get_either_iter(data, name); 1987c478bd9Sstevel@tonic-gate } 1997c478bd9Sstevel@tonic-gate 20056a424ccSmp153739 static kadm5_ret_t kadm5_get_either(int princ, 2017c478bd9Sstevel@tonic-gate void *server_handle, 2027c478bd9Sstevel@tonic-gate char *exp, 2037c478bd9Sstevel@tonic-gate char ***princs, 2047c478bd9Sstevel@tonic-gate int *count) 2057c478bd9Sstevel@tonic-gate { 2067c478bd9Sstevel@tonic-gate struct iter_data data; 20756a424ccSmp153739 #ifdef BSD_REGEXPS 20856a424ccSmp153739 char *msg; 20956a424ccSmp153739 #endif 21056a424ccSmp153739 char *regexp; 21156a424ccSmp153739 int i, ret; 2127c478bd9Sstevel@tonic-gate kadm5_server_handle_t handle = server_handle; 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate *count = 0; 2157c478bd9Sstevel@tonic-gate if (exp == NULL) 2167c478bd9Sstevel@tonic-gate exp = "*"; 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate CHECK_HANDLE(server_handle); 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate if ((ret = glob_to_regexp(exp, princ ? handle->params.realm : NULL, 2217c478bd9Sstevel@tonic-gate ®exp)) != KADM5_OK) 2227c478bd9Sstevel@tonic-gate return ret; 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate if ( 2257c478bd9Sstevel@tonic-gate #ifdef SOLARIS_REGEXPS 2267c478bd9Sstevel@tonic-gate ((data.expbuf = compile(regexp, NULL, NULL)) == NULL) 2277c478bd9Sstevel@tonic-gate #endif 2287c478bd9Sstevel@tonic-gate #ifdef POSIX_REGEXPS 2297c478bd9Sstevel@tonic-gate ((regcomp(&data.preg, regexp, REG_NOSUB)) != 0) 2307c478bd9Sstevel@tonic-gate #endif 2317c478bd9Sstevel@tonic-gate #ifdef BSD_REGEXPS 2327c478bd9Sstevel@tonic-gate ((msg = (char *) re_comp(regexp)) != NULL) 2337c478bd9Sstevel@tonic-gate #endif 2347c478bd9Sstevel@tonic-gate ) 2357c478bd9Sstevel@tonic-gate { 2367c478bd9Sstevel@tonic-gate /* XXX syslog msg or regerr(regerrno) */ 2377c478bd9Sstevel@tonic-gate free(regexp); 2387c478bd9Sstevel@tonic-gate return EINVAL; 2397c478bd9Sstevel@tonic-gate } 2407c478bd9Sstevel@tonic-gate 24156a424ccSmp153739 data.n_names = 0; 24256a424ccSmp153739 data.sz_names = 10; 24356a424ccSmp153739 data.malloc_failed = 0; 24456a424ccSmp153739 data.names = malloc(sizeof(char *) * data.sz_names); 24556a424ccSmp153739 if (data.names == NULL) { 2467c478bd9Sstevel@tonic-gate free(regexp); 2477c478bd9Sstevel@tonic-gate return ENOMEM; 2487c478bd9Sstevel@tonic-gate } 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate if (princ) { 2517c478bd9Sstevel@tonic-gate data.context = handle->context; 25254925bf6Swillf ret = kdb_iter_entry(handle, exp, get_princs_iter, (void *) &data); 2537c478bd9Sstevel@tonic-gate } else { 25454925bf6Swillf ret = krb5_db_iter_policy(handle->context, exp, get_pols_iter, (void *)&data); 2557c478bd9Sstevel@tonic-gate } 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate free(regexp); 25856a424ccSmp153739 #ifdef POSIX_REGEXPS 25956a424ccSmp153739 regfree(&data.preg); 26056a424ccSmp153739 #endif 26154925bf6Swillf if ( !ret && data.malloc_failed) 26256a424ccSmp153739 ret = ENOMEM; 26354925bf6Swillf if ( ret ) { 26456a424ccSmp153739 for (i = 0; i < data.n_names; i++) 26556a424ccSmp153739 free(data.names[i]); 26656a424ccSmp153739 free(data.names); 2677c478bd9Sstevel@tonic-gate return ret; 2687c478bd9Sstevel@tonic-gate } 2697c478bd9Sstevel@tonic-gate 27056a424ccSmp153739 *princs = data.names; 27156a424ccSmp153739 *count = data.n_names; 2727c478bd9Sstevel@tonic-gate return KADM5_OK; 2737c478bd9Sstevel@tonic-gate } 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate kadm5_ret_t kadm5_get_principals(void *server_handle, 2767c478bd9Sstevel@tonic-gate char *exp, 2777c478bd9Sstevel@tonic-gate char ***princs, 2787c478bd9Sstevel@tonic-gate int *count) 2797c478bd9Sstevel@tonic-gate { 2807c478bd9Sstevel@tonic-gate return kadm5_get_either(1, server_handle, exp, princs, count); 2817c478bd9Sstevel@tonic-gate } 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate kadm5_ret_t kadm5_get_policies(void *server_handle, 2847c478bd9Sstevel@tonic-gate char *exp, 2857c478bd9Sstevel@tonic-gate char ***pols, 2867c478bd9Sstevel@tonic-gate int *count) 2877c478bd9Sstevel@tonic-gate { 2887c478bd9Sstevel@tonic-gate return kadm5_get_either(0, server_handle, exp, pols, count); 2897c478bd9Sstevel@tonic-gate } 2907c478bd9Sstevel@tonic-gate 291