2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
8 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
10 * Openvision retains the copyright to derivative works of
11 * this source code. Do *NOT* create a derivative of this
12 * source code before consulting with your legal department.
13 * Do *NOT* integrate *ANY* of this source code into another
14 * product before consulting with your legal department.
16 * For further information, read the top-level Openvision
17 * copyright which is contained in the top-level MIT Kerberos
20 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
26 * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
31 #if !defined(lint) && !defined(__CODECENTER__)
32 static char *rcsid
= "$Header$";
35 #include <rpc/rpc.h> /* SUNWresync121 XXX */
36 #include <kadm5/admin.h>
37 #include <kadm5/kadm_rpc.h>
42 #include "client_internal.h"
44 #ifdef DEBUG /* SUNWresync14 XXX */
45 #define eret() {clnt_perror(handle->clnt, "null ret"); return KADM5_RPC_ERROR;}
47 #define eret() return KADM5_RPC_ERROR
51 kadm5_create_principal(void *server_handle
,
52 kadm5_principal_ent_t princ
, long mask
,
57 kadm5_server_handle_t handle
= server_handle
;
59 CHECK_HANDLE(server_handle
);
61 memset(&arg
, 0, sizeof(arg
));
64 arg
.api_version
= handle
->api_version
;
69 if (handle
->api_version
== KADM5_API_VERSION_1
) {
70 memcpy(&arg
.rec
, princ
, sizeof(kadm5_principal_ent_rec_v1
));
72 memcpy(&arg
.rec
, princ
, sizeof(kadm5_principal_ent_rec
));
74 if (handle
->api_version
== KADM5_API_VERSION_1
) {
76 * hack hack cough cough.
77 * krb5_unparse name dumps core if we pass it in garbage
78 * or null. So, since the client is not allowed to set mod_name
79 * anyway, we just fill it in with a dummy principal. The server of
80 * course ignores this.
82 /* krb5_parse_name(handle->context, "bogus/bogus", &arg.rec.mod_name); */
83 arg
.rec
.mod_name
= NULL
;
85 arg
.rec
.mod_name
= NULL
;
87 if(!(mask
& KADM5_POLICY
))
88 arg
.rec
.policy
= NULL
;
89 if (! (mask
& KADM5_KEY_DATA
)) {
90 arg
.rec
.n_key_data
= 0;
91 arg
.rec
.key_data
= NULL
;
93 if (! (mask
& KADM5_TL_DATA
)) {
94 arg
.rec
.n_tl_data
= 0;
95 arg
.rec
.tl_data
= NULL
;
98 r
= create_principal_2(&arg
, handle
->clnt
);
100 if (handle
->api_version
== KADM5_API_VERSION_1
)
101 krb5_free_principal(handle
->context
, arg
.rec
.mod_name
);
109 kadm5_create_principal_3(void *server_handle
,
110 kadm5_principal_ent_t princ
, long mask
,
112 krb5_key_salt_tuple
*ks_tuple
,
117 kadm5_server_handle_t handle
= server_handle
;
119 CHECK_HANDLE(server_handle
);
121 memset(&arg
, 0, sizeof(arg
));
124 arg
.api_version
= handle
->api_version
;
125 arg
.n_ks_tuple
= n_ks_tuple
;
126 arg
.ks_tuple
= ks_tuple
;
131 if (handle
->api_version
== KADM5_API_VERSION_1
) {
132 memcpy(&arg
.rec
, princ
, sizeof(kadm5_principal_ent_rec_v1
));
134 memcpy(&arg
.rec
, princ
, sizeof(kadm5_principal_ent_rec
));
136 if (handle
->api_version
== KADM5_API_VERSION_1
) {
138 * hack hack cough cough.
139 * krb5_unparse name dumps core if we pass it in garbage
140 * or null. So, since the client is not allowed to set mod_name
141 * anyway, we just fill it in with a dummy principal. The server of
142 * course ignores this.
144 krb5_parse_name(handle
->context
, "bogus/bogus", &arg
.rec
.mod_name
);
146 arg
.rec
.mod_name
= NULL
;
148 if(!(mask
& KADM5_POLICY
))
149 arg
.rec
.policy
= NULL
;
150 if (! (mask
& KADM5_KEY_DATA
)) {
151 arg
.rec
.n_key_data
= 0;
152 arg
.rec
.key_data
= NULL
;
154 if (! (mask
& KADM5_TL_DATA
)) {
155 arg
.rec
.n_tl_data
= 0;
156 arg
.rec
.tl_data
= NULL
;
159 r
= create_principal3_2(&arg
, handle
->clnt
);
161 if (handle
->api_version
== KADM5_API_VERSION_1
)
162 krb5_free_principal(handle
->context
, arg
.rec
.mod_name
);
170 kadm5_delete_principal(void *server_handle
, krb5_principal principal
)
174 kadm5_server_handle_t handle
= server_handle
;
176 CHECK_HANDLE(server_handle
);
178 if(principal
== NULL
)
180 arg
.princ
= principal
;
181 arg
.api_version
= handle
->api_version
;
182 r
= delete_principal_2(&arg
, handle
->clnt
);
189 kadm5_modify_principal(void *server_handle
,
190 kadm5_principal_ent_t princ
, long mask
)
194 kadm5_server_handle_t handle
= server_handle
;
196 CHECK_HANDLE(server_handle
);
198 memset(&arg
, 0, sizeof(arg
));
200 arg
.api_version
= handle
->api_version
;
202 * cough cough gag gag
203 * see comment in create_principal.
207 if (handle
->api_version
== KADM5_API_VERSION_1
) {
208 memcpy(&arg
.rec
, princ
, sizeof(kadm5_principal_ent_rec_v1
));
210 memcpy(&arg
.rec
, princ
, sizeof(kadm5_principal_ent_rec
));
212 if(!(mask
& KADM5_POLICY
))
213 arg
.rec
.policy
= NULL
;
214 if (! (mask
& KADM5_KEY_DATA
)) {
215 arg
.rec
.n_key_data
= 0;
216 arg
.rec
.key_data
= NULL
;
218 if (! (mask
& KADM5_TL_DATA
)) {
219 arg
.rec
.n_tl_data
= 0;
220 arg
.rec
.tl_data
= NULL
;
223 if (handle
->api_version
== KADM5_API_VERSION_1
) {
225 * See comment in create_principal
227 krb5_parse_name(handle
->context
, "bogus/bogus", &arg
.rec
.mod_name
);
229 arg
.rec
.mod_name
= NULL
;
231 r
= modify_principal_2(&arg
, handle
->clnt
);
233 if (handle
->api_version
== KADM5_API_VERSION_1
)
234 krb5_free_principal(handle
->context
, arg
.rec
.mod_name
);
242 kadm5_get_principal(void *server_handle
,
243 krb5_principal princ
, kadm5_principal_ent_t ent
,
248 kadm5_server_handle_t handle
= server_handle
;
250 CHECK_HANDLE(server_handle
);
255 if (handle
->api_version
== KADM5_API_VERSION_1
)
256 arg
.mask
= KADM5_PRINCIPAL_NORMAL_MASK
;
259 arg
.api_version
= handle
->api_version
;
260 r
= get_principal_2(&arg
, handle
->clnt
);
263 if (handle
->api_version
== KADM5_API_VERSION_1
) {
264 kadm5_principal_ent_t_v1
*entp
;
266 entp
= (kadm5_principal_ent_t_v1
*) ent
;
268 if (!(*entp
= (kadm5_principal_ent_t_v1
)
269 malloc(sizeof(kadm5_principal_ent_rec_v1
))))
271 /* this memcpy works because the v1 structure is an initial
272 subset of the v2 struct. C guarantees that this will
273 result in the same layout in memory */
274 memcpy(*entp
, &r
->rec
, sizeof(**entp
));
280 memcpy(ent
, &r
->rec
, sizeof(r
->rec
));
287 kadm5_get_principals(void *server_handle
,
288 char *exp
, char ***princs
, int *count
)
292 kadm5_server_handle_t handle
= server_handle
;
294 CHECK_HANDLE(server_handle
);
296 if(princs
== NULL
|| count
== NULL
)
299 arg
.api_version
= handle
->api_version
;
300 r
= get_princs_2(&arg
, handle
->clnt
);
315 kadm5_rename_principal(void *server_handle
,
316 krb5_principal source
, krb5_principal dest
)
320 kadm5_server_handle_t handle
= server_handle
;
322 CHECK_HANDLE(server_handle
);
326 arg
.api_version
= handle
->api_version
;
327 if (source
== NULL
|| dest
== NULL
)
329 r
= rename_principal_2(&arg
, handle
->clnt
);
336 kadm5_chpass_principal(void *server_handle
,
337 krb5_principal princ
, char *password
)
341 kadm5_server_handle_t handle
= server_handle
;
343 CHECK_HANDLE(server_handle
);
347 arg
.api_version
= handle
->api_version
;
351 r
= chpass_principal_2(&arg
, handle
->clnt
);
358 kadm5_chpass_principal_3(void *server_handle
,
359 krb5_principal princ
, krb5_boolean keepold
,
360 int n_ks_tuple
, krb5_key_salt_tuple
*ks_tuple
,
365 kadm5_server_handle_t handle
= server_handle
;
367 CHECK_HANDLE(server_handle
);
371 arg
.api_version
= handle
->api_version
;
372 arg
.keepold
= keepold
;
373 arg
.n_ks_tuple
= n_ks_tuple
;
374 arg
.ks_tuple
= ks_tuple
;
378 r
= chpass_principal3_2(&arg
, handle
->clnt
);
385 kadm5_setv4key_principal(void *server_handle
,
386 krb5_principal princ
,
387 krb5_keyblock
*keyblock
)
391 kadm5_server_handle_t handle
= server_handle
;
393 CHECK_HANDLE(server_handle
);
396 arg
.keyblock
= keyblock
;
397 arg
.api_version
= handle
->api_version
;
399 if(princ
== NULL
|| keyblock
== NULL
)
401 r
= setv4key_principal_2(&arg
, handle
->clnt
);
408 kadm5_setkey_principal(void *server_handle
,
409 krb5_principal princ
,
410 krb5_keyblock
*keyblocks
,
415 kadm5_server_handle_t handle
= server_handle
;
417 CHECK_HANDLE(server_handle
);
420 arg
.keyblocks
= keyblocks
;
422 arg
.api_version
= handle
->api_version
;
424 if(princ
== NULL
|| keyblocks
== NULL
)
426 r
= setkey_principal_2(&arg
, handle
->clnt
);
433 kadm5_setkey_principal_3(void *server_handle
,
434 krb5_principal princ
,
435 krb5_boolean keepold
, int n_ks_tuple
,
436 krb5_key_salt_tuple
*ks_tuple
,
437 krb5_keyblock
*keyblocks
,
442 kadm5_server_handle_t handle
= server_handle
;
444 CHECK_HANDLE(server_handle
);
447 arg
.keyblocks
= keyblocks
;
449 arg
.api_version
= handle
->api_version
;
450 arg
.keepold
= keepold
;
451 arg
.n_ks_tuple
= n_ks_tuple
;
452 arg
.ks_tuple
= ks_tuple
;
454 if(princ
== NULL
|| keyblocks
== NULL
)
456 r
= setkey_principal3_2(&arg
, handle
->clnt
);
464 * This routine implements just the "old" randkey_principal code.
465 * The code in the kadmin client sometimes needs to call this
466 * directly when the kadm5_randkey_principal_3 call fails.
468 * The kadmin client utility uses a specific set of key/salt tuples,
469 * so the standard fallback in kadm5_randkey_principal (see below)
470 * will not work because it would result in kadm5_randkey_principal_3
471 * being called twice - once with the specific key/salts specified by
472 * kadmin and once with the NULL set (used to indicate that the server
473 * should use the full set of supported enctypes). Making this
474 * routine separate makes the code simpler and avoids making the
475 * kadm5_randkey_principal_3 twice from kadmin.
478 kadm5_randkey_principal_old(void *server_handle
,
479 krb5_principal princ
,
485 kadm5_server_handle_t handle
= server_handle
;
493 CHECK_HANDLE(server_handle
);
496 arg
.api_version
= handle
->api_version
;
500 r
= chrand_principal_2(&arg
, handle
->clnt
);
502 return KADM5_RPC_ERROR
;
503 if (handle
->api_version
== KADM5_API_VERSION_1
) {
505 krb5_copy_keyblock(handle
->context
, &r
->key
, key
);
506 } else if (key
&& (r
->n_keys
> 0)) {
507 *key
= (krb5_keyblock
*) malloc(
508 r
->n_keys
*sizeof(krb5_keyblock
));
511 for (i
= 0; i
< r
->n_keys
; i
++) {
512 ret
= krb5_copy_keyblock_contents(
529 kadm5_randkey_principal_3(void *server_handle
,
530 krb5_principal princ
,
531 krb5_boolean keepold
, int n_ks_tuple
,
532 krb5_key_salt_tuple
*ks_tuple
,
533 krb5_keyblock
**key
, int *n_keys
)
537 kadm5_server_handle_t handle
= server_handle
;
540 /* Solaris Kerberos - For safety */
546 CHECK_HANDLE(server_handle
);
549 arg
.api_version
= handle
->api_version
;
550 arg
.keepold
= keepold
;
551 arg
.n_ks_tuple
= n_ks_tuple
;
552 arg
.ks_tuple
= ks_tuple
;
556 r
= chrand_principal3_2(&arg
, handle
->clnt
);
559 if (handle
->api_version
== KADM5_API_VERSION_1
) {
561 krb5_copy_keyblock(handle
->context
, &r
->key
, key
);
567 *key
= (krb5_keyblock
*)
568 malloc(r
->n_keys
*sizeof(krb5_keyblock
));
571 for (i
= 0; i
< r
->n_keys
; i
++) {
572 ret
= krb5_copy_keyblock_contents(handle
->context
,
588 kadm5_randkey_principal(void *server_handle
,
589 krb5_principal princ
,
590 krb5_keyblock
**key
, int *n_keys
)
592 /* Solaris Kerberos */
596 * Default to trying the newest API to insure that the full
597 * set of enctypes is created.
599 kret
= kadm5_randkey_principal_3(server_handle
, princ
, FALSE
,
600 0, NULL
, key
, n_keys
);
603 * We will get an RPC error if the RPC call failed which
604 * will normally indicate that the remote procedure did not
605 * exist on the server, so try the older API.
607 if (kret
== KADM5_RPC_ERROR
) {
608 kret
= kadm5_randkey_principal_old(server_handle
, princ
,
614 /* not supported on client side */
615 kadm5_ret_t
kadm5_decrypt_key(void *server_handle
,
616 kadm5_principal_ent_t entry
, krb5_int32
617 ktype
, krb5_int32 stype
, krb5_int32
618 kvno
, krb5_keyblock
*keyblock
,
619 krb5_keysalt
*keysalt
, int *kvnop
)