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_dup_context(void *server_handle
, void **dup_server_handle
)
44 return __CALL(dup_context
, (server_handle
, dup_server_handle
));
48 kadm5_chpass_principal(void *server_handle
,
52 return __CALL(chpass_principal
, (server_handle
, princ
, 0,
57 kadm5_chpass_principal_3(void *server_handle
,
61 krb5_key_salt_tuple
*ks_tuple
,
64 return __CALL(chpass_principal
, (server_handle
, princ
, keepold
,
65 n_ks_tuple
, ks_tuple
, password
));
69 kadm5_chpass_principal_with_key(void *server_handle
,
72 krb5_key_data
*key_data
)
74 return __CALL(chpass_principal_with_key
,
75 (server_handle
, princ
, 0, n_key_data
, key_data
));
79 kadm5_chpass_principal_with_key_3(void *server_handle
,
83 krb5_key_data
*key_data
)
85 return __CALL(chpass_principal_with_key
,
86 (server_handle
, princ
, keepold
, n_key_data
, key_data
));
90 kadm5_create_principal_3(void *server_handle
,
91 kadm5_principal_ent_t princ
,
94 krb5_key_salt_tuple
*ks_tuple
,
97 return __CALL(create_principal
,
98 (server_handle
, princ
, mask
, n_ks_tuple
, ks_tuple
, password
));
102 kadm5_create_principal(void *server_handle
,
103 kadm5_principal_ent_t princ
,
105 const char *password
)
107 return __CALL(create_principal
,
108 (server_handle
, princ
, mask
, 0, NULL
, password
));
112 kadm5_delete_principal(void *server_handle
,
113 krb5_principal princ
)
115 return __CALL(delete_principal
, (server_handle
, princ
));
119 kadm5_destroy (void *server_handle
)
121 return __CALL(destroy
, (server_handle
));
125 kadm5_flush (void *server_handle
)
127 return __CALL(flush
, (server_handle
));
131 kadm5_get_principal(void *server_handle
,
132 krb5_principal princ
,
133 kadm5_principal_ent_t out
,
136 return __CALL(get_principal
, (server_handle
, princ
, out
, mask
));
140 * Extract decrypted keys from kadm5_principal_ent_t object. Mostly a
141 * no-op for Heimdal because we fetch the entry with decrypted keys.
142 * Sadly this is not fully a no-op, as we have to allocate a copy.
144 * @server_handle is the kadm5 handle
145 * @entry is the HDB entry for the principal in question
146 * @ktype is the enctype to get a key for, or -1 to get the first one
147 * @stype is the salttype to get a key for, or -1 to get the first match
148 * @kvno is the kvno to search for, or -1 to get the first match (highest kvno)
149 * @keyblock is where the key will be placed
150 * @keysalt, if not NULL, is where the salt will be placed
151 * @kvnop, if not NULL, is where the selected kvno will be placed
154 kadm5_decrypt_key(void *server_handle
,
155 kadm5_principal_ent_t entry
,
156 int32_t ktype
, int32_t stype
,
157 int32_t kvno
, krb5_keyblock
*keyblock
,
158 krb5_keysalt
*keysalt
, int *kvnop
)
161 kadm5_server_context
*context
= server_handle
;
163 if (kvno
< 1 || stype
!= -1)
164 return KADM5_DECRYPT_USAGE_NOSUPP
;
166 for (i
= 0; i
< entry
->n_key_data
; i
++) {
167 if (ktype
!= entry
->key_data
[i
].key_data_kvno
)
170 keyblock
->keytype
= ktype
;
171 keyblock
->keyvalue
.length
= entry
->key_data
[i
].key_data_length
[0];
172 keyblock
->keyvalue
.data
= malloc(keyblock
->keyvalue
.length
);
173 if (keyblock
->keyvalue
.data
== NULL
)
174 return krb5_enomem(context
->context
);
175 memcpy(keyblock
->keyvalue
.data
,
176 entry
->key_data
[i
].key_data_contents
[0],
177 keyblock
->keyvalue
.length
);
184 kadm5_modify_principal(void *server_handle
,
185 kadm5_principal_ent_t princ
,
188 return __CALL(modify_principal
, (server_handle
, princ
, mask
));
192 kadm5_randkey_principal(void *server_handle
,
193 krb5_principal princ
,
194 krb5_keyblock
**new_keys
,
197 return __CALL(randkey_principal
, (server_handle
, princ
, FALSE
, 0, NULL
,
202 kadm5_randkey_principal_3(void *server_handle
,
203 krb5_principal princ
,
204 krb5_boolean keepold
,
206 krb5_key_salt_tuple
*ks_tuple
,
207 krb5_keyblock
**new_keys
,
210 return __CALL(randkey_principal
, (server_handle
, princ
, keepold
,
211 n_ks_tuple
, ks_tuple
, new_keys
, n_keys
));
215 kadm5_rename_principal(void *server_handle
,
216 krb5_principal source
,
217 krb5_principal target
)
219 return __CALL(rename_principal
, (server_handle
, source
, target
));
223 kadm5_get_principals(void *server_handle
,
224 const char *expression
,
228 return __CALL(get_principals
, (server_handle
, expression
, princs
, count
));
232 kadm5_iter_principals(void *server_handle
,
233 const char *expression
,
234 int (*cb
)(void *, const char *),
237 return __CALL(iter_principals
, (server_handle
, expression
, cb
, cbdata
));
241 kadm5_get_privs(void *server_handle
,
244 return __CALL(get_privs
, (server_handle
, privs
));
249 * This function is allows the caller to set new keys for a principal.
250 * This is a trivial wrapper around kadm5_setkey_principal_3().
253 kadm5_setkey_principal(void *server_handle
,
254 krb5_principal princ
,
255 krb5_keyblock
*new_keys
,
258 return kadm5_setkey_principal_3(server_handle
, princ
, 0, 0, NULL
,
263 * This function is allows the caller to set new keys for a principal.
264 * This is a simple wrapper around kadm5_get_principal() and
265 * kadm5_modify_principal().
268 kadm5_setkey_principal_3(void *server_handle
,
269 krb5_principal princ
,
270 krb5_boolean keepold
,
271 int n_ks_tuple
, krb5_key_salt_tuple
*ks_tuple
,
272 krb5_keyblock
*keyblocks
,
275 kadm5_principal_ent_rec princ_ent
;
277 krb5_key_data
*new_key_data
= NULL
;
279 kadm5_server_context
*context
= server_handle
;
283 if (n_ks_tuple
> 0 && n_ks_tuple
!= n_keys
)
284 return KADM5_SETKEY3_ETYPE_MISMATCH
;
287 * If setkey_principal_3 is defined in the server handle, use that.
289 if (__CALLABLE(setkey_principal_3
))
290 return __CALL(setkey_principal_3
,
291 (server_handle
, princ
, keepold
, n_ks_tuple
, ks_tuple
,
295 * Otherwise, simulate it via a get, update, modify sequence.
297 ret
= kadm5_get_principal(server_handle
, princ
, &princ_ent
,
298 KADM5_KVNO
| KADM5_PRINCIPAL
| KADM5_KEY_DATA
);
303 new_key_data
= calloc((n_keys
+ princ_ent
.n_key_data
),
304 sizeof(*new_key_data
));
305 if (new_key_data
== NULL
) {
306 ret
= krb5_enomem(context
->context
);
310 memcpy(&new_key_data
[n_keys
], &princ_ent
.key_data
[0],
311 princ_ent
.n_key_data
* sizeof (princ_ent
.key_data
[0]));
313 new_key_data
= calloc(n_keys
, sizeof(*new_key_data
));
314 if (new_key_data
== NULL
) {
315 ret
= krb5_enomem(context
->context
);
321 for (i
= 0; i
< n_keys
; i
++) {
322 new_key_data
[i
].key_data_ver
= 2;
325 new_key_data
[i
].key_data_kvno
= princ_ent
.kvno
;
326 new_key_data
[i
].key_data_type
[0] = keyblocks
[i
].keytype
;
327 new_key_data
[i
].key_data_length
[0] = keyblocks
[i
].keyvalue
.length
;
328 new_key_data
[i
].key_data_contents
[0] =
329 malloc(keyblocks
[i
].keyvalue
.length
);
330 if (new_key_data
[i
].key_data_contents
[0] == NULL
) {
331 ret
= krb5_enomem(context
->context
);
334 memcpy(new_key_data
[i
].key_data_contents
[0],
335 keyblocks
[i
].keyvalue
.data
,
336 keyblocks
[i
].keyvalue
.length
);
339 * Salt (but there's no salt, just salttype, which is kinda
340 * silly -- what's the point of setkey_3() then, besides
343 new_key_data
[i
].key_data_type
[1] = 0;
344 if (n_ks_tuple
> 0) {
345 if (ks_tuple
[i
].ks_enctype
!= keyblocks
[i
].keytype
) {
346 ret
= KADM5_SETKEY3_ETYPE_MISMATCH
;
349 new_key_data
[i
].key_data_type
[1] = ks_tuple
[i
].ks_salttype
;
351 new_key_data
[i
].key_data_length
[1] = 0;
352 new_key_data
[i
].key_data_contents
[1] = NULL
;
357 for (i
= 0; i
< princ_ent
.n_key_data
; i
++) {
358 free(princ_ent
.key_data
[i
].key_data_contents
[0]);
359 free(princ_ent
.key_data
[i
].key_data_contents
[1]);
362 free(princ_ent
.key_data
);
363 princ_ent
.key_data
= new_key_data
;
364 princ_ent
.n_key_data
= n_keys
+ (keepold
? princ_ent
.n_key_data
: 0);
367 /* Modify the principal */
368 ret
= kadm5_modify_principal(server_handle
, &princ_ent
, KADM5_KVNO
| KADM5_KEY_DATA
);
371 if (new_key_data
!= NULL
) {
372 for (i
= 0; i
< n_keys
; i
++) {
373 free(new_key_data
[i
].key_data_contents
[0]);
374 free(new_key_data
[i
].key_data_contents
[1]);
378 kadm5_free_principal_ent(server_handle
, &princ_ent
);
384 kadm5_lock(void *server_handle
)
386 return __CALL(lock
, (server_handle
));
390 kadm5_unlock(void *server_handle
)
392 return __CALL(unlock
, (server_handle
));
397 kadm5_create_policy(void *server_handle
,
398 kadm5_policy_ent_t policy
, long mask
)
400 return KADM5_POLICY_OP_NOSUPP
;
404 kadm5_delete_policy(void *server_handle
, char *name
)
406 return KADM5_POLICY_OP_NOSUPP
;
411 kadm5_modify_policy(void *server_handle
, kadm5_policy_ent_t policy
,
414 return KADM5_POLICY_OP_NOSUPP
;
418 kadm5_get_policy(void *server_handle
, char *policy
, kadm5_policy_ent_t ent
)
420 memset(ent
, 0, sizeof (*ent
));
421 return KADM5_POLICY_OP_NOSUPP
;
426 kadm5_get_policies(void *server_handle
, char *exp
, char ***pols
, int *count
)
431 return KADM5_POLICY_OP_NOSUPP
;
435 kadm5_free_policy_ent(kadm5_policy_ent_t ent
)
440 * Not clear if we should free ent or not. It might be an automatic
441 * struct, so we don't free it for now, just in case.
447 kadm5_prune_principal(void *server_handle
,
448 krb5_principal princ
,
451 return __CALL(prune_principal
, (server_handle
, princ
, kvno
));