Path: blob/main/crypto/krb5/src/lib/kadm5/srv/svr_iters.c
39566 views
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */1/*2* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved3*4* $Header$5*/67#include "autoconf.h"89#include <sys/types.h>10#include <string.h>11#include <kadm5/admin.h>12#include "k5-regex.h"13#include <stdlib.h>1415#include "server_internal.h"1617struct iter_data {18krb5_context context;19char **names;20int n_names, sz_names;21unsigned int malloc_failed;22char *exp;23regex_t preg;24};2526/* XXX Duplicated in kdb5_util! */27/*28* Function: glob_to_regexp29*30* Arguments:31*32* glob (r) the shell-style glob (?*[]) to convert33* realm (r) the default realm to append, or NULL34* regexp (w) the ed-style regexp created from glob35*36* Effects:37*38* regexp is filled in with allocated memory contained a regular39* expression that matches what the shell-style glob would match.40* If glob does not contain an "@" character and realm is not41* NULL, "@*" is appended to the regexp.42*43* Conversion algorithm:44*45* quoted characters are copied quoted46* ? is converted to .47* * is converted to .*48* active characters are quoted: ^, $, .49* [ and ] are active but supported and have the same meaning, so50* they are copied51* other characters are copied52* regexp is anchored with ^ and $53*/54static kadm5_ret_t glob_to_regexp(char *glob, char *realm, char **regexp)55{56int append_realm;57char *p;5859/* validate the glob */60if (glob[strlen(glob)-1] == '\\')61return EINVAL;6263/* A character of glob can turn into two in regexp, plus ^ and $ */64/* and trailing null. If glob has no @, also allocate space for */65/* the realm. */66append_realm = (realm != NULL) && (strchr(glob, '@') == NULL);67p = (char *) malloc(strlen(glob)*2+ 3 + (append_realm ? 3 : 0));68if (p == NULL)69return ENOMEM;70*regexp = p;7172*p++ = '^';73while (*glob) {74switch (*glob) {75case '?':76*p++ = '.';77break;78case '*':79*p++ = '.';80*p++ = '*';81break;82case '.':83case '^':84case '$':85*p++ = '\\';86*p++ = *glob;87break;88case '\\':89*p++ = '\\';90*p++ = *++glob;91break;92default:93*p++ = *glob;94break;95}96glob++;97}9899if (append_realm) {100*p++ = '@';101*p++ = '.';102*p++ = '*';103}104105*p++ = '$';106*p++ = '\0';107return KADM5_OK;108}109110static void get_either_iter(struct iter_data *data, char *name)111{112int match;113match = (regexec(&data->preg, name, 0, NULL, 0) == 0);114if (match) {115if (data->n_names == data->sz_names) {116int new_sz = data->sz_names * 2;117char **new_names = realloc(data->names,118new_sz * sizeof(char *));119if (new_names) {120data->names = new_names;121data->sz_names = new_sz;122} else {123data->malloc_failed = 1;124free(name);125return;126}127}128data->names[data->n_names++] = name;129} else130free(name);131}132133static void get_pols_iter(void *data, osa_policy_ent_t entry)134{135char *name;136137if ((name = strdup(entry->name)) == NULL)138return;139get_either_iter(data, name);140}141142static void get_princs_iter(void *data, krb5_principal princ)143{144struct iter_data *id = (struct iter_data *) data;145char *name;146147if (krb5_unparse_name(id->context, princ, &name) != 0)148return;149get_either_iter(data, name);150}151152static kadm5_ret_t kadm5_get_either(int princ,153void *server_handle,154char *exp,155char ***princs,156int *count)157{158struct iter_data data;159char *regexp = NULL;160int i, ret;161kadm5_server_handle_t handle = server_handle;162163*princs = NULL;164*count = 0;165if (exp == NULL)166exp = "*";167168CHECK_HANDLE(server_handle);169170if ((ret = glob_to_regexp(exp, princ ? handle->params.realm : NULL,171®exp)) != KADM5_OK)172return ret;173174if (regcomp(&data.preg, regexp, REG_NOSUB) != 0) {175/* XXX syslog msg or regerr(regerrno) */176free(regexp);177return EINVAL;178}179180data.n_names = 0;181data.sz_names = 10;182data.malloc_failed = 0;183data.names = malloc(sizeof(char *) * data.sz_names);184if (data.names == NULL) {185free(regexp);186return ENOMEM;187}188189if (princ) {190data.context = handle->context;191ret = kdb_iter_entry(handle, exp, get_princs_iter, (void *) &data);192} else {193ret = krb5_db_iter_policy(handle->context, exp, get_pols_iter, (void *)&data);194}195196free(regexp);197regfree(&data.preg);198if ( !ret && data.malloc_failed)199ret = ENOMEM;200if ( ret ) {201for (i = 0; i < data.n_names; i++)202free(data.names[i]);203free(data.names);204return ret;205}206207*princs = data.names;208*count = data.n_names;209return KADM5_OK;210}211212kadm5_ret_t kadm5_get_principals(void *server_handle,213char *exp,214char ***princs,215int *count)216{217return kadm5_get_either(1, server_handle, exp, princs, count);218}219220kadm5_ret_t kadm5_get_policies(void *server_handle,221char *exp,222char ***pols,223int *count)224{225return kadm5_get_either(0, server_handle, exp, pols, count);226}227228229