dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / krb5 / kadm5 / clnt / client_principal.c
blob4afa9fca5d66f4ea4e967d2d56f694e4ff6ea670
1 /*
2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
7 /*
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
18 * copyright.
20 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
26 * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
28 * $Header$
31 static char *rcsid = "$Header$";
33 #include <rpc/rpc.h> /* SUNWresync121 XXX */
34 #include <kadm5/admin.h>
35 #include <kadm5/kadm_rpc.h>
36 #ifdef HAVE_MEMORY_H
37 #include <memory.h>
38 #endif
39 #include <errno.h>
40 #include "client_internal.h"
42 #ifdef DEBUG /* SUNWresync14 XXX */
43 #define eret() {clnt_perror(handle->clnt, "null ret"); return KADM5_RPC_ERROR;}
44 #else
45 #define eret() return KADM5_RPC_ERROR
46 #endif
48 kadm5_ret_t
49 kadm5_create_principal(void *server_handle,
50 kadm5_principal_ent_t princ, long mask,
51 char *pw)
53 generic_ret *r;
54 cprinc_arg arg;
55 kadm5_server_handle_t handle = server_handle;
57 CHECK_HANDLE(server_handle);
59 memset(&arg, 0, sizeof(arg));
60 arg.mask = mask;
61 arg.passwd = pw;
62 arg.api_version = handle->api_version;
64 if(princ == NULL)
65 return EINVAL;
67 if (handle->api_version == KADM5_API_VERSION_1) {
68 memcpy(&arg.rec, princ, sizeof(kadm5_principal_ent_rec_v1));
69 } else {
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;
82 } else
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);
101 if(r == NULL)
102 eret();
103 return r->code;
106 kadm5_ret_t
107 kadm5_create_principal_3(void *server_handle,
108 kadm5_principal_ent_t princ, long mask,
109 int n_ks_tuple,
110 krb5_key_salt_tuple *ks_tuple,
111 char *pw)
113 generic_ret *r;
114 cprinc3_arg arg;
115 kadm5_server_handle_t handle = server_handle;
117 CHECK_HANDLE(server_handle);
119 memset(&arg, 0, sizeof(arg));
120 arg.mask = mask;
121 arg.passwd = pw;
122 arg.api_version = handle->api_version;
123 arg.n_ks_tuple = n_ks_tuple;
124 arg.ks_tuple = ks_tuple;
126 if(princ == NULL)
127 return EINVAL;
129 if (handle->api_version == KADM5_API_VERSION_1) {
130 memcpy(&arg.rec, princ, sizeof(kadm5_principal_ent_rec_v1));
131 } else {
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);
143 } else
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);
162 if(r == NULL)
163 eret();
164 return r->code;
167 kadm5_ret_t
168 kadm5_delete_principal(void *server_handle, krb5_principal principal)
170 dprinc_arg arg;
171 generic_ret *r;
172 kadm5_server_handle_t handle = server_handle;
174 CHECK_HANDLE(server_handle);
176 if(principal == NULL)
177 return EINVAL;
178 arg.princ = principal;
179 arg.api_version = handle->api_version;
180 r = delete_principal_2(&arg, handle->clnt);
181 if(r == NULL)
182 eret();
183 return r->code;
186 kadm5_ret_t
187 kadm5_modify_principal(void *server_handle,
188 kadm5_principal_ent_t princ, long mask)
190 mprinc_arg arg;
191 generic_ret *r;
192 kadm5_server_handle_t handle = server_handle;
194 CHECK_HANDLE(server_handle);
196 memset(&arg, 0, sizeof(arg));
197 arg.mask = mask;
198 arg.api_version = handle->api_version;
200 * cough cough gag gag
201 * see comment in create_principal.
203 if(princ == NULL)
204 return EINVAL;
205 if (handle->api_version == KADM5_API_VERSION_1) {
206 memcpy(&arg.rec, princ, sizeof(kadm5_principal_ent_rec_v1));
207 } else {
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);
226 } else
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);
234 if(r == NULL)
235 eret();
236 return r->code;
239 kadm5_ret_t
240 kadm5_get_principal(void *server_handle,
241 krb5_principal princ, kadm5_principal_ent_t ent,
242 long mask)
244 gprinc_arg arg;
245 gprinc_ret *r;
246 kadm5_server_handle_t handle = server_handle;
248 CHECK_HANDLE(server_handle);
250 if(princ == NULL)
251 return EINVAL;
252 arg.princ = princ;
253 if (handle->api_version == KADM5_API_VERSION_1)
254 arg.mask = KADM5_PRINCIPAL_NORMAL_MASK;
255 else
256 arg.mask = mask;
257 arg.api_version = handle->api_version;
258 r = get_principal_2(&arg, handle->clnt);
259 if(r == NULL)
260 eret();
261 if (handle->api_version == KADM5_API_VERSION_1) {
262 kadm5_principal_ent_t_v1 *entp;
264 entp = (kadm5_principal_ent_t_v1 *) ent;
265 if (r->code == 0) {
266 if (!(*entp = (kadm5_principal_ent_t_v1)
267 malloc(sizeof(kadm5_principal_ent_rec_v1))))
268 return ENOMEM;
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));
273 } else {
274 *entp = NULL;
276 } else {
277 if (r->code == 0)
278 memcpy(ent, &r->rec, sizeof(r->rec));
281 return r->code;
284 kadm5_ret_t
285 kadm5_get_principals(void *server_handle,
286 char *exp, char ***princs, int *count)
288 gprincs_arg arg;
289 gprincs_ret *r;
290 kadm5_server_handle_t handle = server_handle;
292 CHECK_HANDLE(server_handle);
294 if(princs == NULL || count == NULL)
295 return EINVAL;
296 arg.exp = exp;
297 arg.api_version = handle->api_version;
298 r = get_princs_2(&arg, handle->clnt);
299 if(r == NULL)
300 eret();
301 if(r->code == 0) {
302 *count = r->count;
303 *princs = r->princs;
304 } else {
305 *count = 0;
306 *princs = NULL;
309 return r->code;
312 kadm5_ret_t
313 kadm5_rename_principal(void *server_handle,
314 krb5_principal source, krb5_principal dest)
316 rprinc_arg arg;
317 generic_ret *r;
318 kadm5_server_handle_t handle = server_handle;
320 CHECK_HANDLE(server_handle);
322 arg.src = source;
323 arg.dest = dest;
324 arg.api_version = handle->api_version;
325 if (source == NULL || dest == NULL)
326 return EINVAL;
327 r = rename_principal_2(&arg, handle->clnt);
328 if(r == NULL)
329 eret();
330 return r->code;
333 kadm5_ret_t
334 kadm5_chpass_principal(void *server_handle,
335 krb5_principal princ, char *password)
337 chpass_arg arg;
338 generic_ret *r;
339 kadm5_server_handle_t handle = server_handle;
341 CHECK_HANDLE(server_handle);
343 arg.princ = princ;
344 arg.pass = password;
345 arg.api_version = handle->api_version;
347 if(princ == NULL)
348 return EINVAL;
349 r = chpass_principal_2(&arg, handle->clnt);
350 if(r == NULL)
351 eret();
352 return r->code;
355 kadm5_ret_t
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,
359 char *password)
361 chpass3_arg arg;
362 generic_ret *r;
363 kadm5_server_handle_t handle = server_handle;
365 CHECK_HANDLE(server_handle);
367 arg.princ = princ;
368 arg.pass = password;
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;
374 if(princ == NULL)
375 return EINVAL;
376 r = chpass_principal3_2(&arg, handle->clnt);
377 if(r == NULL)
378 eret();
379 return r->code;
382 kadm5_ret_t
383 kadm5_setv4key_principal(void *server_handle,
384 krb5_principal princ,
385 krb5_keyblock *keyblock)
387 setv4key_arg arg;
388 generic_ret *r;
389 kadm5_server_handle_t handle = server_handle;
391 CHECK_HANDLE(server_handle);
393 arg.princ = princ;
394 arg.keyblock = keyblock;
395 arg.api_version = handle->api_version;
397 if(princ == NULL || keyblock == NULL)
398 return EINVAL;
399 r = setv4key_principal_2(&arg, handle->clnt);
400 if(r == NULL)
401 eret();
402 return r->code;
405 kadm5_ret_t
406 kadm5_setkey_principal(void *server_handle,
407 krb5_principal princ,
408 krb5_keyblock *keyblocks,
409 int n_keys)
411 setkey_arg arg;
412 generic_ret *r;
413 kadm5_server_handle_t handle = server_handle;
415 CHECK_HANDLE(server_handle);
417 arg.princ = princ;
418 arg.keyblocks = keyblocks;
419 arg.n_keys = n_keys;
420 arg.api_version = handle->api_version;
422 if(princ == NULL || keyblocks == NULL)
423 return EINVAL;
424 r = setkey_principal_2(&arg, handle->clnt);
425 if(r == NULL)
426 eret();
427 return r->code;
430 kadm5_ret_t
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,
436 int n_keys)
438 setkey3_arg arg;
439 generic_ret *r;
440 kadm5_server_handle_t handle = server_handle;
442 CHECK_HANDLE(server_handle);
444 arg.princ = princ;
445 arg.keyblocks = keyblocks;
446 arg.n_keys = n_keys;
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)
453 return EINVAL;
454 r = setkey_principal3_2(&arg, handle->clnt);
455 if(r == NULL)
456 eret();
457 return r->code;
461 * Solaris Kerberos:
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.
475 kadm5_ret_t
476 kadm5_randkey_principal_old(void *server_handle,
477 krb5_principal princ,
478 krb5_keyblock **key,
479 int *n_keys)
481 chrand_arg arg;
482 chrand_ret *r;
483 kadm5_server_handle_t handle = server_handle;
484 int i, ret;
486 /* For safety */
487 if (n_keys)
488 *n_keys = 0;
489 if (key)
490 *key = NULL;
491 CHECK_HANDLE(server_handle);
493 arg.princ = princ;
494 arg.api_version = handle->api_version;
496 if(princ == NULL)
497 return EINVAL;
498 r = chrand_principal_2(&arg, handle->clnt);
499 if (r == NULL)
500 return KADM5_RPC_ERROR;
501 if (handle->api_version == KADM5_API_VERSION_1) {
502 if (key)
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));
507 if (*key == NULL)
508 return ENOMEM;
509 for (i = 0; i < r->n_keys; i++) {
510 ret = krb5_copy_keyblock_contents(
511 handle->context,
512 &r->keys[i],
513 &(*key)[i]);
514 if (ret) {
515 free(*key);
516 *key = NULL;
517 return ENOMEM;
520 if (n_keys)
521 *n_keys = r->n_keys;
523 return (r->code);
526 kadm5_ret_t
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)
533 chrand3_arg arg;
534 chrand_ret *r;
535 kadm5_server_handle_t handle = server_handle;
536 int i, ret;
538 /* Solaris Kerberos - For safety */
539 if (n_keys)
540 *n_keys = 0;
541 if (key)
542 *key = NULL;
544 CHECK_HANDLE(server_handle);
546 arg.princ = princ;
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;
552 if(princ == NULL)
553 return EINVAL;
554 r = chrand_principal3_2(&arg, handle->clnt);
555 if(r == NULL)
556 eret();
557 if (handle->api_version == KADM5_API_VERSION_1) {
558 if (key)
559 krb5_copy_keyblock(handle->context, &r->key, key);
560 } else {
561 if (n_keys)
562 *n_keys = r->n_keys;
563 if (key) {
564 if(r->n_keys) {
565 *key = (krb5_keyblock *)
566 malloc(r->n_keys*sizeof(krb5_keyblock));
567 if (*key == NULL)
568 return ENOMEM;
569 for (i = 0; i < r->n_keys; i++) {
570 ret = krb5_copy_keyblock_contents(handle->context,
571 &r->keys[i],
572 &(*key)[i]);
573 if (ret) {
574 free(*key);
575 return ENOMEM;
578 } else *key = NULL;
582 return r->code;
585 kadm5_ret_t
586 kadm5_randkey_principal(void *server_handle,
587 krb5_principal princ,
588 krb5_keyblock **key, int *n_keys)
590 /* Solaris Kerberos */
591 kadm5_ret_t kret;
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,
607 key, n_keys);
609 return (kret);
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)
619 return EINVAL;