xref: /onnv-gate/usr/src/lib/krb5/kadm5/clnt/client_principal.c (revision 7934:6aeeafc994de)
10Sstevel@tonic-gate /*
2*7934SMark.Phalan@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
30Sstevel@tonic-gate  * Use is subject to license terms.
40Sstevel@tonic-gate  */
50Sstevel@tonic-gate 
60Sstevel@tonic-gate 
70Sstevel@tonic-gate /*
80Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
90Sstevel@tonic-gate  *
100Sstevel@tonic-gate  *	Openvision retains the copyright to derivative works of
110Sstevel@tonic-gate  *	this source code.  Do *NOT* create a derivative of this
120Sstevel@tonic-gate  *	source code before consulting with your legal department.
130Sstevel@tonic-gate  *	Do *NOT* integrate *ANY* of this source code into another
140Sstevel@tonic-gate  *	product before consulting with your legal department.
150Sstevel@tonic-gate  *
160Sstevel@tonic-gate  *	For further information, read the top-level Openvision
170Sstevel@tonic-gate  *	copyright which is contained in the top-level MIT Kerberos
180Sstevel@tonic-gate  *	copyright.
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
210Sstevel@tonic-gate  *
220Sstevel@tonic-gate  */
230Sstevel@tonic-gate 
240Sstevel@tonic-gate 
250Sstevel@tonic-gate /*
260Sstevel@tonic-gate  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
270Sstevel@tonic-gate  *
28*7934SMark.Phalan@Sun.COM  * $Header$
290Sstevel@tonic-gate  */
300Sstevel@tonic-gate 
310Sstevel@tonic-gate #if !defined(lint) && !defined(__CODECENTER__)
32*7934SMark.Phalan@Sun.COM static char *rcsid = "$Header$";
330Sstevel@tonic-gate #endif
340Sstevel@tonic-gate 
350Sstevel@tonic-gate #include    <rpc/rpc.h>  /* SUNWresync121 XXX */
360Sstevel@tonic-gate #include    <kadm5/admin.h>
370Sstevel@tonic-gate #include    <kadm5/kadm_rpc.h>
382881Smp153739 #ifdef HAVE_MEMORY_H
390Sstevel@tonic-gate #include    <memory.h>
402881Smp153739 #endif
41*7934SMark.Phalan@Sun.COM #include    <errno.h>
420Sstevel@tonic-gate #include    "client_internal.h"
430Sstevel@tonic-gate 
442881Smp153739 #ifdef DEBUG /* SUNWresync14 XXX */
454248Swillf #define eret() {clnt_perror(handle->clnt, "null ret"); return KADM5_RPC_ERROR;}
462881Smp153739 #else
474248Swillf #define eret() return KADM5_RPC_ERROR
482881Smp153739 #endif
492881Smp153739 
500Sstevel@tonic-gate kadm5_ret_t
kadm5_create_principal(void * server_handle,kadm5_principal_ent_t princ,long mask,char * pw)510Sstevel@tonic-gate kadm5_create_principal(void *server_handle,
520Sstevel@tonic-gate 			    kadm5_principal_ent_t princ, long mask,
530Sstevel@tonic-gate 			    char *pw)
540Sstevel@tonic-gate {
550Sstevel@tonic-gate     generic_ret		*r;
560Sstevel@tonic-gate     cprinc_arg		arg;
570Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
580Sstevel@tonic-gate 
590Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
600Sstevel@tonic-gate 
610Sstevel@tonic-gate     memset(&arg, 0, sizeof(arg));
620Sstevel@tonic-gate     arg.mask = mask;
630Sstevel@tonic-gate     arg.passwd = pw;
640Sstevel@tonic-gate     arg.api_version = handle->api_version;
650Sstevel@tonic-gate 
660Sstevel@tonic-gate     if(princ == NULL)
670Sstevel@tonic-gate 	return EINVAL;
680Sstevel@tonic-gate 
690Sstevel@tonic-gate     if (handle->api_version == KADM5_API_VERSION_1) {
700Sstevel@tonic-gate        memcpy(&arg.rec, princ, sizeof(kadm5_principal_ent_rec_v1));
710Sstevel@tonic-gate     } else {
720Sstevel@tonic-gate        memcpy(&arg.rec, princ, sizeof(kadm5_principal_ent_rec));
730Sstevel@tonic-gate     }
740Sstevel@tonic-gate     if (handle->api_version == KADM5_API_VERSION_1) {
750Sstevel@tonic-gate 	 /*
760Sstevel@tonic-gate 	  * hack hack cough cough.
770Sstevel@tonic-gate 	  * krb5_unparse name dumps core if we pass it in garbage
780Sstevel@tonic-gate 	  * or null. So, since the client is not allowed to set mod_name
790Sstevel@tonic-gate 	  * anyway, we just fill it in with a dummy principal. The server of
800Sstevel@tonic-gate 	  * course ignores this.
810Sstevel@tonic-gate 	  */
820Sstevel@tonic-gate 	/* krb5_parse_name(handle->context, "bogus/bogus", &arg.rec.mod_name); */
830Sstevel@tonic-gate 	 arg.rec.mod_name = NULL;
840Sstevel@tonic-gate     } else
850Sstevel@tonic-gate 	 arg.rec.mod_name = NULL;
860Sstevel@tonic-gate 
870Sstevel@tonic-gate     if(!(mask & KADM5_POLICY))
880Sstevel@tonic-gate 	arg.rec.policy = NULL;
890Sstevel@tonic-gate     if (! (mask & KADM5_KEY_DATA)) {
900Sstevel@tonic-gate 	 arg.rec.n_key_data = 0;
910Sstevel@tonic-gate 	 arg.rec.key_data = NULL;
920Sstevel@tonic-gate     }
930Sstevel@tonic-gate     if (! (mask & KADM5_TL_DATA)) {
940Sstevel@tonic-gate 	 arg.rec.n_tl_data = 0;
950Sstevel@tonic-gate 	 arg.rec.tl_data = NULL;
960Sstevel@tonic-gate     }
970Sstevel@tonic-gate 
98*7934SMark.Phalan@Sun.COM     r = create_principal_2(&arg, handle->clnt);
990Sstevel@tonic-gate 
1000Sstevel@tonic-gate     if (handle->api_version == KADM5_API_VERSION_1)
1010Sstevel@tonic-gate 	 krb5_free_principal(handle->context, arg.rec.mod_name);
1020Sstevel@tonic-gate 
1030Sstevel@tonic-gate     if(r == NULL)
1042881Smp153739 	eret();
1050Sstevel@tonic-gate     return r->code;
1060Sstevel@tonic-gate }
1070Sstevel@tonic-gate 
1080Sstevel@tonic-gate kadm5_ret_t
kadm5_create_principal_3(void * server_handle,kadm5_principal_ent_t princ,long mask,int n_ks_tuple,krb5_key_salt_tuple * ks_tuple,char * pw)1090Sstevel@tonic-gate kadm5_create_principal_3(void *server_handle,
1100Sstevel@tonic-gate 			 kadm5_principal_ent_t princ, long mask,
1110Sstevel@tonic-gate 			 int n_ks_tuple,
1120Sstevel@tonic-gate 			 krb5_key_salt_tuple *ks_tuple,
1130Sstevel@tonic-gate 			 char *pw)
1140Sstevel@tonic-gate {
1150Sstevel@tonic-gate     generic_ret		*r;
1160Sstevel@tonic-gate     cprinc3_arg		arg;
1170Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
1180Sstevel@tonic-gate 
1190Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate     memset(&arg, 0, sizeof(arg));
1220Sstevel@tonic-gate     arg.mask = mask;
1230Sstevel@tonic-gate     arg.passwd = pw;
1240Sstevel@tonic-gate     arg.api_version = handle->api_version;
1250Sstevel@tonic-gate     arg.n_ks_tuple = n_ks_tuple;
1260Sstevel@tonic-gate     arg.ks_tuple = ks_tuple;
1270Sstevel@tonic-gate 
1280Sstevel@tonic-gate     if(princ == NULL)
1290Sstevel@tonic-gate 	return EINVAL;
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate     if (handle->api_version == KADM5_API_VERSION_1) {
1320Sstevel@tonic-gate        memcpy(&arg.rec, princ, sizeof(kadm5_principal_ent_rec_v1));
1330Sstevel@tonic-gate     } else {
1340Sstevel@tonic-gate        memcpy(&arg.rec, princ, sizeof(kadm5_principal_ent_rec));
1350Sstevel@tonic-gate     }
1360Sstevel@tonic-gate     if (handle->api_version == KADM5_API_VERSION_1) {
1370Sstevel@tonic-gate 	 /*
1380Sstevel@tonic-gate 	  * hack hack cough cough.
1390Sstevel@tonic-gate 	  * krb5_unparse name dumps core if we pass it in garbage
1400Sstevel@tonic-gate 	  * or null. So, since the client is not allowed to set mod_name
1410Sstevel@tonic-gate 	  * anyway, we just fill it in with a dummy principal. The server of
1420Sstevel@tonic-gate 	  * course ignores this.
1430Sstevel@tonic-gate 	  */
1440Sstevel@tonic-gate 	 krb5_parse_name(handle->context, "bogus/bogus", &arg.rec.mod_name);
1450Sstevel@tonic-gate     } else
1460Sstevel@tonic-gate 	 arg.rec.mod_name = NULL;
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate     if(!(mask & KADM5_POLICY))
1490Sstevel@tonic-gate 	arg.rec.policy = NULL;
1500Sstevel@tonic-gate     if (! (mask & KADM5_KEY_DATA)) {
1510Sstevel@tonic-gate 	 arg.rec.n_key_data = 0;
1520Sstevel@tonic-gate 	 arg.rec.key_data = NULL;
1530Sstevel@tonic-gate     }
1540Sstevel@tonic-gate     if (! (mask & KADM5_TL_DATA)) {
1550Sstevel@tonic-gate 	 arg.rec.n_tl_data = 0;
1560Sstevel@tonic-gate 	 arg.rec.tl_data = NULL;
1570Sstevel@tonic-gate     }
1580Sstevel@tonic-gate 
159*7934SMark.Phalan@Sun.COM     r = create_principal3_2(&arg, handle->clnt);
1600Sstevel@tonic-gate 
1610Sstevel@tonic-gate     if (handle->api_version == KADM5_API_VERSION_1)
1620Sstevel@tonic-gate 	 krb5_free_principal(handle->context, arg.rec.mod_name);
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate     if(r == NULL)
1652881Smp153739 	eret();
1660Sstevel@tonic-gate     return r->code;
1670Sstevel@tonic-gate }
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate kadm5_ret_t
kadm5_delete_principal(void * server_handle,krb5_principal principal)1700Sstevel@tonic-gate kadm5_delete_principal(void *server_handle, krb5_principal principal)
1710Sstevel@tonic-gate {
1720Sstevel@tonic-gate     dprinc_arg		arg;
1730Sstevel@tonic-gate     generic_ret		*r;
1740Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
1750Sstevel@tonic-gate 
1760Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
1770Sstevel@tonic-gate 
1780Sstevel@tonic-gate     if(principal == NULL)
1790Sstevel@tonic-gate 	return EINVAL;
1800Sstevel@tonic-gate     arg.princ = principal;
1810Sstevel@tonic-gate     arg.api_version = handle->api_version;
182*7934SMark.Phalan@Sun.COM     r = delete_principal_2(&arg, handle->clnt);
1830Sstevel@tonic-gate     if(r == NULL)
1842881Smp153739 	eret();
1850Sstevel@tonic-gate     return r->code;
1860Sstevel@tonic-gate }
1870Sstevel@tonic-gate 
1880Sstevel@tonic-gate kadm5_ret_t
kadm5_modify_principal(void * server_handle,kadm5_principal_ent_t princ,long mask)1890Sstevel@tonic-gate kadm5_modify_principal(void *server_handle,
1900Sstevel@tonic-gate 			    kadm5_principal_ent_t princ, long mask)
1910Sstevel@tonic-gate {
1920Sstevel@tonic-gate     mprinc_arg		arg;
1930Sstevel@tonic-gate     generic_ret		*r;
1940Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
1950Sstevel@tonic-gate 
1960Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
1970Sstevel@tonic-gate 
1980Sstevel@tonic-gate     memset(&arg, 0, sizeof(arg));
1990Sstevel@tonic-gate     arg.mask = mask;
2000Sstevel@tonic-gate     arg.api_version = handle->api_version;
2010Sstevel@tonic-gate     /*
2020Sstevel@tonic-gate      * cough cough gag gag
2030Sstevel@tonic-gate      * see comment in create_principal.
2040Sstevel@tonic-gate      */
2050Sstevel@tonic-gate     if(princ == NULL)
2060Sstevel@tonic-gate 	return EINVAL;
2070Sstevel@tonic-gate     if (handle->api_version == KADM5_API_VERSION_1) {
2080Sstevel@tonic-gate         memcpy(&arg.rec, princ, sizeof(kadm5_principal_ent_rec_v1));
2090Sstevel@tonic-gate     } else {
2100Sstevel@tonic-gate         memcpy(&arg.rec, princ, sizeof(kadm5_principal_ent_rec));
2110Sstevel@tonic-gate     }
2120Sstevel@tonic-gate     if(!(mask & KADM5_POLICY))
2130Sstevel@tonic-gate 	arg.rec.policy = NULL;
2140Sstevel@tonic-gate     if (! (mask & KADM5_KEY_DATA)) {
2150Sstevel@tonic-gate 	 arg.rec.n_key_data = 0;
2160Sstevel@tonic-gate 	 arg.rec.key_data = NULL;
2170Sstevel@tonic-gate     }
2180Sstevel@tonic-gate     if (! (mask & KADM5_TL_DATA)) {
2190Sstevel@tonic-gate 	 arg.rec.n_tl_data = 0;
2200Sstevel@tonic-gate 	 arg.rec.tl_data = NULL;
2210Sstevel@tonic-gate     }
2220Sstevel@tonic-gate 
2230Sstevel@tonic-gate     if (handle->api_version == KADM5_API_VERSION_1) {
2240Sstevel@tonic-gate 	 /*
2250Sstevel@tonic-gate 	  * See comment in create_principal
2260Sstevel@tonic-gate 	  */
2270Sstevel@tonic-gate 	 krb5_parse_name(handle->context, "bogus/bogus", &arg.rec.mod_name);
2280Sstevel@tonic-gate     } else
2290Sstevel@tonic-gate 	 arg.rec.mod_name = NULL;
2300Sstevel@tonic-gate 
231*7934SMark.Phalan@Sun.COM     r = modify_principal_2(&arg, handle->clnt);
2320Sstevel@tonic-gate 
2330Sstevel@tonic-gate     if (handle->api_version == KADM5_API_VERSION_1)
2340Sstevel@tonic-gate 	 krb5_free_principal(handle->context, arg.rec.mod_name);
2350Sstevel@tonic-gate 
2360Sstevel@tonic-gate     if(r == NULL)
2372881Smp153739 	eret();
2380Sstevel@tonic-gate     return r->code;
2390Sstevel@tonic-gate }
2400Sstevel@tonic-gate 
2410Sstevel@tonic-gate kadm5_ret_t
kadm5_get_principal(void * server_handle,krb5_principal princ,kadm5_principal_ent_t ent,long mask)2420Sstevel@tonic-gate kadm5_get_principal(void *server_handle,
2430Sstevel@tonic-gate 		    krb5_principal princ, kadm5_principal_ent_t ent,
2440Sstevel@tonic-gate 		    long mask)
2450Sstevel@tonic-gate {
2460Sstevel@tonic-gate     gprinc_arg	arg;
2470Sstevel@tonic-gate     gprinc_ret	*r;
2480Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
2490Sstevel@tonic-gate 
2500Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
2510Sstevel@tonic-gate 
2520Sstevel@tonic-gate     if(princ == NULL)
2530Sstevel@tonic-gate 	return EINVAL;
2540Sstevel@tonic-gate     arg.princ = princ;
2550Sstevel@tonic-gate     if (handle->api_version == KADM5_API_VERSION_1)
2560Sstevel@tonic-gate        arg.mask = KADM5_PRINCIPAL_NORMAL_MASK;
2570Sstevel@tonic-gate     else
2580Sstevel@tonic-gate        arg.mask = mask;
2590Sstevel@tonic-gate     arg.api_version = handle->api_version;
260*7934SMark.Phalan@Sun.COM     r = get_principal_2(&arg, handle->clnt);
2610Sstevel@tonic-gate     if(r == NULL)
2622881Smp153739 	eret();
2630Sstevel@tonic-gate     if (handle->api_version == KADM5_API_VERSION_1) {
2640Sstevel@tonic-gate 	 kadm5_principal_ent_t_v1 *entp;
2650Sstevel@tonic-gate 
2660Sstevel@tonic-gate 	 entp = (kadm5_principal_ent_t_v1 *) ent;
2670Sstevel@tonic-gate 	 if (r->code == 0) {
2680Sstevel@tonic-gate 	      if (!(*entp = (kadm5_principal_ent_t_v1)
2690Sstevel@tonic-gate 		    malloc(sizeof(kadm5_principal_ent_rec_v1))))
2700Sstevel@tonic-gate 		   return ENOMEM;
2710Sstevel@tonic-gate 	      /* this memcpy works because the v1 structure is an initial
2720Sstevel@tonic-gate 		 subset of the v2 struct.  C guarantees that this will
2730Sstevel@tonic-gate 		 result in the same layout in memory */
2740Sstevel@tonic-gate 	      memcpy(*entp, &r->rec, sizeof(**entp));
2750Sstevel@tonic-gate 	 } else {
2760Sstevel@tonic-gate 	    *entp = NULL;
2770Sstevel@tonic-gate 	 }
2780Sstevel@tonic-gate     } else {
2790Sstevel@tonic-gate 	 if (r->code == 0)
2800Sstevel@tonic-gate 	      memcpy(ent, &r->rec, sizeof(r->rec));
2810Sstevel@tonic-gate     }
2820Sstevel@tonic-gate 
2830Sstevel@tonic-gate     return r->code;
2840Sstevel@tonic-gate }
2850Sstevel@tonic-gate 
2860Sstevel@tonic-gate kadm5_ret_t
kadm5_get_principals(void * server_handle,char * exp,char *** princs,int * count)2870Sstevel@tonic-gate kadm5_get_principals(void *server_handle,
2880Sstevel@tonic-gate 			  char *exp, char ***princs, int *count)
2890Sstevel@tonic-gate {
2900Sstevel@tonic-gate     gprincs_arg	arg;
2910Sstevel@tonic-gate     gprincs_ret	*r;
2920Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
2930Sstevel@tonic-gate 
2940Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
2950Sstevel@tonic-gate 
2960Sstevel@tonic-gate     if(princs == NULL || count == NULL)
2970Sstevel@tonic-gate 	return EINVAL;
2980Sstevel@tonic-gate     arg.exp = exp;
2990Sstevel@tonic-gate     arg.api_version = handle->api_version;
300*7934SMark.Phalan@Sun.COM     r = get_princs_2(&arg, handle->clnt);
3010Sstevel@tonic-gate     if(r == NULL)
3022881Smp153739 	eret();
3030Sstevel@tonic-gate     if(r->code == 0) {
3040Sstevel@tonic-gate 	 *count = r->count;
3050Sstevel@tonic-gate 	 *princs = r->princs;
3060Sstevel@tonic-gate     } else {
3070Sstevel@tonic-gate 	 *count = 0;
3080Sstevel@tonic-gate 	 *princs = NULL;
3090Sstevel@tonic-gate     }
3100Sstevel@tonic-gate 
3110Sstevel@tonic-gate     return r->code;
3120Sstevel@tonic-gate }
3130Sstevel@tonic-gate 
3140Sstevel@tonic-gate kadm5_ret_t
kadm5_rename_principal(void * server_handle,krb5_principal source,krb5_principal dest)3150Sstevel@tonic-gate kadm5_rename_principal(void *server_handle,
3160Sstevel@tonic-gate 			    krb5_principal source, krb5_principal dest)
3170Sstevel@tonic-gate {
3180Sstevel@tonic-gate     rprinc_arg		arg;
3190Sstevel@tonic-gate     generic_ret		*r;
3200Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
3210Sstevel@tonic-gate 
3220Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
3230Sstevel@tonic-gate 
3240Sstevel@tonic-gate     arg.src = source;
3250Sstevel@tonic-gate     arg.dest = dest;
3260Sstevel@tonic-gate     arg.api_version = handle->api_version;
3270Sstevel@tonic-gate     if (source == NULL || dest == NULL)
3280Sstevel@tonic-gate 	return EINVAL;
329*7934SMark.Phalan@Sun.COM     r = rename_principal_2(&arg, handle->clnt);
3300Sstevel@tonic-gate     if(r == NULL)
3312881Smp153739 	eret();
3320Sstevel@tonic-gate     return r->code;
3330Sstevel@tonic-gate }
3340Sstevel@tonic-gate 
3350Sstevel@tonic-gate kadm5_ret_t
kadm5_chpass_principal(void * server_handle,krb5_principal princ,char * password)3360Sstevel@tonic-gate kadm5_chpass_principal(void *server_handle,
3370Sstevel@tonic-gate 			    krb5_principal princ, char *password)
3380Sstevel@tonic-gate {
3390Sstevel@tonic-gate     chpass_arg		arg;
3400Sstevel@tonic-gate     generic_ret		*r;
3410Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
3420Sstevel@tonic-gate 
3430Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
3440Sstevel@tonic-gate 
3450Sstevel@tonic-gate     arg.princ = princ;
3460Sstevel@tonic-gate     arg.pass = password;
3470Sstevel@tonic-gate     arg.api_version = handle->api_version;
3480Sstevel@tonic-gate 
3490Sstevel@tonic-gate     if(princ == NULL)
3500Sstevel@tonic-gate 	return EINVAL;
351*7934SMark.Phalan@Sun.COM     r = chpass_principal_2(&arg, handle->clnt);
3520Sstevel@tonic-gate     if(r == NULL)
3532881Smp153739 	eret();
3540Sstevel@tonic-gate     return r->code;
3550Sstevel@tonic-gate }
3560Sstevel@tonic-gate 
3570Sstevel@tonic-gate kadm5_ret_t
kadm5_chpass_principal_3(void * server_handle,krb5_principal princ,krb5_boolean keepold,int n_ks_tuple,krb5_key_salt_tuple * ks_tuple,char * password)3580Sstevel@tonic-gate kadm5_chpass_principal_3(void *server_handle,
3590Sstevel@tonic-gate 			 krb5_principal princ, krb5_boolean keepold,
3600Sstevel@tonic-gate 			 int n_ks_tuple, krb5_key_salt_tuple *ks_tuple,
3610Sstevel@tonic-gate 			 char *password)
3620Sstevel@tonic-gate {
3630Sstevel@tonic-gate     chpass3_arg		arg;
3640Sstevel@tonic-gate     generic_ret		*r;
3650Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
3660Sstevel@tonic-gate 
3670Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
3680Sstevel@tonic-gate 
3690Sstevel@tonic-gate     arg.princ = princ;
3700Sstevel@tonic-gate     arg.pass = password;
3710Sstevel@tonic-gate     arg.api_version = handle->api_version;
3720Sstevel@tonic-gate     arg.keepold = keepold;
3730Sstevel@tonic-gate     arg.n_ks_tuple = n_ks_tuple;
3740Sstevel@tonic-gate     arg.ks_tuple = ks_tuple;
3750Sstevel@tonic-gate 
3760Sstevel@tonic-gate     if(princ == NULL)
3770Sstevel@tonic-gate 	return EINVAL;
378*7934SMark.Phalan@Sun.COM     r = chpass_principal3_2(&arg, handle->clnt);
3790Sstevel@tonic-gate     if(r == NULL)
3802881Smp153739 	eret();
3810Sstevel@tonic-gate     return r->code;
3820Sstevel@tonic-gate }
3830Sstevel@tonic-gate 
3840Sstevel@tonic-gate kadm5_ret_t
kadm5_setv4key_principal(void * server_handle,krb5_principal princ,krb5_keyblock * keyblock)3850Sstevel@tonic-gate kadm5_setv4key_principal(void *server_handle,
3860Sstevel@tonic-gate 			 krb5_principal princ,
3870Sstevel@tonic-gate 			 krb5_keyblock *keyblock)
3880Sstevel@tonic-gate {
3890Sstevel@tonic-gate     setv4key_arg	arg;
3900Sstevel@tonic-gate     generic_ret		*r;
3910Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
3920Sstevel@tonic-gate 
3930Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
3940Sstevel@tonic-gate 
3950Sstevel@tonic-gate     arg.princ = princ;
3960Sstevel@tonic-gate     arg.keyblock = keyblock;
3970Sstevel@tonic-gate     arg.api_version = handle->api_version;
3980Sstevel@tonic-gate 
3990Sstevel@tonic-gate     if(princ == NULL || keyblock == NULL)
4000Sstevel@tonic-gate 	return EINVAL;
401*7934SMark.Phalan@Sun.COM     r = setv4key_principal_2(&arg, handle->clnt);
4020Sstevel@tonic-gate     if(r == NULL)
4032881Smp153739 	eret();
4040Sstevel@tonic-gate     return r->code;
4050Sstevel@tonic-gate }
4060Sstevel@tonic-gate 
4070Sstevel@tonic-gate kadm5_ret_t
kadm5_setkey_principal(void * server_handle,krb5_principal princ,krb5_keyblock * keyblocks,int n_keys)4080Sstevel@tonic-gate kadm5_setkey_principal(void *server_handle,
4090Sstevel@tonic-gate 		       krb5_principal princ,
4100Sstevel@tonic-gate 		       krb5_keyblock *keyblocks,
4110Sstevel@tonic-gate 		       int n_keys)
4120Sstevel@tonic-gate {
4130Sstevel@tonic-gate     setkey_arg		arg;
4140Sstevel@tonic-gate     generic_ret		*r;
4150Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
4160Sstevel@tonic-gate 
4170Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
4180Sstevel@tonic-gate 
4190Sstevel@tonic-gate     arg.princ = princ;
4200Sstevel@tonic-gate     arg.keyblocks = keyblocks;
4210Sstevel@tonic-gate     arg.n_keys = n_keys;
4220Sstevel@tonic-gate     arg.api_version = handle->api_version;
4230Sstevel@tonic-gate 
4240Sstevel@tonic-gate     if(princ == NULL || keyblocks == NULL)
4250Sstevel@tonic-gate 	return EINVAL;
426*7934SMark.Phalan@Sun.COM     r = setkey_principal_2(&arg, handle->clnt);
4270Sstevel@tonic-gate     if(r == NULL)
4282881Smp153739 	eret();
4290Sstevel@tonic-gate     return r->code;
4300Sstevel@tonic-gate }
4310Sstevel@tonic-gate 
4320Sstevel@tonic-gate kadm5_ret_t
kadm5_setkey_principal_3(void * server_handle,krb5_principal princ,krb5_boolean keepold,int n_ks_tuple,krb5_key_salt_tuple * ks_tuple,krb5_keyblock * keyblocks,int n_keys)4330Sstevel@tonic-gate kadm5_setkey_principal_3(void *server_handle,
4340Sstevel@tonic-gate 			 krb5_principal princ,
4350Sstevel@tonic-gate 			 krb5_boolean keepold, int n_ks_tuple,
4360Sstevel@tonic-gate 			 krb5_key_salt_tuple *ks_tuple,
4370Sstevel@tonic-gate 			 krb5_keyblock *keyblocks,
4380Sstevel@tonic-gate 			 int n_keys)
4390Sstevel@tonic-gate {
4400Sstevel@tonic-gate     setkey3_arg		arg;
4410Sstevel@tonic-gate     generic_ret		*r;
4420Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
4430Sstevel@tonic-gate 
4440Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
4450Sstevel@tonic-gate 
4460Sstevel@tonic-gate     arg.princ = princ;
4470Sstevel@tonic-gate     arg.keyblocks = keyblocks;
4480Sstevel@tonic-gate     arg.n_keys = n_keys;
4490Sstevel@tonic-gate     arg.api_version = handle->api_version;
4500Sstevel@tonic-gate     arg.keepold = keepold;
4510Sstevel@tonic-gate     arg.n_ks_tuple = n_ks_tuple;
4520Sstevel@tonic-gate     arg.ks_tuple = ks_tuple;
4530Sstevel@tonic-gate 
4540Sstevel@tonic-gate     if(princ == NULL || keyblocks == NULL)
4550Sstevel@tonic-gate 	return EINVAL;
456*7934SMark.Phalan@Sun.COM     r = setkey_principal3_2(&arg, handle->clnt);
4570Sstevel@tonic-gate     if(r == NULL)
4582881Smp153739 	eret();
4590Sstevel@tonic-gate     return r->code;
4600Sstevel@tonic-gate }
4610Sstevel@tonic-gate 
4620Sstevel@tonic-gate /*
4630Sstevel@tonic-gate  * Solaris Kerberos:
4640Sstevel@tonic-gate  * This routine implements just the "old" randkey_principal code.
4650Sstevel@tonic-gate  * The code in the kadmin client sometimes needs to call this
4660Sstevel@tonic-gate  * directly when the kadm5_randkey_principal_3 call fails.
4670Sstevel@tonic-gate  *
4680Sstevel@tonic-gate  * The kadmin client utility uses a specific set of key/salt tuples,
4690Sstevel@tonic-gate  * so the standard fallback in kadm5_randkey_principal (see below)
4700Sstevel@tonic-gate  * will not work because it would result in kadm5_randkey_principal_3
4710Sstevel@tonic-gate  * being called twice - once with the specific key/salts specified by
4720Sstevel@tonic-gate  * kadmin and once with the NULL set (used to indicate that the server
4730Sstevel@tonic-gate  * should use the full set of supported enctypes).  Making this
4740Sstevel@tonic-gate  * routine separate makes the code simpler and avoids making the
4750Sstevel@tonic-gate  * kadm5_randkey_principal_3 twice from kadmin.
4760Sstevel@tonic-gate  */
4770Sstevel@tonic-gate kadm5_ret_t
kadm5_randkey_principal_old(void * server_handle,krb5_principal princ,krb5_keyblock ** key,int * n_keys)4780Sstevel@tonic-gate kadm5_randkey_principal_old(void *server_handle,
4790Sstevel@tonic-gate 			krb5_principal princ,
4800Sstevel@tonic-gate 			krb5_keyblock **key,
4810Sstevel@tonic-gate 			int *n_keys)
4820Sstevel@tonic-gate {
4830Sstevel@tonic-gate 	chrand_arg		arg;
4840Sstevel@tonic-gate 	chrand_ret		*r;
4850Sstevel@tonic-gate 	kadm5_server_handle_t handle = server_handle;
4860Sstevel@tonic-gate 	int		i, ret;
4870Sstevel@tonic-gate 
4880Sstevel@tonic-gate 	/* For safety */
4890Sstevel@tonic-gate 	if (n_keys)
4900Sstevel@tonic-gate 		*n_keys = 0;
4910Sstevel@tonic-gate 	if (key)
4920Sstevel@tonic-gate 		*key = NULL;
4930Sstevel@tonic-gate 	CHECK_HANDLE(server_handle);
4940Sstevel@tonic-gate 
4950Sstevel@tonic-gate 	arg.princ = princ;
4960Sstevel@tonic-gate 	arg.api_version = handle->api_version;
4970Sstevel@tonic-gate 
4980Sstevel@tonic-gate 	if(princ == NULL)
4990Sstevel@tonic-gate 		return EINVAL;
500*7934SMark.Phalan@Sun.COM 	r = chrand_principal_2(&arg, handle->clnt);
5010Sstevel@tonic-gate 	if (r == NULL)
5020Sstevel@tonic-gate 		return KADM5_RPC_ERROR;
5030Sstevel@tonic-gate 	if (handle->api_version == KADM5_API_VERSION_1) {
5040Sstevel@tonic-gate 		if (key)
5050Sstevel@tonic-gate 			krb5_copy_keyblock(handle->context, &r->key, key);
5060Sstevel@tonic-gate 	} else if (key && (r->n_keys > 0)) {
5070Sstevel@tonic-gate 		*key = (krb5_keyblock *) malloc(
5080Sstevel@tonic-gate 			r->n_keys*sizeof(krb5_keyblock));
5090Sstevel@tonic-gate 		if (*key == NULL)
5100Sstevel@tonic-gate 			return ENOMEM;
5110Sstevel@tonic-gate 		for (i = 0; i < r->n_keys; i++) {
5120Sstevel@tonic-gate 			ret = krb5_copy_keyblock_contents(
5130Sstevel@tonic-gate 				handle->context,
5140Sstevel@tonic-gate 				&r->keys[i],
5150Sstevel@tonic-gate 				&(*key)[i]);
5160Sstevel@tonic-gate 			if (ret) {
5170Sstevel@tonic-gate 				free(*key);
5180Sstevel@tonic-gate 				*key = NULL;
5190Sstevel@tonic-gate 				return ENOMEM;
5200Sstevel@tonic-gate 			}
5210Sstevel@tonic-gate 		}
5220Sstevel@tonic-gate 		if (n_keys)
5230Sstevel@tonic-gate 			*n_keys = r->n_keys;
5240Sstevel@tonic-gate 	}
5250Sstevel@tonic-gate 	return (r->code);
5260Sstevel@tonic-gate }
5270Sstevel@tonic-gate 
5280Sstevel@tonic-gate kadm5_ret_t
kadm5_randkey_principal_3(void * server_handle,krb5_principal princ,krb5_boolean keepold,int n_ks_tuple,krb5_key_salt_tuple * ks_tuple,krb5_keyblock ** key,int * n_keys)5290Sstevel@tonic-gate kadm5_randkey_principal_3(void *server_handle,
5300Sstevel@tonic-gate 			  krb5_principal princ,
5310Sstevel@tonic-gate 			  krb5_boolean keepold, int n_ks_tuple,
5320Sstevel@tonic-gate 			  krb5_key_salt_tuple *ks_tuple,
5330Sstevel@tonic-gate 			  krb5_keyblock **key, int *n_keys)
5340Sstevel@tonic-gate {
5350Sstevel@tonic-gate     chrand3_arg		arg;
5360Sstevel@tonic-gate     chrand_ret		*r;
5370Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
5380Sstevel@tonic-gate     int			i, ret;
5390Sstevel@tonic-gate 
540*7934SMark.Phalan@Sun.COM     /* Solaris Kerberos - For safety */
5410Sstevel@tonic-gate     if (n_keys)
5420Sstevel@tonic-gate 	*n_keys = 0;
5430Sstevel@tonic-gate     if (key)
5440Sstevel@tonic-gate 	*key = NULL;
5450Sstevel@tonic-gate 
5460Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
5470Sstevel@tonic-gate 
5480Sstevel@tonic-gate     arg.princ = princ;
5490Sstevel@tonic-gate     arg.api_version = handle->api_version;
5500Sstevel@tonic-gate     arg.keepold = keepold;
5510Sstevel@tonic-gate     arg.n_ks_tuple = n_ks_tuple;
5520Sstevel@tonic-gate     arg.ks_tuple = ks_tuple;
5530Sstevel@tonic-gate 
5540Sstevel@tonic-gate     if(princ == NULL)
5550Sstevel@tonic-gate 	return EINVAL;
556*7934SMark.Phalan@Sun.COM     r = chrand_principal3_2(&arg, handle->clnt);
5570Sstevel@tonic-gate     if(r == NULL)
5582881Smp153739 	eret();
5590Sstevel@tonic-gate     if (handle->api_version == KADM5_API_VERSION_1) {
5600Sstevel@tonic-gate 	 if (key)
5610Sstevel@tonic-gate 	      krb5_copy_keyblock(handle->context, &r->key, key);
5622881Smp153739     } else {
5632881Smp153739 	 if (n_keys)
5642881Smp153739 	      *n_keys = r->n_keys;
5652881Smp153739 	 if (key) {
5662881Smp153739 	      if(r->n_keys) {
5672881Smp153739 		      *key = (krb5_keyblock *)
5682881Smp153739 			      malloc(r->n_keys*sizeof(krb5_keyblock));
5692881Smp153739 		      if (*key == NULL)
5702881Smp153739 			      return ENOMEM;
5712881Smp153739 		      for (i = 0; i < r->n_keys; i++) {
5722881Smp153739 			      ret = krb5_copy_keyblock_contents(handle->context,
5732881Smp153739 								&r->keys[i],
5742881Smp153739 								&(*key)[i]);
5752881Smp153739 			      if (ret) {
5762881Smp153739 				      free(*key);
5772881Smp153739 				      return ENOMEM;
5782881Smp153739 			      }
5792881Smp153739 		      }
5802881Smp153739 	      } else *key = NULL;
5812881Smp153739          }
5820Sstevel@tonic-gate     }
5830Sstevel@tonic-gate 
5840Sstevel@tonic-gate     return r->code;
5850Sstevel@tonic-gate }
5860Sstevel@tonic-gate 
5870Sstevel@tonic-gate kadm5_ret_t
kadm5_randkey_principal(void * server_handle,krb5_principal princ,krb5_keyblock ** key,int * n_keys)5880Sstevel@tonic-gate kadm5_randkey_principal(void *server_handle,
5890Sstevel@tonic-gate 			krb5_principal princ,
5900Sstevel@tonic-gate 			krb5_keyblock **key, int *n_keys)
5910Sstevel@tonic-gate {
592*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
5930Sstevel@tonic-gate 	kadm5_ret_t kret;
5940Sstevel@tonic-gate 
5950Sstevel@tonic-gate 	/*
5960Sstevel@tonic-gate 	 * Default to trying the newest API to insure that the full
5970Sstevel@tonic-gate 	 * set of enctypes is created.
5980Sstevel@tonic-gate 	 */
5990Sstevel@tonic-gate 	kret = kadm5_randkey_principal_3(server_handle, princ, FALSE,
6000Sstevel@tonic-gate 		0, NULL, key, n_keys);
6010Sstevel@tonic-gate 
6020Sstevel@tonic-gate 	/*
6030Sstevel@tonic-gate 	 * We will get an RPC error if the RPC call failed which
6040Sstevel@tonic-gate 	 * will normally indicate that the remote procedure did not
6050Sstevel@tonic-gate 	 * exist on the server, so try the older API.
6060Sstevel@tonic-gate 	 */
6070Sstevel@tonic-gate 	if (kret == KADM5_RPC_ERROR) {
6080Sstevel@tonic-gate 		kret = kadm5_randkey_principal_old(server_handle, princ,
6090Sstevel@tonic-gate 				key, n_keys);
6100Sstevel@tonic-gate 	}
6110Sstevel@tonic-gate 	return (kret);
6120Sstevel@tonic-gate }
6130Sstevel@tonic-gate 
6140Sstevel@tonic-gate /* not supported on client side */
kadm5_decrypt_key(void * server_handle,kadm5_principal_ent_t entry,krb5_int32 ktype,krb5_int32 stype,krb5_int32 kvno,krb5_keyblock * keyblock,krb5_keysalt * keysalt,int * kvnop)6150Sstevel@tonic-gate kadm5_ret_t kadm5_decrypt_key(void *server_handle,
6160Sstevel@tonic-gate 			      kadm5_principal_ent_t entry, krb5_int32
6170Sstevel@tonic-gate 			      ktype, krb5_int32 stype, krb5_int32
6180Sstevel@tonic-gate 			      kvno, krb5_keyblock *keyblock,
6190Sstevel@tonic-gate 			      krb5_keysalt *keysalt, int *kvnop)
6200Sstevel@tonic-gate {
6210Sstevel@tonic-gate      return EINVAL;
6220Sstevel@tonic-gate }
623