Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/heimdal/lib/kadm5/get_s.c
34878 views
1
/*
2
* Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan
3
* (Royal Institute of Technology, Stockholm, Sweden).
4
* All rights reserved.
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
8
* are met:
9
*
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
*
13
* 2. Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
16
*
17
* 3. Neither the name of the Institute nor the names of its contributors
18
* may be used to endorse or promote products derived from this software
19
* without specific prior written permission.
20
*
21
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31
* SUCH DAMAGE.
32
*/
33
34
#include "kadm5_locl.h"
35
36
RCSID("$Id$");
37
38
static kadm5_ret_t
39
add_tl_data(kadm5_principal_ent_t ent, int16_t type,
40
const void *data, size_t size)
41
{
42
krb5_tl_data *tl;
43
44
tl = calloc(1, sizeof(*tl));
45
if (tl == NULL)
46
return _kadm5_error_code(ENOMEM);
47
48
tl->tl_data_type = type;
49
tl->tl_data_length = size;
50
tl->tl_data_contents = malloc(size);
51
if (tl->tl_data_contents == NULL && size != 0) {
52
free(tl);
53
return _kadm5_error_code(ENOMEM);
54
}
55
memcpy(tl->tl_data_contents, data, size);
56
57
tl->tl_data_next = ent->tl_data;
58
ent->tl_data = tl;
59
ent->n_tl_data++;
60
61
return 0;
62
}
63
64
KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL
65
_krb5_put_int(void *buffer, unsigned long value, size_t size); /* XXX */
66
67
kadm5_ret_t
68
kadm5_s_get_principal(void *server_handle,
69
krb5_principal princ,
70
kadm5_principal_ent_t out,
71
uint32_t mask)
72
{
73
kadm5_server_context *context = server_handle;
74
kadm5_ret_t ret;
75
hdb_entry_ex ent;
76
77
memset(&ent, 0, sizeof(ent));
78
ret = context->db->hdb_open(context->context, context->db, O_RDONLY, 0);
79
if(ret)
80
return ret;
81
ret = context->db->hdb_fetch_kvno(context->context, context->db, princ,
82
HDB_F_DECRYPT|HDB_F_GET_ANY|HDB_F_ADMIN_DATA, 0, &ent);
83
context->db->hdb_close(context->context, context->db);
84
if(ret)
85
return _kadm5_error_code(ret);
86
87
memset(out, 0, sizeof(*out));
88
if(mask & KADM5_PRINCIPAL)
89
ret = krb5_copy_principal(context->context, ent.entry.principal,
90
&out->principal);
91
if(ret)
92
goto out;
93
if(mask & KADM5_PRINC_EXPIRE_TIME && ent.entry.valid_end)
94
out->princ_expire_time = *ent.entry.valid_end;
95
if(mask & KADM5_PW_EXPIRATION && ent.entry.pw_end)
96
out->pw_expiration = *ent.entry.pw_end;
97
if(mask & KADM5_LAST_PWD_CHANGE)
98
hdb_entry_get_pw_change_time(&ent.entry, &out->last_pwd_change);
99
if(mask & KADM5_ATTRIBUTES){
100
out->attributes |= ent.entry.flags.postdate ? 0 : KRB5_KDB_DISALLOW_POSTDATED;
101
out->attributes |= ent.entry.flags.forwardable ? 0 : KRB5_KDB_DISALLOW_FORWARDABLE;
102
out->attributes |= ent.entry.flags.initial ? KRB5_KDB_DISALLOW_TGT_BASED : 0;
103
out->attributes |= ent.entry.flags.renewable ? 0 : KRB5_KDB_DISALLOW_RENEWABLE;
104
out->attributes |= ent.entry.flags.proxiable ? 0 : KRB5_KDB_DISALLOW_PROXIABLE;
105
out->attributes |= ent.entry.flags.invalid ? KRB5_KDB_DISALLOW_ALL_TIX : 0;
106
out->attributes |= ent.entry.flags.require_preauth ? KRB5_KDB_REQUIRES_PRE_AUTH : 0;
107
out->attributes |= ent.entry.flags.server ? 0 : KRB5_KDB_DISALLOW_SVR;
108
out->attributes |= ent.entry.flags.change_pw ? KRB5_KDB_PWCHANGE_SERVICE : 0;
109
out->attributes |= ent.entry.flags.ok_as_delegate ? KRB5_KDB_OK_AS_DELEGATE : 0;
110
out->attributes |= ent.entry.flags.trusted_for_delegation ? KRB5_KDB_TRUSTED_FOR_DELEGATION : 0;
111
out->attributes |= ent.entry.flags.allow_kerberos4 ? KRB5_KDB_ALLOW_KERBEROS4 : 0;
112
out->attributes |= ent.entry.flags.allow_digest ? KRB5_KDB_ALLOW_DIGEST : 0;
113
}
114
if(mask & KADM5_MAX_LIFE) {
115
if(ent.entry.max_life)
116
out->max_life = *ent.entry.max_life;
117
else
118
out->max_life = INT_MAX;
119
}
120
if(mask & KADM5_MOD_TIME) {
121
if(ent.entry.modified_by)
122
out->mod_date = ent.entry.modified_by->time;
123
else
124
out->mod_date = ent.entry.created_by.time;
125
}
126
if(mask & KADM5_MOD_NAME) {
127
if(ent.entry.modified_by) {
128
if (ent.entry.modified_by->principal != NULL)
129
ret = krb5_copy_principal(context->context,
130
ent.entry.modified_by->principal,
131
&out->mod_name);
132
} else if(ent.entry.created_by.principal != NULL)
133
ret = krb5_copy_principal(context->context,
134
ent.entry.created_by.principal,
135
&out->mod_name);
136
else
137
out->mod_name = NULL;
138
}
139
if(ret)
140
goto out;
141
142
if(mask & KADM5_KVNO)
143
out->kvno = ent.entry.kvno;
144
if(mask & KADM5_MKVNO) {
145
size_t n;
146
out->mkvno = 0; /* XXX */
147
for(n = 0; n < ent.entry.keys.len; n++)
148
if(ent.entry.keys.val[n].mkvno) {
149
out->mkvno = *ent.entry.keys.val[n].mkvno; /* XXX this isn't right */
150
break;
151
}
152
}
153
#if 0 /* XXX implement */
154
if(mask & KADM5_AUX_ATTRIBUTES)
155
;
156
if(mask & KADM5_LAST_SUCCESS)
157
;
158
if(mask & KADM5_LAST_FAILED)
159
;
160
if(mask & KADM5_FAIL_AUTH_COUNT)
161
;
162
#endif
163
if(mask & KADM5_POLICY)
164
out->policy = NULL;
165
if(mask & KADM5_MAX_RLIFE) {
166
if(ent.entry.max_renew)
167
out->max_renewable_life = *ent.entry.max_renew;
168
else
169
out->max_renewable_life = INT_MAX;
170
}
171
if(mask & KADM5_KEY_DATA){
172
size_t i;
173
Key *key;
174
krb5_key_data *kd;
175
krb5_salt salt;
176
krb5_data *sp;
177
krb5_get_pw_salt(context->context, ent.entry.principal, &salt);
178
out->key_data = malloc(ent.entry.keys.len * sizeof(*out->key_data));
179
if (out->key_data == NULL && ent.entry.keys.len != 0) {
180
ret = ENOMEM;
181
goto out;
182
}
183
for(i = 0; i < ent.entry.keys.len; i++){
184
key = &ent.entry.keys.val[i];
185
kd = &out->key_data[i];
186
kd->key_data_ver = 2;
187
kd->key_data_kvno = ent.entry.kvno;
188
kd->key_data_type[0] = key->key.keytype;
189
if(key->salt)
190
kd->key_data_type[1] = key->salt->type;
191
else
192
kd->key_data_type[1] = KRB5_PADATA_PW_SALT;
193
/* setup key */
194
kd->key_data_length[0] = key->key.keyvalue.length;
195
kd->key_data_contents[0] = malloc(kd->key_data_length[0]);
196
if(kd->key_data_contents[0] == NULL && kd->key_data_length[0] != 0){
197
ret = ENOMEM;
198
break;
199
}
200
memcpy(kd->key_data_contents[0], key->key.keyvalue.data,
201
kd->key_data_length[0]);
202
/* setup salt */
203
if(key->salt)
204
sp = &key->salt->salt;
205
else
206
sp = &salt.saltvalue;
207
kd->key_data_length[1] = sp->length;
208
kd->key_data_contents[1] = malloc(kd->key_data_length[1]);
209
if(kd->key_data_length[1] != 0
210
&& kd->key_data_contents[1] == NULL) {
211
memset(kd->key_data_contents[0], 0, kd->key_data_length[0]);
212
ret = ENOMEM;
213
break;
214
}
215
memcpy(kd->key_data_contents[1], sp->data, kd->key_data_length[1]);
216
out->n_key_data = i + 1;
217
}
218
krb5_free_salt(context->context, salt);
219
}
220
if(ret){
221
kadm5_free_principal_ent(context, out);
222
goto out;
223
}
224
if(mask & KADM5_TL_DATA) {
225
time_t last_pw_expire;
226
const HDB_Ext_PKINIT_acl *acl;
227
const HDB_Ext_Aliases *aliases;
228
229
ret = hdb_entry_get_pw_change_time(&ent.entry, &last_pw_expire);
230
if (ret == 0 && last_pw_expire) {
231
unsigned char buf[4];
232
_krb5_put_int(buf, last_pw_expire, sizeof(buf));
233
ret = add_tl_data(out, KRB5_TL_LAST_PWD_CHANGE, buf, sizeof(buf));
234
if (ret)
235
goto out;
236
}
237
if(ret){
238
kadm5_free_principal_ent(context, out);
239
goto out;
240
}
241
/*
242
* If the client was allowed to get key data, let it have the
243
* password too.
244
*/
245
if(mask & KADM5_KEY_DATA) {
246
heim_utf8_string pw;
247
248
ret = hdb_entry_get_password(context->context,
249
context->db, &ent.entry, &pw);
250
if (ret == 0) {
251
(void) add_tl_data(out, KRB5_TL_PASSWORD, pw, strlen(pw) + 1);
252
free(pw);
253
}
254
krb5_clear_error_message(context->context);
255
}
256
257
ret = hdb_entry_get_pkinit_acl(&ent.entry, &acl);
258
if (ret == 0 && acl) {
259
krb5_data buf;
260
size_t len;
261
262
ASN1_MALLOC_ENCODE(HDB_Ext_PKINIT_acl, buf.data, buf.length,
263
acl, &len, ret);
264
if (ret) {
265
kadm5_free_principal_ent(context, out);
266
goto out;
267
}
268
if (len != buf.length)
269
krb5_abortx(context->context,
270
"internal ASN.1 encoder error");
271
ret = add_tl_data(out, KRB5_TL_PKINIT_ACL, buf.data, buf.length);
272
free(buf.data);
273
if (ret) {
274
kadm5_free_principal_ent(context, out);
275
goto out;
276
}
277
}
278
if(ret){
279
kadm5_free_principal_ent(context, out);
280
goto out;
281
}
282
283
ret = hdb_entry_get_aliases(&ent.entry, &aliases);
284
if (ret == 0 && aliases) {
285
krb5_data buf;
286
size_t len;
287
288
ASN1_MALLOC_ENCODE(HDB_Ext_Aliases, buf.data, buf.length,
289
aliases, &len, ret);
290
if (ret) {
291
kadm5_free_principal_ent(context, out);
292
goto out;
293
}
294
if (len != buf.length)
295
krb5_abortx(context->context,
296
"internal ASN.1 encoder error");
297
ret = add_tl_data(out, KRB5_TL_ALIASES, buf.data, buf.length);
298
free(buf.data);
299
if (ret) {
300
kadm5_free_principal_ent(context, out);
301
goto out;
302
}
303
}
304
if(ret){
305
kadm5_free_principal_ent(context, out);
306
goto out;
307
}
308
309
}
310
out:
311
hdb_free_entry(context->context, &ent);
312
313
return _kadm5_error_code(ret);
314
}
315
316