2 * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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.
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
34 #include "kadm5_locl.h"
38 #define __CALL(F, P) (*((kadm5_common_context*)server_handle)->funcs.F)P
39 #define __CALLABLE(F) (((kadm5_common_context*)server_handle)->funcs.F != 0)
42 kadm5_chpass_principal(void *server_handle
,
46 return __CALL(chpass_principal
, (server_handle
, princ
, 0,
51 kadm5_chpass_principal_3(void *server_handle
,
55 krb5_key_salt_tuple
*ks_tuple
,
58 return __CALL(chpass_principal
, (server_handle
, princ
, keepold
,
59 n_ks_tuple
, ks_tuple
, password
));
63 kadm5_chpass_principal_with_key(void *server_handle
,
66 krb5_key_data
*key_data
)
68 return __CALL(chpass_principal_with_key
,
69 (server_handle
, princ
, 0, n_key_data
, key_data
));
73 kadm5_chpass_principal_with_key_3(void *server_handle
,
77 krb5_key_data
*key_data
)
79 return __CALL(chpass_principal_with_key
,
80 (server_handle
, princ
, keepold
, n_key_data
, key_data
));
84 kadm5_create_principal_3(void *server_handle
,
85 kadm5_principal_ent_t princ
,
88 krb5_key_salt_tuple
*ks_tuple
,
91 return __CALL(create_principal
,
92 (server_handle
, princ
, mask
, n_ks_tuple
, ks_tuple
, password
));
96 kadm5_create_principal(void *server_handle
,
97 kadm5_principal_ent_t princ
,
101 return __CALL(create_principal
,
102 (server_handle
, princ
, mask
, 0, NULL
, password
));
106 kadm5_delete_principal(void *server_handle
,
107 krb5_principal princ
)
109 return __CALL(delete_principal
, (server_handle
, princ
));
113 kadm5_destroy (void *server_handle
)
115 return __CALL(destroy
, (server_handle
));
119 kadm5_flush (void *server_handle
)
121 return __CALL(flush
, (server_handle
));
125 kadm5_get_principal(void *server_handle
,
126 krb5_principal princ
,
127 kadm5_principal_ent_t out
,
130 return __CALL(get_principal
, (server_handle
, princ
, out
, mask
));
134 * Extract decrypted keys from kadm5_principal_ent_t object. Mostly a
135 * no-op for Heimdal because we fetch the entry with decrypted keys.
136 * Sadly this is not fully a no-op, as we have to allocate a copy.
138 * @server_handle is the kadm5 handle
139 * @entry is the HDB entry for the principal in question
140 * @ktype is the enctype to get a key for, or -1 to get the first one
141 * @stype is the salttype to get a key for, or -1 to get the first match
142 * @kvno is the kvno to search for, or -1 to get the first match (highest kvno)
143 * @keyblock is where the key will be placed
144 * @keysalt, if not NULL, is where the salt will be placed
145 * @kvnop, if not NULL, is where the selected kvno will be placed
148 kadm5_decrypt_key(void *server_handle
,
149 kadm5_principal_ent_t entry
,
150 int32_t ktype
, int32_t stype
,
151 int32_t kvno
, krb5_keyblock
*keyblock
,
152 krb5_keysalt
*keysalt
, int *kvnop
)
155 kadm5_server_context
*context
= server_handle
;
157 if (kvno
< 1 || stype
!= -1)
158 return KADM5_DECRYPT_USAGE_NOSUPP
;
160 for (i
= 0; i
< entry
->n_key_data
; i
++) {
161 if (ktype
!= entry
->key_data
[i
].key_data_kvno
)
164 keyblock
->keytype
= ktype
;
165 keyblock
->keyvalue
.length
= entry
->key_data
[i
].key_data_length
[0];
166 keyblock
->keyvalue
.data
= malloc(keyblock
->keyvalue
.length
);
167 if (keyblock
->keyvalue
.data
== NULL
)
168 return krb5_enomem(context
->context
);
169 memcpy(keyblock
->keyvalue
.data
,
170 entry
->key_data
[i
].key_data_contents
[0],
171 keyblock
->keyvalue
.length
);
178 kadm5_modify_principal(void *server_handle
,
179 kadm5_principal_ent_t princ
,
182 return __CALL(modify_principal
, (server_handle
, princ
, mask
));
186 kadm5_randkey_principal(void *server_handle
,
187 krb5_principal princ
,
188 krb5_keyblock
**new_keys
,
191 return __CALL(randkey_principal
, (server_handle
, princ
, FALSE
, 0, NULL
,
196 kadm5_randkey_principal_3(void *server_handle
,
197 krb5_principal princ
,
198 krb5_boolean keepold
,
200 krb5_key_salt_tuple
*ks_tuple
,
201 krb5_keyblock
**new_keys
,
204 return __CALL(randkey_principal
, (server_handle
, princ
, keepold
,
205 n_ks_tuple
, ks_tuple
, new_keys
, n_keys
));
209 kadm5_rename_principal(void *server_handle
,
210 krb5_principal source
,
211 krb5_principal target
)
213 return __CALL(rename_principal
, (server_handle
, source
, target
));
217 kadm5_get_principals(void *server_handle
,
218 const char *expression
,
222 return __CALL(get_principals
, (server_handle
, expression
, princs
, count
));
226 kadm5_get_privs(void *server_handle
,
229 return __CALL(get_privs
, (server_handle
, privs
));
234 * This function is allows the caller to set new keys for a principal.
235 * This is a trivial wrapper around kadm5_setkey_principal_3().
238 kadm5_setkey_principal(void *server_handle
,
239 krb5_principal princ
,
240 krb5_keyblock
*new_keys
,
243 return kadm5_setkey_principal_3(server_handle
, princ
, 0, 0, NULL
,
248 * This function is allows the caller to set new keys for a principal.
249 * This is a simple wrapper around kadm5_get_principal() and
250 * kadm5_modify_principal().
253 kadm5_setkey_principal_3(void *server_handle
,
254 krb5_principal princ
,
255 krb5_boolean keepold
,
256 int n_ks_tuple
, krb5_key_salt_tuple
*ks_tuple
,
257 krb5_keyblock
*keyblocks
,
260 kadm5_principal_ent_rec princ_ent
;
262 krb5_key_data
*new_key_data
= NULL
;
264 kadm5_server_context
*context
= server_handle
;
268 if (n_ks_tuple
> 0 && n_ks_tuple
!= n_keys
)
269 return KADM5_SETKEY3_ETYPE_MISMATCH
;
272 * If setkey_principal_3 is defined in the server handle, use that.
274 if (__CALLABLE(setkey_principal_3
))
275 return __CALL(setkey_principal_3
,
276 (server_handle
, princ
, keepold
, n_ks_tuple
, ks_tuple
,
280 * Otherwise, simulate it via a get, update, modify sequence.
282 ret
= kadm5_get_principal(server_handle
, princ
, &princ_ent
,
283 KADM5_KVNO
| KADM5_PRINCIPAL
| KADM5_KEY_DATA
);
288 new_key_data
= calloc((n_keys
+ princ_ent
.n_key_data
),
289 sizeof(*new_key_data
));
290 if (new_key_data
== NULL
) {
291 ret
= krb5_enomem(context
->context
);
295 memcpy(&new_key_data
[n_keys
], &princ_ent
.key_data
[0],
296 princ_ent
.n_key_data
* sizeof (princ_ent
.key_data
[0]));
298 new_key_data
= calloc(n_keys
, sizeof(*new_key_data
));
299 if (new_key_data
== NULL
) {
300 ret
= krb5_enomem(context
->context
);
306 for (i
= 0; i
< n_keys
; i
++) {
307 new_key_data
[i
].key_data_ver
= 2;
310 new_key_data
[i
].key_data_kvno
= princ_ent
.kvno
;
311 new_key_data
[i
].key_data_type
[0] = keyblocks
[i
].keytype
;
312 new_key_data
[i
].key_data_length
[0] = keyblocks
[i
].keyvalue
.length
;
313 new_key_data
[i
].key_data_contents
[0] =
314 malloc(keyblocks
[i
].keyvalue
.length
);
315 if (new_key_data
[i
].key_data_contents
[0] == NULL
) {
316 ret
= krb5_enomem(context
->context
);
319 memcpy(new_key_data
[i
].key_data_contents
[0],
320 keyblocks
[i
].keyvalue
.data
,
321 keyblocks
[i
].keyvalue
.length
);
324 * Salt (but there's no salt, just salttype, which is kinda
325 * silly -- what's the point of setkey_3() then, besides
328 new_key_data
[i
].key_data_type
[1] = 0;
329 if (n_ks_tuple
> 0) {
330 if (ks_tuple
[i
].ks_enctype
!= keyblocks
[i
].keytype
) {
331 ret
= KADM5_SETKEY3_ETYPE_MISMATCH
;
334 new_key_data
[i
].key_data_type
[1] = ks_tuple
[i
].ks_salttype
;
336 new_key_data
[i
].key_data_length
[1] = 0;
337 new_key_data
[i
].key_data_contents
[1] = NULL
;
342 for (i
= 0; i
< princ_ent
.n_key_data
; i
++) {
343 free(princ_ent
.key_data
[i
].key_data_contents
[0]);
344 free(princ_ent
.key_data
[i
].key_data_contents
[1]);
347 free(princ_ent
.key_data
);
348 princ_ent
.key_data
= new_key_data
;
349 princ_ent
.n_key_data
= n_keys
+ (keepold
? princ_ent
.n_key_data
: 0);
352 /* Modify the principal */
353 ret
= kadm5_modify_principal(server_handle
, &princ_ent
, KADM5_KVNO
| KADM5_KEY_DATA
);
356 if (new_key_data
!= NULL
) {
357 for (i
= 0; i
< n_keys
; i
++) {
358 free(new_key_data
[i
].key_data_contents
[0]);
359 free(new_key_data
[i
].key_data_contents
[1]);
363 kadm5_free_principal_ent(server_handle
, &princ_ent
);
369 kadm5_lock(void *server_handle
)
371 return __CALL(lock
, (server_handle
));
375 kadm5_unlock(void *server_handle
)
377 return __CALL(unlock
, (server_handle
));
382 kadm5_create_policy(void *server_handle
,
383 kadm5_policy_ent_t policy
, long mask
)
385 return KADM5_POLICY_OP_NOSUPP
;
389 kadm5_delete_policy(void *server_handle
, char *name
)
391 return KADM5_POLICY_OP_NOSUPP
;
396 kadm5_modify_policy(void *server_handle
, kadm5_policy_ent_t policy
,
399 return KADM5_POLICY_OP_NOSUPP
;
403 kadm5_get_policy(void *server_handle
, char *policy
, kadm5_policy_ent_t ent
)
405 memset(ent
, 0, sizeof (*ent
));
406 return KADM5_POLICY_OP_NOSUPP
;
411 kadm5_get_policies(void *server_handle
, char *exp
, char ***pols
, int *count
)
416 return KADM5_POLICY_OP_NOSUPP
;
420 kadm5_free_policy_ent(kadm5_policy_ent_t ent
)
425 * Not clear if we should free ent or not. It might be an automatic
426 * struct, so we don't free it for now, just in case.
432 kadm5_prune_principal(void *server_handle
,
433 krb5_principal princ
,
436 return __CALL(prune_principal
, (server_handle
, princ
, kvno
));