Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/lib/kadm5/srv/svr_iters.c
39566 views
1
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
/*
3
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
4
*
5
* $Header$
6
*/
7
8
#include "autoconf.h"
9
10
#include <sys/types.h>
11
#include <string.h>
12
#include <kadm5/admin.h>
13
#include "k5-regex.h"
14
#include <stdlib.h>
15
16
#include "server_internal.h"
17
18
struct iter_data {
19
krb5_context context;
20
char **names;
21
int n_names, sz_names;
22
unsigned int malloc_failed;
23
char *exp;
24
regex_t preg;
25
};
26
27
/* XXX Duplicated in kdb5_util! */
28
/*
29
* Function: glob_to_regexp
30
*
31
* Arguments:
32
*
33
* glob (r) the shell-style glob (?*[]) to convert
34
* realm (r) the default realm to append, or NULL
35
* regexp (w) the ed-style regexp created from glob
36
*
37
* Effects:
38
*
39
* regexp is filled in with allocated memory contained a regular
40
* expression that matches what the shell-style glob would match.
41
* If glob does not contain an "@" character and realm is not
42
* NULL, "@*" is appended to the regexp.
43
*
44
* Conversion algorithm:
45
*
46
* quoted characters are copied quoted
47
* ? is converted to .
48
* * is converted to .*
49
* active characters are quoted: ^, $, .
50
* [ and ] are active but supported and have the same meaning, so
51
* they are copied
52
* other characters are copied
53
* regexp is anchored with ^ and $
54
*/
55
static kadm5_ret_t glob_to_regexp(char *glob, char *realm, char **regexp)
56
{
57
int append_realm;
58
char *p;
59
60
/* validate the glob */
61
if (glob[strlen(glob)-1] == '\\')
62
return EINVAL;
63
64
/* A character of glob can turn into two in regexp, plus ^ and $ */
65
/* and trailing null. If glob has no @, also allocate space for */
66
/* the realm. */
67
append_realm = (realm != NULL) && (strchr(glob, '@') == NULL);
68
p = (char *) malloc(strlen(glob)*2+ 3 + (append_realm ? 3 : 0));
69
if (p == NULL)
70
return ENOMEM;
71
*regexp = p;
72
73
*p++ = '^';
74
while (*glob) {
75
switch (*glob) {
76
case '?':
77
*p++ = '.';
78
break;
79
case '*':
80
*p++ = '.';
81
*p++ = '*';
82
break;
83
case '.':
84
case '^':
85
case '$':
86
*p++ = '\\';
87
*p++ = *glob;
88
break;
89
case '\\':
90
*p++ = '\\';
91
*p++ = *++glob;
92
break;
93
default:
94
*p++ = *glob;
95
break;
96
}
97
glob++;
98
}
99
100
if (append_realm) {
101
*p++ = '@';
102
*p++ = '.';
103
*p++ = '*';
104
}
105
106
*p++ = '$';
107
*p++ = '\0';
108
return KADM5_OK;
109
}
110
111
static void get_either_iter(struct iter_data *data, char *name)
112
{
113
int match;
114
match = (regexec(&data->preg, name, 0, NULL, 0) == 0);
115
if (match) {
116
if (data->n_names == data->sz_names) {
117
int new_sz = data->sz_names * 2;
118
char **new_names = realloc(data->names,
119
new_sz * sizeof(char *));
120
if (new_names) {
121
data->names = new_names;
122
data->sz_names = new_sz;
123
} else {
124
data->malloc_failed = 1;
125
free(name);
126
return;
127
}
128
}
129
data->names[data->n_names++] = name;
130
} else
131
free(name);
132
}
133
134
static void get_pols_iter(void *data, osa_policy_ent_t entry)
135
{
136
char *name;
137
138
if ((name = strdup(entry->name)) == NULL)
139
return;
140
get_either_iter(data, name);
141
}
142
143
static void get_princs_iter(void *data, krb5_principal princ)
144
{
145
struct iter_data *id = (struct iter_data *) data;
146
char *name;
147
148
if (krb5_unparse_name(id->context, princ, &name) != 0)
149
return;
150
get_either_iter(data, name);
151
}
152
153
static kadm5_ret_t kadm5_get_either(int princ,
154
void *server_handle,
155
char *exp,
156
char ***princs,
157
int *count)
158
{
159
struct iter_data data;
160
char *regexp = NULL;
161
int i, ret;
162
kadm5_server_handle_t handle = server_handle;
163
164
*princs = NULL;
165
*count = 0;
166
if (exp == NULL)
167
exp = "*";
168
169
CHECK_HANDLE(server_handle);
170
171
if ((ret = glob_to_regexp(exp, princ ? handle->params.realm : NULL,
172
&regexp)) != KADM5_OK)
173
return ret;
174
175
if (regcomp(&data.preg, regexp, REG_NOSUB) != 0) {
176
/* XXX syslog msg or regerr(regerrno) */
177
free(regexp);
178
return EINVAL;
179
}
180
181
data.n_names = 0;
182
data.sz_names = 10;
183
data.malloc_failed = 0;
184
data.names = malloc(sizeof(char *) * data.sz_names);
185
if (data.names == NULL) {
186
free(regexp);
187
return ENOMEM;
188
}
189
190
if (princ) {
191
data.context = handle->context;
192
ret = kdb_iter_entry(handle, exp, get_princs_iter, (void *) &data);
193
} else {
194
ret = krb5_db_iter_policy(handle->context, exp, get_pols_iter, (void *)&data);
195
}
196
197
free(regexp);
198
regfree(&data.preg);
199
if ( !ret && data.malloc_failed)
200
ret = ENOMEM;
201
if ( ret ) {
202
for (i = 0; i < data.n_names; i++)
203
free(data.names[i]);
204
free(data.names);
205
return ret;
206
}
207
208
*princs = data.names;
209
*count = data.n_names;
210
return KADM5_OK;
211
}
212
213
kadm5_ret_t kadm5_get_principals(void *server_handle,
214
char *exp,
215
char ***princs,
216
int *count)
217
{
218
return kadm5_get_either(1, server_handle, exp, princs, count);
219
}
220
221
kadm5_ret_t kadm5_get_policies(void *server_handle,
222
char *exp,
223
char ***pols,
224
int *count)
225
{
226
return kadm5_get_either(0, server_handle, exp, pols, count);
227
}
228
229