xref: /onnv-gate/usr/src/lib/krb5/kadm5/clnt/client_principal.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
3*0Sstevel@tonic-gate  * Use is subject to license terms.
4*0Sstevel@tonic-gate  */
5*0Sstevel@tonic-gate 
6*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
7*0Sstevel@tonic-gate 
8*0Sstevel@tonic-gate /*
9*0Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
10*0Sstevel@tonic-gate  *
11*0Sstevel@tonic-gate  *	Openvision retains the copyright to derivative works of
12*0Sstevel@tonic-gate  *	this source code.  Do *NOT* create a derivative of this
13*0Sstevel@tonic-gate  *	source code before consulting with your legal department.
14*0Sstevel@tonic-gate  *	Do *NOT* integrate *ANY* of this source code into another
15*0Sstevel@tonic-gate  *	product before consulting with your legal department.
16*0Sstevel@tonic-gate  *
17*0Sstevel@tonic-gate  *	For further information, read the top-level Openvision
18*0Sstevel@tonic-gate  *	copyright which is contained in the top-level MIT Kerberos
19*0Sstevel@tonic-gate  *	copyright.
20*0Sstevel@tonic-gate  *
21*0Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
22*0Sstevel@tonic-gate  *
23*0Sstevel@tonic-gate  */
24*0Sstevel@tonic-gate 
25*0Sstevel@tonic-gate 
26*0Sstevel@tonic-gate /*
27*0Sstevel@tonic-gate  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
28*0Sstevel@tonic-gate  *
29*0Sstevel@tonic-gate  * $Header: /cvs/krbdev/krb5/src/lib/kadm5/clnt/client_principal.c,v 1.8 2000/02/27 22:18:15 tlyu Exp $
30*0Sstevel@tonic-gate  */
31*0Sstevel@tonic-gate 
32*0Sstevel@tonic-gate #if !defined(lint) && !defined(__CODECENTER__)
33*0Sstevel@tonic-gate static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/clnt/client_principal.c,v 1.8 2000/02/27 22:18:15 tlyu Exp $";
34*0Sstevel@tonic-gate #endif
35*0Sstevel@tonic-gate 
36*0Sstevel@tonic-gate #include    <rpc/rpc.h>  /* SUNWresync121 XXX */
37*0Sstevel@tonic-gate #include    <kadm5/admin.h>
38*0Sstevel@tonic-gate #include    <kadm5/kadm_rpc.h>
39*0Sstevel@tonic-gate #include    <memory.h>
40*0Sstevel@tonic-gate #include    "client_internal.h"
41*0Sstevel@tonic-gate 
42*0Sstevel@tonic-gate kadm5_ret_t
43*0Sstevel@tonic-gate kadm5_create_principal(void *server_handle,
44*0Sstevel@tonic-gate 			    kadm5_principal_ent_t princ, long mask,
45*0Sstevel@tonic-gate 			    char *pw)
46*0Sstevel@tonic-gate {
47*0Sstevel@tonic-gate     generic_ret		*r;
48*0Sstevel@tonic-gate     cprinc_arg		arg;
49*0Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
50*0Sstevel@tonic-gate 
51*0Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
52*0Sstevel@tonic-gate 
53*0Sstevel@tonic-gate     memset(&arg, 0, sizeof(arg));
54*0Sstevel@tonic-gate     arg.mask = mask;
55*0Sstevel@tonic-gate     arg.passwd = pw;
56*0Sstevel@tonic-gate     arg.api_version = handle->api_version;
57*0Sstevel@tonic-gate 
58*0Sstevel@tonic-gate     if(princ == NULL)
59*0Sstevel@tonic-gate 	return EINVAL;
60*0Sstevel@tonic-gate 
61*0Sstevel@tonic-gate     if (handle->api_version == KADM5_API_VERSION_1) {
62*0Sstevel@tonic-gate        memcpy(&arg.rec, princ, sizeof(kadm5_principal_ent_rec_v1));
63*0Sstevel@tonic-gate     } else {
64*0Sstevel@tonic-gate        memcpy(&arg.rec, princ, sizeof(kadm5_principal_ent_rec));
65*0Sstevel@tonic-gate     }
66*0Sstevel@tonic-gate     if (handle->api_version == KADM5_API_VERSION_1) {
67*0Sstevel@tonic-gate 	 /*
68*0Sstevel@tonic-gate 	  * hack hack cough cough.
69*0Sstevel@tonic-gate 	  * krb5_unparse name dumps core if we pass it in garbage
70*0Sstevel@tonic-gate 	  * or null. So, since the client is not allowed to set mod_name
71*0Sstevel@tonic-gate 	  * anyway, we just fill it in with a dummy principal. The server of
72*0Sstevel@tonic-gate 	  * course ignores this.
73*0Sstevel@tonic-gate 	  */
74*0Sstevel@tonic-gate 	/* krb5_parse_name(handle->context, "bogus/bogus", &arg.rec.mod_name); */
75*0Sstevel@tonic-gate 	 arg.rec.mod_name = NULL;
76*0Sstevel@tonic-gate     } else
77*0Sstevel@tonic-gate 	 arg.rec.mod_name = NULL;
78*0Sstevel@tonic-gate 
79*0Sstevel@tonic-gate     if(!(mask & KADM5_POLICY))
80*0Sstevel@tonic-gate 	arg.rec.policy = NULL;
81*0Sstevel@tonic-gate     if (! (mask & KADM5_KEY_DATA)) {
82*0Sstevel@tonic-gate 	 arg.rec.n_key_data = 0;
83*0Sstevel@tonic-gate 	 arg.rec.key_data = NULL;
84*0Sstevel@tonic-gate     }
85*0Sstevel@tonic-gate     if (! (mask & KADM5_TL_DATA)) {
86*0Sstevel@tonic-gate 	 arg.rec.n_tl_data = 0;
87*0Sstevel@tonic-gate 	 arg.rec.tl_data = NULL;
88*0Sstevel@tonic-gate     }
89*0Sstevel@tonic-gate 
90*0Sstevel@tonic-gate     r = create_principal_1(&arg, handle->clnt);
91*0Sstevel@tonic-gate 
92*0Sstevel@tonic-gate     if (handle->api_version == KADM5_API_VERSION_1)
93*0Sstevel@tonic-gate 	 krb5_free_principal(handle->context, arg.rec.mod_name);
94*0Sstevel@tonic-gate 
95*0Sstevel@tonic-gate     if(r == NULL)
96*0Sstevel@tonic-gate 	return KADM5_RPC_ERROR;
97*0Sstevel@tonic-gate     return r->code;
98*0Sstevel@tonic-gate }
99*0Sstevel@tonic-gate 
100*0Sstevel@tonic-gate kadm5_ret_t
101*0Sstevel@tonic-gate kadm5_create_principal_3(void *server_handle,
102*0Sstevel@tonic-gate 			 kadm5_principal_ent_t princ, long mask,
103*0Sstevel@tonic-gate 			 int n_ks_tuple,
104*0Sstevel@tonic-gate 			 krb5_key_salt_tuple *ks_tuple,
105*0Sstevel@tonic-gate 			 char *pw)
106*0Sstevel@tonic-gate {
107*0Sstevel@tonic-gate     generic_ret		*r;
108*0Sstevel@tonic-gate     cprinc3_arg		arg;
109*0Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
110*0Sstevel@tonic-gate 
111*0Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
112*0Sstevel@tonic-gate 
113*0Sstevel@tonic-gate     memset(&arg, 0, sizeof(arg));
114*0Sstevel@tonic-gate     arg.mask = mask;
115*0Sstevel@tonic-gate     arg.passwd = pw;
116*0Sstevel@tonic-gate     arg.api_version = handle->api_version;
117*0Sstevel@tonic-gate     arg.n_ks_tuple = n_ks_tuple;
118*0Sstevel@tonic-gate     arg.ks_tuple = ks_tuple;
119*0Sstevel@tonic-gate 
120*0Sstevel@tonic-gate     if(princ == NULL)
121*0Sstevel@tonic-gate 	return EINVAL;
122*0Sstevel@tonic-gate 
123*0Sstevel@tonic-gate     if (handle->api_version == KADM5_API_VERSION_1) {
124*0Sstevel@tonic-gate        memcpy(&arg.rec, princ, sizeof(kadm5_principal_ent_rec_v1));
125*0Sstevel@tonic-gate     } else {
126*0Sstevel@tonic-gate        memcpy(&arg.rec, princ, sizeof(kadm5_principal_ent_rec));
127*0Sstevel@tonic-gate     }
128*0Sstevel@tonic-gate     if (handle->api_version == KADM5_API_VERSION_1) {
129*0Sstevel@tonic-gate 	 /*
130*0Sstevel@tonic-gate 	  * hack hack cough cough.
131*0Sstevel@tonic-gate 	  * krb5_unparse name dumps core if we pass it in garbage
132*0Sstevel@tonic-gate 	  * or null. So, since the client is not allowed to set mod_name
133*0Sstevel@tonic-gate 	  * anyway, we just fill it in with a dummy principal. The server of
134*0Sstevel@tonic-gate 	  * course ignores this.
135*0Sstevel@tonic-gate 	  */
136*0Sstevel@tonic-gate 	 krb5_parse_name(handle->context, "bogus/bogus", &arg.rec.mod_name);
137*0Sstevel@tonic-gate     } else
138*0Sstevel@tonic-gate 	 arg.rec.mod_name = NULL;
139*0Sstevel@tonic-gate 
140*0Sstevel@tonic-gate     if(!(mask & KADM5_POLICY))
141*0Sstevel@tonic-gate 	arg.rec.policy = NULL;
142*0Sstevel@tonic-gate     if (! (mask & KADM5_KEY_DATA)) {
143*0Sstevel@tonic-gate 	 arg.rec.n_key_data = 0;
144*0Sstevel@tonic-gate 	 arg.rec.key_data = NULL;
145*0Sstevel@tonic-gate     }
146*0Sstevel@tonic-gate     if (! (mask & KADM5_TL_DATA)) {
147*0Sstevel@tonic-gate 	 arg.rec.n_tl_data = 0;
148*0Sstevel@tonic-gate 	 arg.rec.tl_data = NULL;
149*0Sstevel@tonic-gate     }
150*0Sstevel@tonic-gate 
151*0Sstevel@tonic-gate     r = create_principal3_1(&arg, handle->clnt);
152*0Sstevel@tonic-gate 
153*0Sstevel@tonic-gate     if (handle->api_version == KADM5_API_VERSION_1)
154*0Sstevel@tonic-gate 	 krb5_free_principal(handle->context, arg.rec.mod_name);
155*0Sstevel@tonic-gate 
156*0Sstevel@tonic-gate     if(r == NULL)
157*0Sstevel@tonic-gate 	return KADM5_RPC_ERROR;
158*0Sstevel@tonic-gate     return r->code;
159*0Sstevel@tonic-gate }
160*0Sstevel@tonic-gate 
161*0Sstevel@tonic-gate kadm5_ret_t
162*0Sstevel@tonic-gate kadm5_delete_principal(void *server_handle, krb5_principal principal)
163*0Sstevel@tonic-gate {
164*0Sstevel@tonic-gate     dprinc_arg		arg;
165*0Sstevel@tonic-gate     generic_ret		*r;
166*0Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
167*0Sstevel@tonic-gate 
168*0Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
169*0Sstevel@tonic-gate 
170*0Sstevel@tonic-gate     if(principal == NULL)
171*0Sstevel@tonic-gate 	return EINVAL;
172*0Sstevel@tonic-gate     arg.princ = principal;
173*0Sstevel@tonic-gate     arg.api_version = handle->api_version;
174*0Sstevel@tonic-gate     r = delete_principal_1(&arg, handle->clnt);
175*0Sstevel@tonic-gate     if(r == NULL)
176*0Sstevel@tonic-gate 	return KADM5_RPC_ERROR;
177*0Sstevel@tonic-gate     return r->code;
178*0Sstevel@tonic-gate }
179*0Sstevel@tonic-gate 
180*0Sstevel@tonic-gate kadm5_ret_t
181*0Sstevel@tonic-gate kadm5_modify_principal(void *server_handle,
182*0Sstevel@tonic-gate 			    kadm5_principal_ent_t princ, long mask)
183*0Sstevel@tonic-gate {
184*0Sstevel@tonic-gate     mprinc_arg		arg;
185*0Sstevel@tonic-gate     generic_ret		*r;
186*0Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
187*0Sstevel@tonic-gate 
188*0Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
189*0Sstevel@tonic-gate 
190*0Sstevel@tonic-gate     memset(&arg, 0, sizeof(arg));
191*0Sstevel@tonic-gate     arg.mask = mask;
192*0Sstevel@tonic-gate     arg.api_version = handle->api_version;
193*0Sstevel@tonic-gate     /*
194*0Sstevel@tonic-gate      * cough cough gag gag
195*0Sstevel@tonic-gate      * see comment in create_principal.
196*0Sstevel@tonic-gate      */
197*0Sstevel@tonic-gate     if(princ == NULL)
198*0Sstevel@tonic-gate 	return EINVAL;
199*0Sstevel@tonic-gate     if (handle->api_version == KADM5_API_VERSION_1) {
200*0Sstevel@tonic-gate         memcpy(&arg.rec, princ, sizeof(kadm5_principal_ent_rec_v1));
201*0Sstevel@tonic-gate     } else {
202*0Sstevel@tonic-gate         memcpy(&arg.rec, princ, sizeof(kadm5_principal_ent_rec));
203*0Sstevel@tonic-gate     }
204*0Sstevel@tonic-gate     if(!(mask & KADM5_POLICY))
205*0Sstevel@tonic-gate 	arg.rec.policy = NULL;
206*0Sstevel@tonic-gate     if (! (mask & KADM5_KEY_DATA)) {
207*0Sstevel@tonic-gate 	 arg.rec.n_key_data = 0;
208*0Sstevel@tonic-gate 	 arg.rec.key_data = NULL;
209*0Sstevel@tonic-gate     }
210*0Sstevel@tonic-gate     if (! (mask & KADM5_TL_DATA)) {
211*0Sstevel@tonic-gate 	 arg.rec.n_tl_data = 0;
212*0Sstevel@tonic-gate 	 arg.rec.tl_data = NULL;
213*0Sstevel@tonic-gate     }
214*0Sstevel@tonic-gate 
215*0Sstevel@tonic-gate     if (handle->api_version == KADM5_API_VERSION_1) {
216*0Sstevel@tonic-gate 	 /*
217*0Sstevel@tonic-gate 	  * See comment in create_principal
218*0Sstevel@tonic-gate 	  */
219*0Sstevel@tonic-gate 	 krb5_parse_name(handle->context, "bogus/bogus", &arg.rec.mod_name);
220*0Sstevel@tonic-gate     } else
221*0Sstevel@tonic-gate 	 arg.rec.mod_name = NULL;
222*0Sstevel@tonic-gate 
223*0Sstevel@tonic-gate     r = modify_principal_1(&arg, handle->clnt);
224*0Sstevel@tonic-gate 
225*0Sstevel@tonic-gate     if (handle->api_version == KADM5_API_VERSION_1)
226*0Sstevel@tonic-gate 	 krb5_free_principal(handle->context, arg.rec.mod_name);
227*0Sstevel@tonic-gate 
228*0Sstevel@tonic-gate     if(r == NULL)
229*0Sstevel@tonic-gate 	return KADM5_RPC_ERROR;
230*0Sstevel@tonic-gate     return r->code;
231*0Sstevel@tonic-gate }
232*0Sstevel@tonic-gate 
233*0Sstevel@tonic-gate kadm5_ret_t
234*0Sstevel@tonic-gate kadm5_get_principal(void *server_handle,
235*0Sstevel@tonic-gate 		    krb5_principal princ, kadm5_principal_ent_t ent,
236*0Sstevel@tonic-gate 		    long mask)
237*0Sstevel@tonic-gate {
238*0Sstevel@tonic-gate     gprinc_arg	arg;
239*0Sstevel@tonic-gate     gprinc_ret	*r;
240*0Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
241*0Sstevel@tonic-gate 
242*0Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
243*0Sstevel@tonic-gate 
244*0Sstevel@tonic-gate     if(princ == NULL)
245*0Sstevel@tonic-gate 	return EINVAL;
246*0Sstevel@tonic-gate     arg.princ = princ;
247*0Sstevel@tonic-gate     if (handle->api_version == KADM5_API_VERSION_1)
248*0Sstevel@tonic-gate        arg.mask = KADM5_PRINCIPAL_NORMAL_MASK;
249*0Sstevel@tonic-gate     else
250*0Sstevel@tonic-gate        arg.mask = mask;
251*0Sstevel@tonic-gate     arg.api_version = handle->api_version;
252*0Sstevel@tonic-gate     r = get_principal_1(&arg, handle->clnt);
253*0Sstevel@tonic-gate     if(r == NULL)
254*0Sstevel@tonic-gate 	return KADM5_RPC_ERROR;
255*0Sstevel@tonic-gate     if (handle->api_version == KADM5_API_VERSION_1) {
256*0Sstevel@tonic-gate 	 kadm5_principal_ent_t_v1 *entp;
257*0Sstevel@tonic-gate 
258*0Sstevel@tonic-gate 	 entp = (kadm5_principal_ent_t_v1 *) ent;
259*0Sstevel@tonic-gate 	 if (r->code == 0) {
260*0Sstevel@tonic-gate 	      if (!(*entp = (kadm5_principal_ent_t_v1)
261*0Sstevel@tonic-gate 		    malloc(sizeof(kadm5_principal_ent_rec_v1))))
262*0Sstevel@tonic-gate 		   return ENOMEM;
263*0Sstevel@tonic-gate 	      /* this memcpy works because the v1 structure is an initial
264*0Sstevel@tonic-gate 		 subset of the v2 struct.  C guarantees that this will
265*0Sstevel@tonic-gate 		 result in the same layout in memory */
266*0Sstevel@tonic-gate 	      memcpy(*entp, &r->rec, sizeof(**entp));
267*0Sstevel@tonic-gate 	 } else {
268*0Sstevel@tonic-gate 	    *entp = NULL;
269*0Sstevel@tonic-gate 	 }
270*0Sstevel@tonic-gate     } else {
271*0Sstevel@tonic-gate 	 if (r->code == 0)
272*0Sstevel@tonic-gate 	      memcpy(ent, &r->rec, sizeof(r->rec));
273*0Sstevel@tonic-gate     }
274*0Sstevel@tonic-gate 
275*0Sstevel@tonic-gate     return r->code;
276*0Sstevel@tonic-gate }
277*0Sstevel@tonic-gate 
278*0Sstevel@tonic-gate kadm5_ret_t
279*0Sstevel@tonic-gate kadm5_get_principals(void *server_handle,
280*0Sstevel@tonic-gate 			  char *exp, char ***princs, int *count)
281*0Sstevel@tonic-gate {
282*0Sstevel@tonic-gate     gprincs_arg	arg;
283*0Sstevel@tonic-gate     gprincs_ret	*r;
284*0Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
285*0Sstevel@tonic-gate 
286*0Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
287*0Sstevel@tonic-gate 
288*0Sstevel@tonic-gate     if(princs == NULL || count == NULL)
289*0Sstevel@tonic-gate 	return EINVAL;
290*0Sstevel@tonic-gate     arg.exp = exp;
291*0Sstevel@tonic-gate     arg.api_version = handle->api_version;
292*0Sstevel@tonic-gate     r = get_princs_1(&arg, handle->clnt);
293*0Sstevel@tonic-gate     if(r == NULL)
294*0Sstevel@tonic-gate 	return KADM5_RPC_ERROR;
295*0Sstevel@tonic-gate     if(r->code == 0) {
296*0Sstevel@tonic-gate 	 *count = r->count;
297*0Sstevel@tonic-gate 	 *princs = r->princs;
298*0Sstevel@tonic-gate     } else {
299*0Sstevel@tonic-gate 	 *count = 0;
300*0Sstevel@tonic-gate 	 *princs = NULL;
301*0Sstevel@tonic-gate     }
302*0Sstevel@tonic-gate 
303*0Sstevel@tonic-gate     return r->code;
304*0Sstevel@tonic-gate }
305*0Sstevel@tonic-gate 
306*0Sstevel@tonic-gate kadm5_ret_t
307*0Sstevel@tonic-gate kadm5_rename_principal(void *server_handle,
308*0Sstevel@tonic-gate 			    krb5_principal source, krb5_principal dest)
309*0Sstevel@tonic-gate {
310*0Sstevel@tonic-gate     rprinc_arg		arg;
311*0Sstevel@tonic-gate     generic_ret		*r;
312*0Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
313*0Sstevel@tonic-gate 
314*0Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
315*0Sstevel@tonic-gate 
316*0Sstevel@tonic-gate     arg.src = source;
317*0Sstevel@tonic-gate     arg.dest = dest;
318*0Sstevel@tonic-gate     arg.api_version = handle->api_version;
319*0Sstevel@tonic-gate     if (source == NULL || dest == NULL)
320*0Sstevel@tonic-gate 	return EINVAL;
321*0Sstevel@tonic-gate     r = rename_principal_1(&arg, handle->clnt);
322*0Sstevel@tonic-gate     if(r == NULL)
323*0Sstevel@tonic-gate 	return KADM5_RPC_ERROR;
324*0Sstevel@tonic-gate     return r->code;
325*0Sstevel@tonic-gate }
326*0Sstevel@tonic-gate 
327*0Sstevel@tonic-gate kadm5_ret_t
328*0Sstevel@tonic-gate kadm5_chpass_principal(void *server_handle,
329*0Sstevel@tonic-gate 			    krb5_principal princ, char *password)
330*0Sstevel@tonic-gate {
331*0Sstevel@tonic-gate     chpass_arg		arg;
332*0Sstevel@tonic-gate     generic_ret		*r;
333*0Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
334*0Sstevel@tonic-gate 
335*0Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
336*0Sstevel@tonic-gate 
337*0Sstevel@tonic-gate     arg.princ = princ;
338*0Sstevel@tonic-gate     arg.pass = password;
339*0Sstevel@tonic-gate     arg.api_version = handle->api_version;
340*0Sstevel@tonic-gate 
341*0Sstevel@tonic-gate     if(princ == NULL)
342*0Sstevel@tonic-gate 	return EINVAL;
343*0Sstevel@tonic-gate     r = chpass_principal_1(&arg, handle->clnt);
344*0Sstevel@tonic-gate     if(r == NULL)
345*0Sstevel@tonic-gate 	return KADM5_RPC_ERROR;
346*0Sstevel@tonic-gate     return r->code;
347*0Sstevel@tonic-gate }
348*0Sstevel@tonic-gate 
349*0Sstevel@tonic-gate kadm5_ret_t
350*0Sstevel@tonic-gate kadm5_chpass_principal_3(void *server_handle,
351*0Sstevel@tonic-gate 			 krb5_principal princ, krb5_boolean keepold,
352*0Sstevel@tonic-gate 			 int n_ks_tuple, krb5_key_salt_tuple *ks_tuple,
353*0Sstevel@tonic-gate 			 char *password)
354*0Sstevel@tonic-gate {
355*0Sstevel@tonic-gate     chpass3_arg		arg;
356*0Sstevel@tonic-gate     generic_ret		*r;
357*0Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
358*0Sstevel@tonic-gate 
359*0Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
360*0Sstevel@tonic-gate 
361*0Sstevel@tonic-gate     arg.princ = princ;
362*0Sstevel@tonic-gate     arg.pass = password;
363*0Sstevel@tonic-gate     arg.api_version = handle->api_version;
364*0Sstevel@tonic-gate     arg.keepold = keepold;
365*0Sstevel@tonic-gate     arg.n_ks_tuple = n_ks_tuple;
366*0Sstevel@tonic-gate     arg.ks_tuple = ks_tuple;
367*0Sstevel@tonic-gate 
368*0Sstevel@tonic-gate     if(princ == NULL)
369*0Sstevel@tonic-gate 	return EINVAL;
370*0Sstevel@tonic-gate     r = chpass_principal3_1(&arg, handle->clnt);
371*0Sstevel@tonic-gate     if(r == NULL)
372*0Sstevel@tonic-gate 	return KADM5_RPC_ERROR;
373*0Sstevel@tonic-gate     return r->code;
374*0Sstevel@tonic-gate }
375*0Sstevel@tonic-gate 
376*0Sstevel@tonic-gate kadm5_ret_t
377*0Sstevel@tonic-gate kadm5_setv4key_principal(void *server_handle,
378*0Sstevel@tonic-gate 			 krb5_principal princ,
379*0Sstevel@tonic-gate 			 krb5_keyblock *keyblock)
380*0Sstevel@tonic-gate {
381*0Sstevel@tonic-gate     setv4key_arg	arg;
382*0Sstevel@tonic-gate     generic_ret		*r;
383*0Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
384*0Sstevel@tonic-gate 
385*0Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
386*0Sstevel@tonic-gate 
387*0Sstevel@tonic-gate     arg.princ = princ;
388*0Sstevel@tonic-gate     arg.keyblock = keyblock;
389*0Sstevel@tonic-gate     arg.api_version = handle->api_version;
390*0Sstevel@tonic-gate 
391*0Sstevel@tonic-gate     if(princ == NULL || keyblock == NULL)
392*0Sstevel@tonic-gate 	return EINVAL;
393*0Sstevel@tonic-gate     r = setv4key_principal_1(&arg, handle->clnt);
394*0Sstevel@tonic-gate     if(r == NULL)
395*0Sstevel@tonic-gate 	return KADM5_RPC_ERROR;
396*0Sstevel@tonic-gate     return r->code;
397*0Sstevel@tonic-gate }
398*0Sstevel@tonic-gate 
399*0Sstevel@tonic-gate kadm5_ret_t
400*0Sstevel@tonic-gate kadm5_setkey_principal(void *server_handle,
401*0Sstevel@tonic-gate 		       krb5_principal princ,
402*0Sstevel@tonic-gate 		       krb5_keyblock *keyblocks,
403*0Sstevel@tonic-gate 		       int n_keys)
404*0Sstevel@tonic-gate {
405*0Sstevel@tonic-gate 
406*0Sstevel@tonic-gate     setkey_arg		arg;
407*0Sstevel@tonic-gate     generic_ret		*r;
408*0Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
409*0Sstevel@tonic-gate 
410*0Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
411*0Sstevel@tonic-gate 
412*0Sstevel@tonic-gate     arg.princ = princ;
413*0Sstevel@tonic-gate     arg.keyblocks = keyblocks;
414*0Sstevel@tonic-gate     arg.n_keys = n_keys;
415*0Sstevel@tonic-gate     arg.api_version = handle->api_version;
416*0Sstevel@tonic-gate 
417*0Sstevel@tonic-gate     if(princ == NULL || keyblocks == NULL)
418*0Sstevel@tonic-gate 	return EINVAL;
419*0Sstevel@tonic-gate     r = setkey_principal_1(&arg, handle->clnt);
420*0Sstevel@tonic-gate     if(r == NULL)
421*0Sstevel@tonic-gate 	return KADM5_RPC_ERROR;
422*0Sstevel@tonic-gate     return r->code;
423*0Sstevel@tonic-gate }
424*0Sstevel@tonic-gate 
425*0Sstevel@tonic-gate kadm5_ret_t
426*0Sstevel@tonic-gate kadm5_setkey_principal_3(void *server_handle,
427*0Sstevel@tonic-gate 			 krb5_principal princ,
428*0Sstevel@tonic-gate 			 krb5_boolean keepold, int n_ks_tuple,
429*0Sstevel@tonic-gate 			 krb5_key_salt_tuple *ks_tuple,
430*0Sstevel@tonic-gate 			 krb5_keyblock *keyblocks,
431*0Sstevel@tonic-gate 			 int n_keys)
432*0Sstevel@tonic-gate {
433*0Sstevel@tonic-gate     setkey3_arg		arg;
434*0Sstevel@tonic-gate     generic_ret		*r;
435*0Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
436*0Sstevel@tonic-gate 
437*0Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
438*0Sstevel@tonic-gate 
439*0Sstevel@tonic-gate     arg.princ = princ;
440*0Sstevel@tonic-gate     arg.keyblocks = keyblocks;
441*0Sstevel@tonic-gate     arg.n_keys = n_keys;
442*0Sstevel@tonic-gate     arg.api_version = handle->api_version;
443*0Sstevel@tonic-gate     arg.keepold = keepold;
444*0Sstevel@tonic-gate     arg.n_ks_tuple = n_ks_tuple;
445*0Sstevel@tonic-gate     arg.ks_tuple = ks_tuple;
446*0Sstevel@tonic-gate 
447*0Sstevel@tonic-gate     if(princ == NULL || keyblocks == NULL)
448*0Sstevel@tonic-gate 	return EINVAL;
449*0Sstevel@tonic-gate     r = setkey_principal3_1(&arg, handle->clnt);
450*0Sstevel@tonic-gate     if(r == NULL)
451*0Sstevel@tonic-gate 	return KADM5_RPC_ERROR;
452*0Sstevel@tonic-gate     return r->code;
453*0Sstevel@tonic-gate }
454*0Sstevel@tonic-gate 
455*0Sstevel@tonic-gate /*
456*0Sstevel@tonic-gate  * Solaris Kerberos:
457*0Sstevel@tonic-gate  * This routine implements just the "old" randkey_principal code.
458*0Sstevel@tonic-gate  * The code in the kadmin client sometimes needs to call this
459*0Sstevel@tonic-gate  * directly when the kadm5_randkey_principal_3 call fails.
460*0Sstevel@tonic-gate  *
461*0Sstevel@tonic-gate  * The kadmin client utility uses a specific set of key/salt tuples,
462*0Sstevel@tonic-gate  * so the standard fallback in kadm5_randkey_principal (see below)
463*0Sstevel@tonic-gate  * will not work because it would result in kadm5_randkey_principal_3
464*0Sstevel@tonic-gate  * being called twice - once with the specific key/salts specified by
465*0Sstevel@tonic-gate  * kadmin and once with the NULL set (used to indicate that the server
466*0Sstevel@tonic-gate  * should use the full set of supported enctypes).  Making this
467*0Sstevel@tonic-gate  * routine separate makes the code simpler and avoids making the
468*0Sstevel@tonic-gate  * kadm5_randkey_principal_3 twice from kadmin.
469*0Sstevel@tonic-gate  */
470*0Sstevel@tonic-gate kadm5_ret_t
471*0Sstevel@tonic-gate kadm5_randkey_principal_old(void *server_handle,
472*0Sstevel@tonic-gate 			krb5_principal princ,
473*0Sstevel@tonic-gate 			krb5_keyblock **key,
474*0Sstevel@tonic-gate 			int *n_keys)
475*0Sstevel@tonic-gate {
476*0Sstevel@tonic-gate 	chrand_arg		arg;
477*0Sstevel@tonic-gate 	chrand_ret		*r;
478*0Sstevel@tonic-gate 	kadm5_server_handle_t handle = server_handle;
479*0Sstevel@tonic-gate 	int		i, ret;
480*0Sstevel@tonic-gate 
481*0Sstevel@tonic-gate 	/* For safety */
482*0Sstevel@tonic-gate 	if (n_keys)
483*0Sstevel@tonic-gate 		*n_keys = 0;
484*0Sstevel@tonic-gate 	if (key)
485*0Sstevel@tonic-gate 		*key = NULL;
486*0Sstevel@tonic-gate 	CHECK_HANDLE(server_handle);
487*0Sstevel@tonic-gate 
488*0Sstevel@tonic-gate 	arg.princ = princ;
489*0Sstevel@tonic-gate 	arg.api_version = handle->api_version;
490*0Sstevel@tonic-gate 
491*0Sstevel@tonic-gate 	if(princ == NULL)
492*0Sstevel@tonic-gate 		return EINVAL;
493*0Sstevel@tonic-gate 	r = chrand_principal_1(&arg, handle->clnt);
494*0Sstevel@tonic-gate 	if (r == NULL)
495*0Sstevel@tonic-gate 		return KADM5_RPC_ERROR;
496*0Sstevel@tonic-gate 	if (handle->api_version == KADM5_API_VERSION_1) {
497*0Sstevel@tonic-gate 		if (key)
498*0Sstevel@tonic-gate 			krb5_copy_keyblock(handle->context, &r->key, key);
499*0Sstevel@tonic-gate 	} else if (key && (r->n_keys > 0)) {
500*0Sstevel@tonic-gate 		*key = (krb5_keyblock *) malloc(
501*0Sstevel@tonic-gate 			r->n_keys*sizeof(krb5_keyblock));
502*0Sstevel@tonic-gate 		if (*key == NULL)
503*0Sstevel@tonic-gate 			return ENOMEM;
504*0Sstevel@tonic-gate 		for (i = 0; i < r->n_keys; i++) {
505*0Sstevel@tonic-gate 			ret = krb5_copy_keyblock_contents(
506*0Sstevel@tonic-gate 				handle->context,
507*0Sstevel@tonic-gate 				&r->keys[i],
508*0Sstevel@tonic-gate 				&(*key)[i]);
509*0Sstevel@tonic-gate 			if (ret) {
510*0Sstevel@tonic-gate 				free(*key);
511*0Sstevel@tonic-gate 				*key = NULL;
512*0Sstevel@tonic-gate 				return ENOMEM;
513*0Sstevel@tonic-gate 			}
514*0Sstevel@tonic-gate 		}
515*0Sstevel@tonic-gate 		if (n_keys)
516*0Sstevel@tonic-gate 			*n_keys = r->n_keys;
517*0Sstevel@tonic-gate 	}
518*0Sstevel@tonic-gate 	return (r->code);
519*0Sstevel@tonic-gate }
520*0Sstevel@tonic-gate 
521*0Sstevel@tonic-gate kadm5_ret_t
522*0Sstevel@tonic-gate kadm5_randkey_principal_3(void *server_handle,
523*0Sstevel@tonic-gate 			  krb5_principal princ,
524*0Sstevel@tonic-gate 			  krb5_boolean keepold, int n_ks_tuple,
525*0Sstevel@tonic-gate 			  krb5_key_salt_tuple *ks_tuple,
526*0Sstevel@tonic-gate 			  krb5_keyblock **key, int *n_keys)
527*0Sstevel@tonic-gate {
528*0Sstevel@tonic-gate     chrand3_arg		arg;
529*0Sstevel@tonic-gate     chrand_ret		*r;
530*0Sstevel@tonic-gate     krb5_keyblock	new;
531*0Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
532*0Sstevel@tonic-gate     int			i, ret;
533*0Sstevel@tonic-gate 
534*0Sstevel@tonic-gate     /* For safety */
535*0Sstevel@tonic-gate     if (n_keys)
536*0Sstevel@tonic-gate 	*n_keys = 0;
537*0Sstevel@tonic-gate     if (key)
538*0Sstevel@tonic-gate 	*key = NULL;
539*0Sstevel@tonic-gate 
540*0Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
541*0Sstevel@tonic-gate 
542*0Sstevel@tonic-gate     arg.princ = princ;
543*0Sstevel@tonic-gate     arg.api_version = handle->api_version;
544*0Sstevel@tonic-gate     arg.keepold = keepold;
545*0Sstevel@tonic-gate     arg.n_ks_tuple = n_ks_tuple;
546*0Sstevel@tonic-gate     arg.ks_tuple = ks_tuple;
547*0Sstevel@tonic-gate 
548*0Sstevel@tonic-gate     if(princ == NULL)
549*0Sstevel@tonic-gate 	return EINVAL;
550*0Sstevel@tonic-gate     r = chrand_principal3_1(&arg, handle->clnt);
551*0Sstevel@tonic-gate     if(r == NULL)
552*0Sstevel@tonic-gate 	return KADM5_RPC_ERROR;
553*0Sstevel@tonic-gate     if (handle->api_version == KADM5_API_VERSION_1) {
554*0Sstevel@tonic-gate 	 if (key)
555*0Sstevel@tonic-gate 	      krb5_copy_keyblock(handle->context, &r->key, key);
556*0Sstevel@tonic-gate     } else if (key && (r->n_keys > 0)) {
557*0Sstevel@tonic-gate 	*key = (krb5_keyblock *)
558*0Sstevel@tonic-gate 	    malloc(r->n_keys*sizeof(krb5_keyblock));
559*0Sstevel@tonic-gate 	if (*key == NULL)
560*0Sstevel@tonic-gate 	    return ENOMEM;
561*0Sstevel@tonic-gate 	for (i = 0; i < r->n_keys; i++) {
562*0Sstevel@tonic-gate 	    ret = krb5_copy_keyblock_contents(handle->context,
563*0Sstevel@tonic-gate 		&r->keys[i],
564*0Sstevel@tonic-gate 		&(*key)[i]);
565*0Sstevel@tonic-gate 	    if (ret) {
566*0Sstevel@tonic-gate 		free(*key);
567*0Sstevel@tonic-gate 		*key = NULL;
568*0Sstevel@tonic-gate 		return ENOMEM;
569*0Sstevel@tonic-gate 	    }
570*0Sstevel@tonic-gate 	}
571*0Sstevel@tonic-gate 	if (n_keys)
572*0Sstevel@tonic-gate 	    *n_keys = r->n_keys;
573*0Sstevel@tonic-gate     }
574*0Sstevel@tonic-gate 
575*0Sstevel@tonic-gate     return r->code;
576*0Sstevel@tonic-gate }
577*0Sstevel@tonic-gate 
578*0Sstevel@tonic-gate kadm5_ret_t
579*0Sstevel@tonic-gate kadm5_randkey_principal(void *server_handle,
580*0Sstevel@tonic-gate 			krb5_principal princ,
581*0Sstevel@tonic-gate 			krb5_keyblock **key, int *n_keys)
582*0Sstevel@tonic-gate {
583*0Sstevel@tonic-gate 
584*0Sstevel@tonic-gate 	kadm5_ret_t kret;
585*0Sstevel@tonic-gate 
586*0Sstevel@tonic-gate 	/*
587*0Sstevel@tonic-gate 	 * Default to trying the newest API to insure that the full
588*0Sstevel@tonic-gate 	 * set of enctypes is created.
589*0Sstevel@tonic-gate 	 */
590*0Sstevel@tonic-gate 	kret = kadm5_randkey_principal_3(server_handle, princ, FALSE,
591*0Sstevel@tonic-gate 		0, NULL, key, n_keys);
592*0Sstevel@tonic-gate 
593*0Sstevel@tonic-gate 	/*
594*0Sstevel@tonic-gate 	 * We will get an RPC error if the RPC call failed which
595*0Sstevel@tonic-gate 	 * will normally indicate that the remote procedure did not
596*0Sstevel@tonic-gate 	 * exist on the server, so try the older API.
597*0Sstevel@tonic-gate 	 */
598*0Sstevel@tonic-gate 	if (kret == KADM5_RPC_ERROR) {
599*0Sstevel@tonic-gate 		kret = kadm5_randkey_principal_old(server_handle, princ,
600*0Sstevel@tonic-gate 				key, n_keys);
601*0Sstevel@tonic-gate 	}
602*0Sstevel@tonic-gate 	return (kret);
603*0Sstevel@tonic-gate }
604*0Sstevel@tonic-gate 
605*0Sstevel@tonic-gate /* not supported on client side */
606*0Sstevel@tonic-gate kadm5_ret_t kadm5_decrypt_key(void *server_handle,
607*0Sstevel@tonic-gate 			      kadm5_principal_ent_t entry, krb5_int32
608*0Sstevel@tonic-gate 			      ktype, krb5_int32 stype, krb5_int32
609*0Sstevel@tonic-gate 			      kvno, krb5_keyblock *keyblock,
610*0Sstevel@tonic-gate 			      krb5_keysalt *keysalt, int *kvnop)
611*0Sstevel@tonic-gate {
612*0Sstevel@tonic-gate      return EINVAL;
613*0Sstevel@tonic-gate }
614