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 static char *rcsid
= "$Header$";
33 #include <rpc/rpc.h> /* SUNWresync121 XXX */
34 #include <kadm5/admin.h>
35 #include <kadm5/kadm_rpc.h>
40 #include "client_internal.h"
42 #ifdef DEBUG /* SUNWresync14 XXX */
43 #define eret() {clnt_perror(handle->clnt, "null ret"); return KADM5_RPC_ERROR;}
45 #define eret() return KADM5_RPC_ERROR
49 kadm5_create_principal(void *server_handle
,
50 kadm5_principal_ent_t princ
, long mask
,
55 kadm5_server_handle_t handle
= server_handle
;
57 CHECK_HANDLE(server_handle
);
59 memset(&arg
, 0, sizeof(arg
));
62 arg
.api_version
= handle
->api_version
;
67 if (handle
->api_version
== KADM5_API_VERSION_1
) {
68 memcpy(&arg
.rec
, princ
, sizeof(kadm5_principal_ent_rec_v1
));
70 memcpy(&arg
.rec
, princ
, sizeof(kadm5_principal_ent_rec
));
72 if (handle
->api_version
== KADM5_API_VERSION_1
) {
74 * hack hack cough cough.
75 * krb5_unparse name dumps core if we pass it in garbage
76 * or null. So, since the client is not allowed to set mod_name
77 * anyway, we just fill it in with a dummy principal. The server of
78 * course ignores this.
80 /* krb5_parse_name(handle->context, "bogus/bogus", &arg.rec.mod_name); */
81 arg
.rec
.mod_name
= NULL
;
83 arg
.rec
.mod_name
= NULL
;
85 if(!(mask
& KADM5_POLICY
))
86 arg
.rec
.policy
= NULL
;
87 if (! (mask
& KADM5_KEY_DATA
)) {
88 arg
.rec
.n_key_data
= 0;
89 arg
.rec
.key_data
= NULL
;
91 if (! (mask
& KADM5_TL_DATA
)) {
92 arg
.rec
.n_tl_data
= 0;
93 arg
.rec
.tl_data
= NULL
;
96 r
= create_principal_2(&arg
, handle
->clnt
);
98 if (handle
->api_version
== KADM5_API_VERSION_1
)
99 krb5_free_principal(handle
->context
, arg
.rec
.mod_name
);
107 kadm5_create_principal_3(void *server_handle
,
108 kadm5_principal_ent_t princ
, long mask
,
110 krb5_key_salt_tuple
*ks_tuple
,
115 kadm5_server_handle_t handle
= server_handle
;
117 CHECK_HANDLE(server_handle
);
119 memset(&arg
, 0, sizeof(arg
));
122 arg
.api_version
= handle
->api_version
;
123 arg
.n_ks_tuple
= n_ks_tuple
;
124 arg
.ks_tuple
= ks_tuple
;
129 if (handle
->api_version
== KADM5_API_VERSION_1
) {
130 memcpy(&arg
.rec
, princ
, sizeof(kadm5_principal_ent_rec_v1
));
132 memcpy(&arg
.rec
, princ
, sizeof(kadm5_principal_ent_rec
));
134 if (handle
->api_version
== KADM5_API_VERSION_1
) {
136 * hack hack cough cough.
137 * krb5_unparse name dumps core if we pass it in garbage
138 * or null. So, since the client is not allowed to set mod_name
139 * anyway, we just fill it in with a dummy principal. The server of
140 * course ignores this.
142 krb5_parse_name(handle
->context
, "bogus/bogus", &arg
.rec
.mod_name
);
144 arg
.rec
.mod_name
= NULL
;
146 if(!(mask
& KADM5_POLICY
))
147 arg
.rec
.policy
= NULL
;
148 if (! (mask
& KADM5_KEY_DATA
)) {
149 arg
.rec
.n_key_data
= 0;
150 arg
.rec
.key_data
= NULL
;
152 if (! (mask
& KADM5_TL_DATA
)) {
153 arg
.rec
.n_tl_data
= 0;
154 arg
.rec
.tl_data
= NULL
;
157 r
= create_principal3_2(&arg
, handle
->clnt
);
159 if (handle
->api_version
== KADM5_API_VERSION_1
)
160 krb5_free_principal(handle
->context
, arg
.rec
.mod_name
);
168 kadm5_delete_principal(void *server_handle
, krb5_principal principal
)
172 kadm5_server_handle_t handle
= server_handle
;
174 CHECK_HANDLE(server_handle
);
176 if(principal
== NULL
)
178 arg
.princ
= principal
;
179 arg
.api_version
= handle
->api_version
;
180 r
= delete_principal_2(&arg
, handle
->clnt
);
187 kadm5_modify_principal(void *server_handle
,
188 kadm5_principal_ent_t princ
, long mask
)
192 kadm5_server_handle_t handle
= server_handle
;
194 CHECK_HANDLE(server_handle
);
196 memset(&arg
, 0, sizeof(arg
));
198 arg
.api_version
= handle
->api_version
;
200 * cough cough gag gag
201 * see comment in create_principal.
205 if (handle
->api_version
== KADM5_API_VERSION_1
) {
206 memcpy(&arg
.rec
, princ
, sizeof(kadm5_principal_ent_rec_v1
));
208 memcpy(&arg
.rec
, princ
, sizeof(kadm5_principal_ent_rec
));
210 if(!(mask
& KADM5_POLICY
))
211 arg
.rec
.policy
= NULL
;
212 if (! (mask
& KADM5_KEY_DATA
)) {
213 arg
.rec
.n_key_data
= 0;
214 arg
.rec
.key_data
= NULL
;
216 if (! (mask
& KADM5_TL_DATA
)) {
217 arg
.rec
.n_tl_data
= 0;
218 arg
.rec
.tl_data
= NULL
;
221 if (handle
->api_version
== KADM5_API_VERSION_1
) {
223 * See comment in create_principal
225 krb5_parse_name(handle
->context
, "bogus/bogus", &arg
.rec
.mod_name
);
227 arg
.rec
.mod_name
= NULL
;
229 r
= modify_principal_2(&arg
, handle
->clnt
);
231 if (handle
->api_version
== KADM5_API_VERSION_1
)
232 krb5_free_principal(handle
->context
, arg
.rec
.mod_name
);
240 kadm5_get_principal(void *server_handle
,
241 krb5_principal princ
, kadm5_principal_ent_t ent
,
246 kadm5_server_handle_t handle
= server_handle
;
248 CHECK_HANDLE(server_handle
);
253 if (handle
->api_version
== KADM5_API_VERSION_1
)
254 arg
.mask
= KADM5_PRINCIPAL_NORMAL_MASK
;
257 arg
.api_version
= handle
->api_version
;
258 r
= get_principal_2(&arg
, handle
->clnt
);
261 if (handle
->api_version
== KADM5_API_VERSION_1
) {
262 kadm5_principal_ent_t_v1
*entp
;
264 entp
= (kadm5_principal_ent_t_v1
*) ent
;
266 if (!(*entp
= (kadm5_principal_ent_t_v1
)
267 malloc(sizeof(kadm5_principal_ent_rec_v1
))))
269 /* this memcpy works because the v1 structure is an initial
270 subset of the v2 struct. C guarantees that this will
271 result in the same layout in memory */
272 memcpy(*entp
, &r
->rec
, sizeof(**entp
));
278 memcpy(ent
, &r
->rec
, sizeof(r
->rec
));
285 kadm5_get_principals(void *server_handle
,
286 char *exp
, char ***princs
, int *count
)
290 kadm5_server_handle_t handle
= server_handle
;
292 CHECK_HANDLE(server_handle
);
294 if(princs
== NULL
|| count
== NULL
)
297 arg
.api_version
= handle
->api_version
;
298 r
= get_princs_2(&arg
, handle
->clnt
);
313 kadm5_rename_principal(void *server_handle
,
314 krb5_principal source
, krb5_principal dest
)
318 kadm5_server_handle_t handle
= server_handle
;
320 CHECK_HANDLE(server_handle
);
324 arg
.api_version
= handle
->api_version
;
325 if (source
== NULL
|| dest
== NULL
)
327 r
= rename_principal_2(&arg
, handle
->clnt
);
334 kadm5_chpass_principal(void *server_handle
,
335 krb5_principal princ
, char *password
)
339 kadm5_server_handle_t handle
= server_handle
;
341 CHECK_HANDLE(server_handle
);
345 arg
.api_version
= handle
->api_version
;
349 r
= chpass_principal_2(&arg
, handle
->clnt
);
356 kadm5_chpass_principal_3(void *server_handle
,
357 krb5_principal princ
, krb5_boolean keepold
,
358 int n_ks_tuple
, krb5_key_salt_tuple
*ks_tuple
,
363 kadm5_server_handle_t handle
= server_handle
;
365 CHECK_HANDLE(server_handle
);
369 arg
.api_version
= handle
->api_version
;
370 arg
.keepold
= keepold
;
371 arg
.n_ks_tuple
= n_ks_tuple
;
372 arg
.ks_tuple
= ks_tuple
;
376 r
= chpass_principal3_2(&arg
, handle
->clnt
);
383 kadm5_setv4key_principal(void *server_handle
,
384 krb5_principal princ
,
385 krb5_keyblock
*keyblock
)
389 kadm5_server_handle_t handle
= server_handle
;
391 CHECK_HANDLE(server_handle
);
394 arg
.keyblock
= keyblock
;
395 arg
.api_version
= handle
->api_version
;
397 if(princ
== NULL
|| keyblock
== NULL
)
399 r
= setv4key_principal_2(&arg
, handle
->clnt
);
406 kadm5_setkey_principal(void *server_handle
,
407 krb5_principal princ
,
408 krb5_keyblock
*keyblocks
,
413 kadm5_server_handle_t handle
= server_handle
;
415 CHECK_HANDLE(server_handle
);
418 arg
.keyblocks
= keyblocks
;
420 arg
.api_version
= handle
->api_version
;
422 if(princ
== NULL
|| keyblocks
== NULL
)
424 r
= setkey_principal_2(&arg
, handle
->clnt
);
431 kadm5_setkey_principal_3(void *server_handle
,
432 krb5_principal princ
,
433 krb5_boolean keepold
, int n_ks_tuple
,
434 krb5_key_salt_tuple
*ks_tuple
,
435 krb5_keyblock
*keyblocks
,
440 kadm5_server_handle_t handle
= server_handle
;
442 CHECK_HANDLE(server_handle
);
445 arg
.keyblocks
= keyblocks
;
447 arg
.api_version
= handle
->api_version
;
448 arg
.keepold
= keepold
;
449 arg
.n_ks_tuple
= n_ks_tuple
;
450 arg
.ks_tuple
= ks_tuple
;
452 if(princ
== NULL
|| keyblocks
== NULL
)
454 r
= setkey_principal3_2(&arg
, handle
->clnt
);
462 * This routine implements just the "old" randkey_principal code.
463 * The code in the kadmin client sometimes needs to call this
464 * directly when the kadm5_randkey_principal_3 call fails.
466 * The kadmin client utility uses a specific set of key/salt tuples,
467 * so the standard fallback in kadm5_randkey_principal (see below)
468 * will not work because it would result in kadm5_randkey_principal_3
469 * being called twice - once with the specific key/salts specified by
470 * kadmin and once with the NULL set (used to indicate that the server
471 * should use the full set of supported enctypes). Making this
472 * routine separate makes the code simpler and avoids making the
473 * kadm5_randkey_principal_3 twice from kadmin.
476 kadm5_randkey_principal_old(void *server_handle
,
477 krb5_principal princ
,
483 kadm5_server_handle_t handle
= server_handle
;
491 CHECK_HANDLE(server_handle
);
494 arg
.api_version
= handle
->api_version
;
498 r
= chrand_principal_2(&arg
, handle
->clnt
);
500 return KADM5_RPC_ERROR
;
501 if (handle
->api_version
== KADM5_API_VERSION_1
) {
503 krb5_copy_keyblock(handle
->context
, &r
->key
, key
);
504 } else if (key
&& (r
->n_keys
> 0)) {
505 *key
= (krb5_keyblock
*) malloc(
506 r
->n_keys
*sizeof(krb5_keyblock
));
509 for (i
= 0; i
< r
->n_keys
; i
++) {
510 ret
= krb5_copy_keyblock_contents(
527 kadm5_randkey_principal_3(void *server_handle
,
528 krb5_principal princ
,
529 krb5_boolean keepold
, int n_ks_tuple
,
530 krb5_key_salt_tuple
*ks_tuple
,
531 krb5_keyblock
**key
, int *n_keys
)
535 kadm5_server_handle_t handle
= server_handle
;
538 /* Solaris Kerberos - For safety */
544 CHECK_HANDLE(server_handle
);
547 arg
.api_version
= handle
->api_version
;
548 arg
.keepold
= keepold
;
549 arg
.n_ks_tuple
= n_ks_tuple
;
550 arg
.ks_tuple
= ks_tuple
;
554 r
= chrand_principal3_2(&arg
, handle
->clnt
);
557 if (handle
->api_version
== KADM5_API_VERSION_1
) {
559 krb5_copy_keyblock(handle
->context
, &r
->key
, key
);
565 *key
= (krb5_keyblock
*)
566 malloc(r
->n_keys
*sizeof(krb5_keyblock
));
569 for (i
= 0; i
< r
->n_keys
; i
++) {
570 ret
= krb5_copy_keyblock_contents(handle
->context
,
586 kadm5_randkey_principal(void *server_handle
,
587 krb5_principal princ
,
588 krb5_keyblock
**key
, int *n_keys
)
590 /* Solaris Kerberos */
594 * Default to trying the newest API to insure that the full
595 * set of enctypes is created.
597 kret
= kadm5_randkey_principal_3(server_handle
, princ
, FALSE
,
598 0, NULL
, key
, n_keys
);
601 * We will get an RPC error if the RPC call failed which
602 * will normally indicate that the remote procedure did not
603 * exist on the server, so try the older API.
605 if (kret
== KADM5_RPC_ERROR
) {
606 kret
= kadm5_randkey_principal_old(server_handle
, princ
,
612 /* not supported on client side */
613 kadm5_ret_t
kadm5_decrypt_key(void *server_handle
,
614 kadm5_principal_ent_t entry
, krb5_int32
615 ktype
, krb5_int32 stype
, krb5_int32
616 kvno
, krb5_keyblock
*keyblock
,
617 krb5_keysalt
*keysalt
, int *kvnop
)