xref: /onnv-gate/usr/src/cmd/krb5/kadmin/server/server_stubs.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: /afs/athena.mit.edu/astaff/project/krbdev/.cvsroot/src/
30*0Sstevel@tonic-gate  *  kadmin/server/server_stubs.c,v 1.34 1996/07/22 20:29:13 marc Exp $
31*0Sstevel@tonic-gate  */
32*0Sstevel@tonic-gate 
33*0Sstevel@tonic-gate #if !defined(lint) && !defined(__CODECENTER__)
34*0Sstevel@tonic-gate static char *rcsid = "$Header: /afs/athena.mit.edu/astaff/project/krbdev"
35*0Sstevel@tonic-gate 	"/.cvsroot/src/kadmin/server/server_stubs.c,v 1.34 "
36*0Sstevel@tonic-gate 	"1996/07/22 20:29:13 marc Exp $";
37*0Sstevel@tonic-gate 
38*0Sstevel@tonic-gate #endif
39*0Sstevel@tonic-gate 
40*0Sstevel@tonic-gate #include <gssapi/gssapi.h>
41*0Sstevel@tonic-gate #include <gssapi_krb5.h>   /* for gss_nt_krb5_name */
42*0Sstevel@tonic-gate #include <krb5.h>
43*0Sstevel@tonic-gate #include <kadm5/admin.h>
44*0Sstevel@tonic-gate #include <kadm5/kadm_rpc.h>
45*0Sstevel@tonic-gate #include <kadm5/server_internal.h>
46*0Sstevel@tonic-gate #include <kadm5/srv/server_acl.h>
47*0Sstevel@tonic-gate #include <security/pam_appl.h>
48*0Sstevel@tonic-gate 
49*0Sstevel@tonic-gate #include <syslog.h>
50*0Sstevel@tonic-gate #include <libintl.h>
51*0Sstevel@tonic-gate #include "misc.h"
52*0Sstevel@tonic-gate 
53*0Sstevel@tonic-gate #define	LOG_UNAUTH  gettext("Unauthorized request: %s, %s, " \
54*0Sstevel@tonic-gate 			    "client=%s, service=%s, addr=%s")
55*0Sstevel@tonic-gate #define	LOG_DONE    gettext("Request: %s, %s, %s, client=%s, " \
56*0Sstevel@tonic-gate 			    "service=%s, addr=%s")
57*0Sstevel@tonic-gate 
58*0Sstevel@tonic-gate extern gss_name_t gss_changepw_name;
59*0Sstevel@tonic-gate extern gss_name_t gss_oldchangepw_name;
60*0Sstevel@tonic-gate extern void *global_server_handle;
61*0Sstevel@tonic-gate extern short l_port;
62*0Sstevel@tonic-gate 
63*0Sstevel@tonic-gate char buf[33];
64*0Sstevel@tonic-gate 
65*0Sstevel@tonic-gate #define	CHANGEPW_SERVICE(rqstp) \
66*0Sstevel@tonic-gate 	(cmp_gss_names_rel_1(acceptor_name(rqstp), gss_changepw_name) |\
67*0Sstevel@tonic-gate 	(gss_oldchangepw_name && \
68*0Sstevel@tonic-gate 	cmp_gss_names_rel_1(acceptor_name(rqstp), \
69*0Sstevel@tonic-gate 			gss_oldchangepw_name)))
70*0Sstevel@tonic-gate 
71*0Sstevel@tonic-gate kadm5_ret_t
72*0Sstevel@tonic-gate kadm5_get_priv(void *server_handle,
73*0Sstevel@tonic-gate     long *privs, gss_name_t clnt);
74*0Sstevel@tonic-gate 
75*0Sstevel@tonic-gate gss_name_t
76*0Sstevel@tonic-gate get_clnt_name(struct svc_req * rqstp)
77*0Sstevel@tonic-gate {
78*0Sstevel@tonic-gate 	OM_uint32 maj_stat, min_stat;
79*0Sstevel@tonic-gate 	gss_name_t name;
80*0Sstevel@tonic-gate 	rpc_gss_rawcred_t *raw_cred;
81*0Sstevel@tonic-gate 	void *cookie;
82*0Sstevel@tonic-gate 	gss_buffer_desc name_buff;
83*0Sstevel@tonic-gate 
84*0Sstevel@tonic-gate 	rpc_gss_getcred(rqstp, &raw_cred, NULL, &cookie);
85*0Sstevel@tonic-gate 	name_buff.value = raw_cred->client_principal->name;
86*0Sstevel@tonic-gate 	name_buff.length = raw_cred->client_principal->len;
87*0Sstevel@tonic-gate 	maj_stat = gss_import_name(&min_stat, &name_buff,
88*0Sstevel@tonic-gate 	    (gss_OID) GSS_C_NT_EXPORT_NAME, &name);
89*0Sstevel@tonic-gate 	if (maj_stat != GSS_S_COMPLETE) {
90*0Sstevel@tonic-gate 		return (NULL);
91*0Sstevel@tonic-gate 	}
92*0Sstevel@tonic-gate 	return (name);
93*0Sstevel@tonic-gate }
94*0Sstevel@tonic-gate 
95*0Sstevel@tonic-gate char *
96*0Sstevel@tonic-gate client_addr(struct svc_req * req, char *buf)
97*0Sstevel@tonic-gate {
98*0Sstevel@tonic-gate 	struct sockaddr *ca;
99*0Sstevel@tonic-gate 	u_char *b;
100*0Sstevel@tonic-gate 	char *frontspace = " ";
101*0Sstevel@tonic-gate 
102*0Sstevel@tonic-gate 	/*
103*0Sstevel@tonic-gate 	 * Convert the caller's IP address to a dotted string
104*0Sstevel@tonic-gate 	 */
105*0Sstevel@tonic-gate 	ca = (struct sockaddr *)
106*0Sstevel@tonic-gate 	    svc_getrpccaller(req->rq_xprt)->buf;
107*0Sstevel@tonic-gate 
108*0Sstevel@tonic-gate 	if (ca->sa_family == AF_INET) {
109*0Sstevel@tonic-gate 		b = (u_char *) & ((struct sockaddr_in *) ca)->sin_addr;
110*0Sstevel@tonic-gate 		(void) sprintf(buf, "%s(%d.%d.%d.%d) ", frontspace,
111*0Sstevel@tonic-gate 		    b[0] & 0xFF, b[1] & 0xFF, b[2] & 0xFF, b[3] & 0xFF);
112*0Sstevel@tonic-gate 	} else {
113*0Sstevel@tonic-gate 		/*
114*0Sstevel@tonic-gate 		 * No IP address to print. If there was a host name
115*0Sstevel@tonic-gate 		 * printed, then we print a space.
116*0Sstevel@tonic-gate 		 */
117*0Sstevel@tonic-gate 		(void) sprintf(buf, frontspace);
118*0Sstevel@tonic-gate 	}
119*0Sstevel@tonic-gate 
120*0Sstevel@tonic-gate 	return (buf);
121*0Sstevel@tonic-gate }
122*0Sstevel@tonic-gate 
123*0Sstevel@tonic-gate int
124*0Sstevel@tonic-gate cmp_gss_names(gss_name_t n1, gss_name_t n2)
125*0Sstevel@tonic-gate {
126*0Sstevel@tonic-gate 	OM_uint32 emaj, emin;
127*0Sstevel@tonic-gate 	int equal;
128*0Sstevel@tonic-gate 
129*0Sstevel@tonic-gate 	if (GSS_ERROR(emaj = gss_compare_name(&emin, n1, n2, &equal)))
130*0Sstevel@tonic-gate 		return (0);
131*0Sstevel@tonic-gate 
132*0Sstevel@tonic-gate 	return (equal);
133*0Sstevel@tonic-gate }
134*0Sstevel@tonic-gate 
135*0Sstevel@tonic-gate /* Does a comparison of the names and then releases the first entity */
136*0Sstevel@tonic-gate /* For use above in CHANGEPW_SERVICE */
137*0Sstevel@tonic-gate int cmp_gss_names_rel_1(gss_name_t n1, gss_name_t n2)
138*0Sstevel@tonic-gate {
139*0Sstevel@tonic-gate    OM_uint32 min_stat;
140*0Sstevel@tonic-gate    int ret;
141*0Sstevel@tonic-gate 
142*0Sstevel@tonic-gate     ret = cmp_gss_names(n1, n2);
143*0Sstevel@tonic-gate    if (n1) (void) gss_release_name(&min_stat, &n1);
144*0Sstevel@tonic-gate    return ret;
145*0Sstevel@tonic-gate }
146*0Sstevel@tonic-gate 
147*0Sstevel@tonic-gate /*
148*0Sstevel@tonic-gate  * Function check_handle
149*0Sstevel@tonic-gate  *
150*0Sstevel@tonic-gate  * Purpose: Check a server handle and return a com_err code if it is
151*0Sstevel@tonic-gate  * invalid or 0 if it is valid.
152*0Sstevel@tonic-gate  *
153*0Sstevel@tonic-gate  * Arguments:
154*0Sstevel@tonic-gate  *
155*0Sstevel@tonic-gate  * 	handle		The server handle.
156*0Sstevel@tonic-gate  */
157*0Sstevel@tonic-gate 
158*0Sstevel@tonic-gate static int
159*0Sstevel@tonic-gate check_handle(void *handle)
160*0Sstevel@tonic-gate {
161*0Sstevel@tonic-gate 	CHECK_HANDLE(handle);
162*0Sstevel@tonic-gate 	return (0);
163*0Sstevel@tonic-gate }
164*0Sstevel@tonic-gate 
165*0Sstevel@tonic-gate int
166*0Sstevel@tonic-gate gss_to_krb5_name(kadm5_server_handle_t handle,
167*0Sstevel@tonic-gate     gss_name_t gss_name, krb5_principal * princ)
168*0Sstevel@tonic-gate {
169*0Sstevel@tonic-gate 	OM_uint32 stat, min_stat;
170*0Sstevel@tonic-gate 	gss_buffer_desc gss_str;
171*0Sstevel@tonic-gate 	gss_OID gss_type;
172*0Sstevel@tonic-gate 	int success;
173*0Sstevel@tonic-gate 
174*0Sstevel@tonic-gate 	stat = gss_display_name(&min_stat, gss_name, &gss_str, &gss_type);
175*0Sstevel@tonic-gate 	if ((stat != GSS_S_COMPLETE) ||
176*0Sstevel@tonic-gate 	    (!g_OID_equal(gss_type, gss_nt_krb5_name)))
177*0Sstevel@tonic-gate 		return (0);
178*0Sstevel@tonic-gate 	success = (krb5_parse_name(handle->context, gss_str.value, princ) == 0);
179*0Sstevel@tonic-gate 	gss_release_buffer(&min_stat, &gss_str);
180*0Sstevel@tonic-gate 	return (success);
181*0Sstevel@tonic-gate }
182*0Sstevel@tonic-gate 
183*0Sstevel@tonic-gate /*
184*0Sstevel@tonic-gate  * Function: new_server_handle
185*0Sstevel@tonic-gate  *
186*0Sstevel@tonic-gate  * Purpose: Constructs a server handle suitable for passing into the
187*0Sstevel@tonic-gate  * server library API functions, by folding the client's API version
188*0Sstevel@tonic-gate  * and calling principal into the server handle returned by
189*0Sstevel@tonic-gate  * kadm5_init.
190*0Sstevel@tonic-gate  *
191*0Sstevel@tonic-gate  * Arguments:
192*0Sstevel@tonic-gate  * 	api_version	(input) The API version specified by the client
193*0Sstevel@tonic-gate  * 	rqstp		(input) The RPC request
194*0Sstevel@tonic-gate  * 	handle		(output) The returned handle
195*0Sstevel@tonic-gate  *	<return value>	(output) An error code, or 0 if no error occurred
196*0Sstevel@tonic-gate  *
197*0Sstevel@tonic-gate  * Effects:
198*0Sstevel@tonic-gate  * 	Returns a pointer to allocated storage containing the server
199*0Sstevel@tonic-gate  * 	handle.  If an error occurs, then no allocated storage is
200*0Sstevel@tonic-gate  *	returned, and the return value of the function will be a
201*0Sstevel@tonic-gate  * 	non-zero com_err code.
202*0Sstevel@tonic-gate  *
203*0Sstevel@tonic-gate  *      The allocated storage for the handle should be freed with
204*0Sstevel@tonic-gate  * 	free_server_handle (see below) when it is no longer needed.
205*0Sstevel@tonic-gate  */
206*0Sstevel@tonic-gate 
207*0Sstevel@tonic-gate static kadm5_ret_t
208*0Sstevel@tonic-gate new_server_handle(krb5_ui_4 api_version,
209*0Sstevel@tonic-gate 		struct svc_req * rqstp,
210*0Sstevel@tonic-gate 		kadm5_server_handle_t *out_handle)
211*0Sstevel@tonic-gate {
212*0Sstevel@tonic-gate 	kadm5_server_handle_t handle;
213*0Sstevel@tonic-gate 	gss_name_t name;
214*0Sstevel@tonic-gate 	OM_uint32 min_stat;
215*0Sstevel@tonic-gate 
216*0Sstevel@tonic-gate 	if (!(handle = (kadm5_server_handle_t)
217*0Sstevel@tonic-gate 		malloc(sizeof (*handle))))
218*0Sstevel@tonic-gate 		return (ENOMEM);
219*0Sstevel@tonic-gate 
220*0Sstevel@tonic-gate 	*handle = *(kadm5_server_handle_t) global_server_handle;
221*0Sstevel@tonic-gate 	handle->api_version = api_version;
222*0Sstevel@tonic-gate 
223*0Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
224*0Sstevel@tonic-gate 		free(handle);
225*0Sstevel@tonic-gate 		return (KADM5_FAILURE);
226*0Sstevel@tonic-gate 	}
227*0Sstevel@tonic-gate 	if (!gss_to_krb5_name(handle, name, &handle->current_caller)) {
228*0Sstevel@tonic-gate 		free(handle);
229*0Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
230*0Sstevel@tonic-gate 		return (KADM5_FAILURE);
231*0Sstevel@tonic-gate 	}
232*0Sstevel@tonic-gate 	gss_release_name(&min_stat, &name);
233*0Sstevel@tonic-gate 
234*0Sstevel@tonic-gate 	*out_handle = handle;
235*0Sstevel@tonic-gate 	return (0);
236*0Sstevel@tonic-gate }
237*0Sstevel@tonic-gate 
238*0Sstevel@tonic-gate /*
239*0Sstevel@tonic-gate  * Function: free_server_handle
240*0Sstevel@tonic-gate  *
241*0Sstevel@tonic-gate  * Purpose: Free handle memory allocated by new_server_handle
242*0Sstevel@tonic-gate  *
243*0Sstevel@tonic-gate  * Arguments:
244*0Sstevel@tonic-gate  * 	handle		(input/output) The handle to free
245*0Sstevel@tonic-gate  */
246*0Sstevel@tonic-gate static void
247*0Sstevel@tonic-gate free_server_handle(kadm5_server_handle_t handle)
248*0Sstevel@tonic-gate {
249*0Sstevel@tonic-gate 	krb5_free_principal(handle->context, handle->current_caller);
250*0Sstevel@tonic-gate 	free(handle);
251*0Sstevel@tonic-gate }
252*0Sstevel@tonic-gate 
253*0Sstevel@tonic-gate gss_name_t
254*0Sstevel@tonic-gate acceptor_name(struct svc_req * rqstp)
255*0Sstevel@tonic-gate {
256*0Sstevel@tonic-gate 	OM_uint32 maj_stat, min_stat;
257*0Sstevel@tonic-gate 	gss_name_t name;
258*0Sstevel@tonic-gate 	rpc_gss_rawcred_t *raw_cred;
259*0Sstevel@tonic-gate 	void *cookie;
260*0Sstevel@tonic-gate 	gss_buffer_desc name_buff;
261*0Sstevel@tonic-gate 
262*0Sstevel@tonic-gate 	rpc_gss_getcred(rqstp, &raw_cred, NULL, &cookie);
263*0Sstevel@tonic-gate 	name_buff.value = raw_cred->svc_principal;
264*0Sstevel@tonic-gate 	name_buff.length = strlen(raw_cred->svc_principal);
265*0Sstevel@tonic-gate 	maj_stat = gss_import_name(&min_stat, &name_buff,
266*0Sstevel@tonic-gate 	    (gss_OID) gss_nt_krb5_name, &name);
267*0Sstevel@tonic-gate 	if (maj_stat != GSS_S_COMPLETE) {
268*0Sstevel@tonic-gate 		gss_release_buffer(&min_stat, &name_buff);
269*0Sstevel@tonic-gate 		return (NULL);
270*0Sstevel@tonic-gate 	}
271*0Sstevel@tonic-gate 	maj_stat = gss_display_name(&min_stat, name, &name_buff, NULL);
272*0Sstevel@tonic-gate 	if (maj_stat != GSS_S_COMPLETE) {
273*0Sstevel@tonic-gate 		gss_release_buffer(&min_stat, &name_buff);
274*0Sstevel@tonic-gate 		return (NULL);
275*0Sstevel@tonic-gate 	}
276*0Sstevel@tonic-gate 	gss_release_buffer(&min_stat, &name_buff);
277*0Sstevel@tonic-gate 
278*0Sstevel@tonic-gate 	return (name);
279*0Sstevel@tonic-gate }
280*0Sstevel@tonic-gate 
281*0Sstevel@tonic-gate /*
282*0Sstevel@tonic-gate  * Function: setup_gss_names
283*0Sstevel@tonic-gate  *
284*0Sstevel@tonic-gate  * Purpose: Create printable representations of the client and server
285*0Sstevel@tonic-gate  * names.
286*0Sstevel@tonic-gate  *
287*0Sstevel@tonic-gate  * Arguments:
288*0Sstevel@tonic-gate  * 	rqstp		(r) the RPC request
289*0Sstevel@tonic-gate  * 	client_name	(w) pointer to client_name string
290*0Sstevel@tonic-gate  * 	server_name	(w) pointer to server_name string
291*0Sstevel@tonic-gate  *
292*0Sstevel@tonic-gate  * Effects:
293*0Sstevel@tonic-gate  *
294*0Sstevel@tonic-gate  * Unparses the client and server names into client_name and
295*0Sstevel@tonic-gate  * server_name, both of which must be freed by the caller.  Returns 0
296*0Sstevel@tonic-gate  * on success and -1 on failure. On failure client_name and server_name
297*0Sstevel@tonic-gate  * will point to null.
298*0Sstevel@tonic-gate  */
299*0Sstevel@tonic-gate int
300*0Sstevel@tonic-gate setup_gss_names(struct svc_req * rqstp,
301*0Sstevel@tonic-gate     char **client_name, char **server_name)
302*0Sstevel@tonic-gate {
303*0Sstevel@tonic-gate 	OM_uint32 maj_stat, min_stat;
304*0Sstevel@tonic-gate 	rpc_gss_rawcred_t *raw_cred;
305*0Sstevel@tonic-gate 	gss_buffer_desc name_buf;
306*0Sstevel@tonic-gate 	char *tmp, *val;
307*0Sstevel@tonic-gate 	size_t len;
308*0Sstevel@tonic-gate 	gss_name_t name;
309*0Sstevel@tonic-gate 
310*0Sstevel@tonic-gate 	*client_name = NULL;
311*0Sstevel@tonic-gate 
312*0Sstevel@tonic-gate 	rpc_gss_getcred(rqstp, &raw_cred, NULL, NULL);
313*0Sstevel@tonic-gate 
314*0Sstevel@tonic-gate 	/* Return a copy of the service principal from the raw_cred */
315*0Sstevel@tonic-gate 	*server_name = strdup(raw_cred->svc_principal);
316*0Sstevel@tonic-gate 
317*0Sstevel@tonic-gate 	if (*server_name == NULL)
318*0Sstevel@tonic-gate 		return (-1);
319*0Sstevel@tonic-gate 
320*0Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
321*0Sstevel@tonic-gate 		free(*server_name);
322*0Sstevel@tonic-gate 		*server_name = NULL;
323*0Sstevel@tonic-gate 		return (-1);
324*0Sstevel@tonic-gate 	}
325*0Sstevel@tonic-gate 	maj_stat = gss_display_name(&min_stat, name, &name_buf, NULL);
326*0Sstevel@tonic-gate 	if (maj_stat != GSS_S_COMPLETE) {
327*0Sstevel@tonic-gate 		free(*server_name);
328*0Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
329*0Sstevel@tonic-gate 		*server_name = NULL;
330*0Sstevel@tonic-gate 		return (-1);
331*0Sstevel@tonic-gate 	}
332*0Sstevel@tonic-gate 	gss_release_name(&min_stat, &name);
333*0Sstevel@tonic-gate 
334*0Sstevel@tonic-gate 	/*
335*0Sstevel@tonic-gate 	 * Allocate space to copy the client principal. We allocate an
336*0Sstevel@tonic-gate 	 * extra byte to make the string null terminated if we need to.
337*0Sstevel@tonic-gate 	 */
338*0Sstevel@tonic-gate 
339*0Sstevel@tonic-gate 	val = name_buf.value;
340*0Sstevel@tonic-gate 	len = name_buf.length + (val[name_buf.length - 1] != '\0');
341*0Sstevel@tonic-gate 
342*0Sstevel@tonic-gate 	/* len is the length including the null terminating byte. */
343*0Sstevel@tonic-gate 
344*0Sstevel@tonic-gate 	tmp = malloc(len);
345*0Sstevel@tonic-gate 	if (tmp) {
346*0Sstevel@tonic-gate 		memcpy(tmp, val, len - 1);
347*0Sstevel@tonic-gate 		tmp[len - 1] = '\0';
348*0Sstevel@tonic-gate 	} else {
349*0Sstevel@tonic-gate 		free(*server_name);
350*0Sstevel@tonic-gate 		*server_name = NULL;
351*0Sstevel@tonic-gate 	}
352*0Sstevel@tonic-gate 
353*0Sstevel@tonic-gate 	/* Were done with the GSS buffer */
354*0Sstevel@tonic-gate 	(void) gss_release_buffer(&min_stat, &name_buf);
355*0Sstevel@tonic-gate 
356*0Sstevel@tonic-gate 	*client_name = tmp;
357*0Sstevel@tonic-gate 
358*0Sstevel@tonic-gate 	return (tmp ? 0 : -1);
359*0Sstevel@tonic-gate }
360*0Sstevel@tonic-gate 
361*0Sstevel@tonic-gate int
362*0Sstevel@tonic-gate cmp_gss_krb5_name(kadm5_server_handle_t handle,
363*0Sstevel@tonic-gate     gss_name_t gss_name, krb5_principal princ)
364*0Sstevel@tonic-gate {
365*0Sstevel@tonic-gate 	krb5_principal princ2;
366*0Sstevel@tonic-gate 	int stat;
367*0Sstevel@tonic-gate 
368*0Sstevel@tonic-gate 	if (!gss_to_krb5_name(handle, gss_name, &princ2))
369*0Sstevel@tonic-gate 		return (0);
370*0Sstevel@tonic-gate 	stat = krb5_principal_compare(handle->context, princ, princ2);
371*0Sstevel@tonic-gate 	krb5_free_principal(handle->context, princ2);
372*0Sstevel@tonic-gate 	return (stat);
373*0Sstevel@tonic-gate }
374*0Sstevel@tonic-gate 
375*0Sstevel@tonic-gate 
376*0Sstevel@tonic-gate /*
377*0Sstevel@tonic-gate  * This routine primarily validates the username and password
378*0Sstevel@tonic-gate  * of the principal to be created, if a prior acl check for
379*0Sstevel@tonic-gate  * the 'u' privilege succeeds. Validation is done using
380*0Sstevel@tonic-gate  * the PAM `k5migrate' service. k5migrate normally stacks
381*0Sstevel@tonic-gate  * pam_unix_auth.so and pam_unix_account.so in its auth and
382*0Sstevel@tonic-gate  * account stacks respectively.
383*0Sstevel@tonic-gate  *
384*0Sstevel@tonic-gate  * Returns 1 (true), if validation is successful,
385*0Sstevel@tonic-gate  * else returns 0 (false).
386*0Sstevel@tonic-gate  */
387*0Sstevel@tonic-gate int verify_pam_pw(char *userdata, char *pwd) {
388*0Sstevel@tonic-gate 	pam_handle_t *pamh;
389*0Sstevel@tonic-gate 	int err = 0;
390*0Sstevel@tonic-gate 	int result = 1;
391*0Sstevel@tonic-gate 	char *user = NULL;
392*0Sstevel@tonic-gate 	char *ptr = NULL;
393*0Sstevel@tonic-gate 
394*0Sstevel@tonic-gate 	ptr = strchr(userdata, '@');
395*0Sstevel@tonic-gate 	if (ptr != NULL) {
396*0Sstevel@tonic-gate 		user = (char *)malloc(ptr - userdata + 1);
397*0Sstevel@tonic-gate 		(void) strlcpy(user, userdata, (ptr - userdata) + 1);
398*0Sstevel@tonic-gate 	} else {
399*0Sstevel@tonic-gate 		user = (char *)strdup(userdata);
400*0Sstevel@tonic-gate 	}
401*0Sstevel@tonic-gate 
402*0Sstevel@tonic-gate 	err = pam_start("k5migrate", user, NULL, &pamh);
403*0Sstevel@tonic-gate 	if (err != PAM_SUCCESS) {
404*0Sstevel@tonic-gate 		syslog(LOG_ERR, "verify_pam_pw: pam_start() failed, %s\n",
405*0Sstevel@tonic-gate 				pam_strerror(pamh, err));
406*0Sstevel@tonic-gate 		if (user)
407*0Sstevel@tonic-gate 			free(user);
408*0Sstevel@tonic-gate 		return (0);
409*0Sstevel@tonic-gate 	}
410*0Sstevel@tonic-gate 	if (user)
411*0Sstevel@tonic-gate 		free(user);
412*0Sstevel@tonic-gate 
413*0Sstevel@tonic-gate 	err = pam_set_item(pamh, PAM_AUTHTOK, (void *)pwd);
414*0Sstevel@tonic-gate 	if (err != PAM_SUCCESS) {
415*0Sstevel@tonic-gate 		syslog(LOG_ERR, "verify_pam_pw: pam_set_item() failed, %s\n",
416*0Sstevel@tonic-gate 				pam_strerror(pamh, err));
417*0Sstevel@tonic-gate 		(void) pam_end(pamh, err);
418*0Sstevel@tonic-gate 		return (0);
419*0Sstevel@tonic-gate 	}
420*0Sstevel@tonic-gate 
421*0Sstevel@tonic-gate 	err = pam_authenticate(pamh, PAM_SILENT);
422*0Sstevel@tonic-gate 	if (err != PAM_SUCCESS) {
423*0Sstevel@tonic-gate 		syslog(LOG_ERR, "verify_pam_pw: pam_authenticate() "
424*0Sstevel@tonic-gate 				"failed, %s\n", pam_strerror(pamh, err));
425*0Sstevel@tonic-gate 		(void) pam_end(pamh, err);
426*0Sstevel@tonic-gate 		return (0);
427*0Sstevel@tonic-gate 	}
428*0Sstevel@tonic-gate 
429*0Sstevel@tonic-gate 	err = pam_acct_mgmt(pamh, PAM_SILENT);
430*0Sstevel@tonic-gate 	if (err != PAM_SUCCESS) {
431*0Sstevel@tonic-gate 		syslog(LOG_ERR, "verify_pam_pw: pam_acct_mgmt() failed, %s\n",
432*0Sstevel@tonic-gate 				pam_strerror(pamh, err));
433*0Sstevel@tonic-gate 		(void) pam_end(pamh, err);
434*0Sstevel@tonic-gate 		return (0);
435*0Sstevel@tonic-gate 	}
436*0Sstevel@tonic-gate 
437*0Sstevel@tonic-gate 	(void) pam_end(pamh, PAM_SUCCESS);
438*0Sstevel@tonic-gate 	return (result);
439*0Sstevel@tonic-gate }
440*0Sstevel@tonic-gate 
441*0Sstevel@tonic-gate generic_ret *
442*0Sstevel@tonic-gate create_principal_1(cprinc_arg * arg, struct svc_req * rqstp)
443*0Sstevel@tonic-gate {
444*0Sstevel@tonic-gate 	static generic_ret ret;
445*0Sstevel@tonic-gate 	char *prime_arg = NULL;
446*0Sstevel@tonic-gate 	char *client_name = NULL, *service_name = NULL;
447*0Sstevel@tonic-gate 	int policy_migrate = 0;
448*0Sstevel@tonic-gate 
449*0Sstevel@tonic-gate 	OM_uint32 min_stat;
450*0Sstevel@tonic-gate 	kadm5_server_handle_t handle;
451*0Sstevel@tonic-gate 	kadm5_ret_t retval;
452*0Sstevel@tonic-gate 	restriction_t		*rp;
453*0Sstevel@tonic-gate 	gss_name_t name = NULL;
454*0Sstevel@tonic-gate 
455*0Sstevel@tonic-gate 	xdr_free(xdr_generic_ret, (char *) &ret);
456*0Sstevel@tonic-gate 
457*0Sstevel@tonic-gate 	if (ret.code = new_server_handle(arg->api_version, rqstp, &handle))
458*0Sstevel@tonic-gate 		return (&ret);
459*0Sstevel@tonic-gate 
460*0Sstevel@tonic-gate 	if (ret.code = check_handle((void *) handle))
461*0Sstevel@tonic-gate 		goto error;
462*0Sstevel@tonic-gate 	ret.api_version = handle->api_version;
463*0Sstevel@tonic-gate 
464*0Sstevel@tonic-gate 	if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
465*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
466*0Sstevel@tonic-gate 		goto error;
467*0Sstevel@tonic-gate 	}
468*0Sstevel@tonic-gate 	if (krb5_unparse_name(handle->context, arg->rec.principal,
469*0Sstevel@tonic-gate 	    &prime_arg)) {
470*0Sstevel@tonic-gate 		ret.code = KADM5_BAD_PRINCIPAL;
471*0Sstevel@tonic-gate 		goto error;
472*0Sstevel@tonic-gate 	}
473*0Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
474*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
475*0Sstevel@tonic-gate 		goto error;
476*0Sstevel@tonic-gate 	}
477*0Sstevel@tonic-gate 
478*0Sstevel@tonic-gate 	if (acl_check(handle->context, name, ACL_MIGRATE,
479*0Sstevel@tonic-gate 	    arg->rec.principal, &rp) &&
480*0Sstevel@tonic-gate 	    verify_pam_pw(prime_arg, arg->passwd)) {
481*0Sstevel@tonic-gate 		policy_migrate = 1;
482*0Sstevel@tonic-gate 	}
483*0Sstevel@tonic-gate 
484*0Sstevel@tonic-gate 	if (CHANGEPW_SERVICE(rqstp)
485*0Sstevel@tonic-gate 	    || (!acl_check(handle->context, name, ACL_ADD,
486*0Sstevel@tonic-gate 			arg->rec.principal, &rp) &&
487*0Sstevel@tonic-gate 		!(policy_migrate))
488*0Sstevel@tonic-gate 	    || acl_impose_restrictions(handle->context,
489*0Sstevel@tonic-gate 				    &arg->rec, &arg->mask, rp)) {
490*0Sstevel@tonic-gate 		ret.code = KADM5_AUTH_ADD;
491*0Sstevel@tonic-gate 
492*0Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
493*0Sstevel@tonic-gate 				    "kadm5_create_principal",
494*0Sstevel@tonic-gate 				    prime_arg, client_name);
495*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH,
496*0Sstevel@tonic-gate 			"kadm5_create_principal", prime_arg, client_name,
497*0Sstevel@tonic-gate 			service_name, client_addr(rqstp, buf));
498*0Sstevel@tonic-gate 	} else {
499*0Sstevel@tonic-gate 		ret.code = kadm5_create_principal((void *) handle,
500*0Sstevel@tonic-gate 		    &arg->rec, arg->mask,
501*0Sstevel@tonic-gate 		    arg->passwd);
502*0Sstevel@tonic-gate 
503*0Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
504*0Sstevel@tonic-gate 				"kadm5_create_principal",
505*0Sstevel@tonic-gate 				prime_arg, client_name, ret.code);
506*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_create_principal",
507*0Sstevel@tonic-gate 		    prime_arg, ((ret.code == 0) ? "success" :
508*0Sstevel@tonic-gate 			error_message(ret.code)),
509*0Sstevel@tonic-gate 		    client_name, service_name, client_addr(rqstp, buf));
510*0Sstevel@tonic-gate 
511*0Sstevel@tonic-gate 		if (policy_migrate && (ret.code == 0)) {
512*0Sstevel@tonic-gate 			arg->rec.policy = strdup("default");
513*0Sstevel@tonic-gate 			if ((arg->mask & KADM5_PW_EXPIRATION)) {
514*0Sstevel@tonic-gate 				arg->mask = 0;
515*0Sstevel@tonic-gate 				arg->mask |= KADM5_POLICY;
516*0Sstevel@tonic-gate 				arg->mask |= KADM5_PW_EXPIRATION;
517*0Sstevel@tonic-gate 			} else {
518*0Sstevel@tonic-gate 				arg->mask = 0;
519*0Sstevel@tonic-gate 				arg->mask |= KADM5_POLICY;
520*0Sstevel@tonic-gate 			}
521*0Sstevel@tonic-gate 
522*0Sstevel@tonic-gate 			retval = kadm5_modify_principal((void *)handle,
523*0Sstevel@tonic-gate 					&arg->rec, arg->mask);
524*0Sstevel@tonic-gate 			krb5_klog_syslog(LOG_NOTICE, LOG_DONE,
525*0Sstevel@tonic-gate 				"kadm5_modify_principal",
526*0Sstevel@tonic-gate 				prime_arg, ((retval == 0) ? "success" :
527*0Sstevel@tonic-gate 				error_message(retval)), client_name,
528*0Sstevel@tonic-gate 				service_name, client_addr(rqstp, buf));
529*0Sstevel@tonic-gate 		}
530*0Sstevel@tonic-gate 	}
531*0Sstevel@tonic-gate 
532*0Sstevel@tonic-gate error:
533*0Sstevel@tonic-gate 	if (name)
534*0Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
535*0Sstevel@tonic-gate 	free_server_handle(handle);
536*0Sstevel@tonic-gate 	if (prime_arg)
537*0Sstevel@tonic-gate 		free(prime_arg);
538*0Sstevel@tonic-gate 	if (client_name)
539*0Sstevel@tonic-gate 		free(client_name);
540*0Sstevel@tonic-gate 	if (service_name)
541*0Sstevel@tonic-gate 		free(service_name);
542*0Sstevel@tonic-gate 	return (&ret);
543*0Sstevel@tonic-gate }
544*0Sstevel@tonic-gate 
545*0Sstevel@tonic-gate generic_ret *
546*0Sstevel@tonic-gate create_principal3_1(cprinc3_arg *arg, struct svc_req *rqstp)
547*0Sstevel@tonic-gate {
548*0Sstevel@tonic-gate     static generic_ret		ret;
549*0Sstevel@tonic-gate     char			*prime_arg = NULL;
550*0Sstevel@tonic-gate     char			*client_name = NULL, *service_name = NULL;
551*0Sstevel@tonic-gate     int				policy_migrate = 0;
552*0Sstevel@tonic-gate 
553*0Sstevel@tonic-gate     OM_uint32			min_stat;
554*0Sstevel@tonic-gate     kadm5_server_handle_t	handle;
555*0Sstevel@tonic-gate     kadm5_ret_t			retval;
556*0Sstevel@tonic-gate     restriction_t		*rp;
557*0Sstevel@tonic-gate     gss_name_t			name = NULL;
558*0Sstevel@tonic-gate 
559*0Sstevel@tonic-gate     xdr_free(xdr_generic_ret, (char *) &ret);
560*0Sstevel@tonic-gate 
561*0Sstevel@tonic-gate     if (ret.code = new_server_handle(arg->api_version, rqstp, &handle))
562*0Sstevel@tonic-gate 	 return &ret;
563*0Sstevel@tonic-gate 
564*0Sstevel@tonic-gate     if (ret.code = check_handle((void *)handle))
565*0Sstevel@tonic-gate 	goto error;
566*0Sstevel@tonic-gate     ret.api_version = handle->api_version;
567*0Sstevel@tonic-gate 
568*0Sstevel@tonic-gate     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
569*0Sstevel@tonic-gate 	ret.code = KADM5_FAILURE;
570*0Sstevel@tonic-gate 	goto error;
571*0Sstevel@tonic-gate     }
572*0Sstevel@tonic-gate     if (krb5_unparse_name(handle->context, arg->rec.principal, &prime_arg)) {
573*0Sstevel@tonic-gate 	ret.code = KADM5_BAD_PRINCIPAL;
574*0Sstevel@tonic-gate 	goto error;
575*0Sstevel@tonic-gate     }
576*0Sstevel@tonic-gate     if (!(name = get_clnt_name(rqstp))) {
577*0Sstevel@tonic-gate 	ret.code = KADM5_FAILURE;
578*0Sstevel@tonic-gate 	goto error;
579*0Sstevel@tonic-gate     }
580*0Sstevel@tonic-gate 
581*0Sstevel@tonic-gate     if (acl_check(handle->context, name, ACL_MIGRATE,
582*0Sstevel@tonic-gate 		arg->rec.principal, &rp) &&
583*0Sstevel@tonic-gate 		verify_pam_pw(prime_arg, arg->passwd)) {
584*0Sstevel@tonic-gate 	policy_migrate = 1;
585*0Sstevel@tonic-gate     }
586*0Sstevel@tonic-gate 
587*0Sstevel@tonic-gate     if (CHANGEPW_SERVICE(rqstp)
588*0Sstevel@tonic-gate 	|| (!acl_check(handle->context, name, ACL_ADD,
589*0Sstevel@tonic-gate 			arg->rec.principal, &rp) &&
590*0Sstevel@tonic-gate 	    !(policy_migrate))
591*0Sstevel@tonic-gate 	|| acl_impose_restrictions(handle->context,
592*0Sstevel@tonic-gate 				   &arg->rec, &arg->mask, rp)) {
593*0Sstevel@tonic-gate 	 ret.code = KADM5_AUTH_ADD;
594*0Sstevel@tonic-gate 	 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_create_principal",
595*0Sstevel@tonic-gate 			  prime_arg, client_name, service_name,
596*0Sstevel@tonic-gate 			  client_addr(rqstp, buf));
597*0Sstevel@tonic-gate     } else {
598*0Sstevel@tonic-gate 	 ret.code = kadm5_create_principal_3((void *)handle,
599*0Sstevel@tonic-gate 					     &arg->rec, arg->mask,
600*0Sstevel@tonic-gate 					     arg->n_ks_tuple,
601*0Sstevel@tonic-gate 					     arg->ks_tuple,
602*0Sstevel@tonic-gate 					     arg->passwd);
603*0Sstevel@tonic-gate 	 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_create_principal",
604*0Sstevel@tonic-gate 			  prime_arg,((ret.code == 0) ? "success" :
605*0Sstevel@tonic-gate 			   error_message(ret.code)),
606*0Sstevel@tonic-gate 			  client_name, service_name,
607*0Sstevel@tonic-gate 			  client_addr(rqstp, buf));
608*0Sstevel@tonic-gate 
609*0Sstevel@tonic-gate 	 if (policy_migrate && (ret.code == 0)) {
610*0Sstevel@tonic-gate 	 	arg->rec.policy = strdup("default");
611*0Sstevel@tonic-gate 	 	if ((arg->mask & KADM5_PW_EXPIRATION)) {
612*0Sstevel@tonic-gate 	 		arg->mask = 0;
613*0Sstevel@tonic-gate 	 		arg->mask |= KADM5_POLICY;
614*0Sstevel@tonic-gate 	 		arg->mask |= KADM5_PW_EXPIRATION;
615*0Sstevel@tonic-gate 	 	} else {
616*0Sstevel@tonic-gate 	 		arg->mask = 0;
617*0Sstevel@tonic-gate 	 		arg->mask |= KADM5_POLICY;
618*0Sstevel@tonic-gate 	 	}
619*0Sstevel@tonic-gate 
620*0Sstevel@tonic-gate 		retval = kadm5_modify_principal((void *)handle,
621*0Sstevel@tonic-gate 					   &arg->rec, arg->mask);
622*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_DONE,
623*0Sstevel@tonic-gate 			    "kadm5_modify_principal",
624*0Sstevel@tonic-gate 			    prime_arg, ((retval == 0) ? "success" :
625*0Sstevel@tonic-gate 					error_message(retval)), client_name,
626*0Sstevel@tonic-gate 			    service_name, client_addr(rqstp, buf));
627*0Sstevel@tonic-gate 	 }
628*0Sstevel@tonic-gate     }
629*0Sstevel@tonic-gate 
630*0Sstevel@tonic-gate error:
631*0Sstevel@tonic-gate     if (name)
632*0Sstevel@tonic-gate     	gss_release_name(&min_stat, &name);
633*0Sstevel@tonic-gate     free_server_handle(handle);
634*0Sstevel@tonic-gate     if (client_name)
635*0Sstevel@tonic-gate 	free(client_name);
636*0Sstevel@tonic-gate     if (service_name)
637*0Sstevel@tonic-gate 	free(service_name);
638*0Sstevel@tonic-gate     if (prime_arg)
639*0Sstevel@tonic-gate 	free(prime_arg);
640*0Sstevel@tonic-gate     return (&ret);
641*0Sstevel@tonic-gate }
642*0Sstevel@tonic-gate 
643*0Sstevel@tonic-gate generic_ret *
644*0Sstevel@tonic-gate delete_principal_1(dprinc_arg * arg, struct svc_req * rqstp)
645*0Sstevel@tonic-gate {
646*0Sstevel@tonic-gate 	static generic_ret ret;
647*0Sstevel@tonic-gate 	char *prime_arg = NULL;
648*0Sstevel@tonic-gate 	char *client_name = NULL, *service_name = NULL;
649*0Sstevel@tonic-gate 	OM_uint32 min_stat;
650*0Sstevel@tonic-gate 	kadm5_server_handle_t handle;
651*0Sstevel@tonic-gate 	gss_name_t name = NULL;
652*0Sstevel@tonic-gate 
653*0Sstevel@tonic-gate 	xdr_free(xdr_generic_ret, (char *) &ret);
654*0Sstevel@tonic-gate 
655*0Sstevel@tonic-gate 	if (ret.code = new_server_handle(arg->api_version, rqstp, &handle))
656*0Sstevel@tonic-gate 		return (&ret);
657*0Sstevel@tonic-gate 
658*0Sstevel@tonic-gate 	if (ret.code = check_handle((void *) handle))
659*0Sstevel@tonic-gate 		goto error;
660*0Sstevel@tonic-gate 	ret.api_version = handle->api_version;
661*0Sstevel@tonic-gate 
662*0Sstevel@tonic-gate 	if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
663*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
664*0Sstevel@tonic-gate 		goto error;
665*0Sstevel@tonic-gate 	}
666*0Sstevel@tonic-gate 	if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
667*0Sstevel@tonic-gate 		ret.code = KADM5_BAD_PRINCIPAL;
668*0Sstevel@tonic-gate 		goto error;
669*0Sstevel@tonic-gate 	}
670*0Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
671*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
672*0Sstevel@tonic-gate 		goto error;
673*0Sstevel@tonic-gate 	}
674*0Sstevel@tonic-gate 
675*0Sstevel@tonic-gate 	if (CHANGEPW_SERVICE(rqstp)
676*0Sstevel@tonic-gate 	    || !acl_check(handle->context, name, ACL_DELETE,
677*0Sstevel@tonic-gate 			arg->princ, NULL)) {
678*0Sstevel@tonic-gate 		ret.code = KADM5_AUTH_DELETE;
679*0Sstevel@tonic-gate 
680*0Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
681*0Sstevel@tonic-gate 				    "kadm5_delete_principal",
682*0Sstevel@tonic-gate 				    prime_arg, client_name);
683*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH,
684*0Sstevel@tonic-gate 			"kadm5_delete_principal", prime_arg, client_name,
685*0Sstevel@tonic-gate 			service_name, client_addr(rqstp, buf));
686*0Sstevel@tonic-gate 	} else {
687*0Sstevel@tonic-gate 		ret.code = kadm5_delete_principal((void *) handle, arg->princ);
688*0Sstevel@tonic-gate 
689*0Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
690*0Sstevel@tonic-gate 				"kadm5_delete_principal",
691*0Sstevel@tonic-gate 				prime_arg, client_name, ret.code);
692*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_DONE,
693*0Sstevel@tonic-gate 		    "kadm5_delete_principal", prime_arg,
694*0Sstevel@tonic-gate 		    ((ret.code == 0) ? "success" : error_message(ret.code)),
695*0Sstevel@tonic-gate 		    client_name, service_name, client_addr(rqstp, buf));
696*0Sstevel@tonic-gate 	}
697*0Sstevel@tonic-gate 
698*0Sstevel@tonic-gate error:
699*0Sstevel@tonic-gate 	if (name)
700*0Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
701*0Sstevel@tonic-gate 	if (prime_arg)
702*0Sstevel@tonic-gate 		free(prime_arg);
703*0Sstevel@tonic-gate 	free_server_handle(handle);
704*0Sstevel@tonic-gate 	if (client_name)
705*0Sstevel@tonic-gate 		free(client_name);
706*0Sstevel@tonic-gate 	if (service_name)
707*0Sstevel@tonic-gate 		free(service_name);
708*0Sstevel@tonic-gate 	return (&ret);
709*0Sstevel@tonic-gate }
710*0Sstevel@tonic-gate 
711*0Sstevel@tonic-gate generic_ret *
712*0Sstevel@tonic-gate modify_principal_1(mprinc_arg * arg, struct svc_req * rqstp)
713*0Sstevel@tonic-gate {
714*0Sstevel@tonic-gate 	static generic_ret ret;
715*0Sstevel@tonic-gate 	char *prime_arg = NULL;
716*0Sstevel@tonic-gate 	char *client_name = NULL, *service_name = NULL;
717*0Sstevel@tonic-gate 	OM_uint32 min_stat;
718*0Sstevel@tonic-gate 	kadm5_server_handle_t handle;
719*0Sstevel@tonic-gate 	restriction_t *rp;
720*0Sstevel@tonic-gate 	gss_name_t name = NULL;
721*0Sstevel@tonic-gate 
722*0Sstevel@tonic-gate 	xdr_free(xdr_generic_ret, (char *) &ret);
723*0Sstevel@tonic-gate 
724*0Sstevel@tonic-gate 	if (ret.code = new_server_handle(arg->api_version, rqstp, &handle))
725*0Sstevel@tonic-gate 		return (&ret);
726*0Sstevel@tonic-gate 
727*0Sstevel@tonic-gate 	if (ret.code = check_handle((void *) handle))
728*0Sstevel@tonic-gate 		goto error;
729*0Sstevel@tonic-gate 	if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
730*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
731*0Sstevel@tonic-gate 		goto error;
732*0Sstevel@tonic-gate 	}
733*0Sstevel@tonic-gate 	if (krb5_unparse_name(handle->context, arg->rec.principal,
734*0Sstevel@tonic-gate 	    &prime_arg)) {
735*0Sstevel@tonic-gate 		ret.code = KADM5_BAD_PRINCIPAL;
736*0Sstevel@tonic-gate 		goto error;
737*0Sstevel@tonic-gate 	}
738*0Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
739*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
740*0Sstevel@tonic-gate 		goto error;
741*0Sstevel@tonic-gate 	}
742*0Sstevel@tonic-gate 
743*0Sstevel@tonic-gate 	if (CHANGEPW_SERVICE(rqstp)
744*0Sstevel@tonic-gate 	    || !acl_check(handle->context, name, ACL_MODIFY,
745*0Sstevel@tonic-gate 			arg->rec.principal, &rp)
746*0Sstevel@tonic-gate 	    || acl_impose_restrictions(handle->context,
747*0Sstevel@tonic-gate 				    &arg->rec, &arg->mask, rp)) {
748*0Sstevel@tonic-gate 		ret.code = KADM5_AUTH_MODIFY;
749*0Sstevel@tonic-gate 
750*0Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
751*0Sstevel@tonic-gate 				    "kadm5_modify_principal",
752*0Sstevel@tonic-gate 				    prime_arg, client_name);
753*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH,
754*0Sstevel@tonic-gate 		    "kadm5_modify_principal", prime_arg, client_name,
755*0Sstevel@tonic-gate 		    service_name, client_addr(rqstp, buf));
756*0Sstevel@tonic-gate 	} else {
757*0Sstevel@tonic-gate 		ret.code = kadm5_modify_principal((void *) handle, &arg->rec,
758*0Sstevel@tonic-gate 		    arg->mask);
759*0Sstevel@tonic-gate 
760*0Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
761*0Sstevel@tonic-gate 				"kadm5_modify_principal",
762*0Sstevel@tonic-gate 				prime_arg, client_name, ret.code);
763*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_modify_principal",
764*0Sstevel@tonic-gate 		    prime_arg, ((ret.code == 0) ? "success" :
765*0Sstevel@tonic-gate 			error_message(ret.code)),
766*0Sstevel@tonic-gate 		    client_name, service_name, client_addr(rqstp, buf));
767*0Sstevel@tonic-gate 	}
768*0Sstevel@tonic-gate 
769*0Sstevel@tonic-gate error:
770*0Sstevel@tonic-gate 	if (name)
771*0Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
772*0Sstevel@tonic-gate 	free_server_handle(handle);
773*0Sstevel@tonic-gate 	if (prime_arg)
774*0Sstevel@tonic-gate 		free(prime_arg);
775*0Sstevel@tonic-gate 	if (client_name)
776*0Sstevel@tonic-gate 		free(client_name);
777*0Sstevel@tonic-gate 	if (service_name)
778*0Sstevel@tonic-gate 		free(service_name);
779*0Sstevel@tonic-gate 	return (&ret);
780*0Sstevel@tonic-gate }
781*0Sstevel@tonic-gate 
782*0Sstevel@tonic-gate generic_ret *
783*0Sstevel@tonic-gate rename_principal_1(rprinc_arg * arg, struct svc_req * rqstp)
784*0Sstevel@tonic-gate {
785*0Sstevel@tonic-gate 	static generic_ret ret;
786*0Sstevel@tonic-gate 	char *prime_arg1 = NULL, *prime_arg2 = NULL;
787*0Sstevel@tonic-gate 	char prime_arg[BUFSIZ];
788*0Sstevel@tonic-gate 	char *client_name = NULL, *service_name = NULL;
789*0Sstevel@tonic-gate 	OM_uint32 min_stat;
790*0Sstevel@tonic-gate 	kadm5_server_handle_t handle;
791*0Sstevel@tonic-gate 	restriction_t *rp;
792*0Sstevel@tonic-gate 	gss_name_t name = NULL;
793*0Sstevel@tonic-gate 
794*0Sstevel@tonic-gate 	xdr_free(xdr_generic_ret, (char *) &ret);
795*0Sstevel@tonic-gate 
796*0Sstevel@tonic-gate 	if (ret.code = new_server_handle(arg->api_version, rqstp, &handle))
797*0Sstevel@tonic-gate 		return (&ret);
798*0Sstevel@tonic-gate 
799*0Sstevel@tonic-gate 	if (ret.code = check_handle((void *) handle))
800*0Sstevel@tonic-gate 		goto error;
801*0Sstevel@tonic-gate 	if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
802*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
803*0Sstevel@tonic-gate 		goto error;
804*0Sstevel@tonic-gate 	}
805*0Sstevel@tonic-gate 	if (krb5_unparse_name(handle->context, arg->src, &prime_arg1)) {
806*0Sstevel@tonic-gate 		ret.code = KADM5_BAD_PRINCIPAL;
807*0Sstevel@tonic-gate 		goto error;
808*0Sstevel@tonic-gate 	}
809*0Sstevel@tonic-gate 	if (krb5_unparse_name(handle->context, arg->dest, &prime_arg2)) {
810*0Sstevel@tonic-gate 		ret.code = KADM5_BAD_PRINCIPAL;
811*0Sstevel@tonic-gate 		goto error;
812*0Sstevel@tonic-gate 	}
813*0Sstevel@tonic-gate 	sprintf(prime_arg, "%s to %s", prime_arg1, prime_arg2);
814*0Sstevel@tonic-gate 	ret.code = KADM5_OK;
815*0Sstevel@tonic-gate 
816*0Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
817*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
818*0Sstevel@tonic-gate 		goto error;
819*0Sstevel@tonic-gate 	}
820*0Sstevel@tonic-gate 
821*0Sstevel@tonic-gate 	if (!CHANGEPW_SERVICE(rqstp)) {
822*0Sstevel@tonic-gate 		if (!acl_check(handle->context, name,
823*0Sstevel@tonic-gate 			    ACL_DELETE, arg->src, NULL))
824*0Sstevel@tonic-gate 			ret.code = KADM5_AUTH_DELETE;
825*0Sstevel@tonic-gate 		/* any restrictions at all on the ADD kills the RENAME */
826*0Sstevel@tonic-gate 		if (!acl_check(handle->context, name,
827*0Sstevel@tonic-gate 			    ACL_ADD, arg->dest, &rp)) {
828*0Sstevel@tonic-gate 			if (ret.code == KADM5_AUTH_DELETE)
829*0Sstevel@tonic-gate 				ret.code = KADM5_AUTH_INSUFFICIENT;
830*0Sstevel@tonic-gate 			else
831*0Sstevel@tonic-gate 				ret.code = KADM5_AUTH_ADD;
832*0Sstevel@tonic-gate 		}
833*0Sstevel@tonic-gate 	} else
834*0Sstevel@tonic-gate 		ret.code = KADM5_AUTH_INSUFFICIENT;
835*0Sstevel@tonic-gate 
836*0Sstevel@tonic-gate 	if (ret.code != KADM5_OK) {
837*0Sstevel@tonic-gate 
838*0Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
839*0Sstevel@tonic-gate 				    "kadm5_rename_principal",
840*0Sstevel@tonic-gate 				    prime_arg, client_name);
841*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH,
842*0Sstevel@tonic-gate 			"kadm5_rename_principal", prime_arg, client_name,
843*0Sstevel@tonic-gate 		    service_name, client_addr(rqstp, buf));
844*0Sstevel@tonic-gate 	} else {
845*0Sstevel@tonic-gate 		ret.code = kadm5_rename_principal((void *) handle, arg->src,
846*0Sstevel@tonic-gate 		    arg->dest);
847*0Sstevel@tonic-gate 
848*0Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
849*0Sstevel@tonic-gate 				"kadm5_rename_principal",
850*0Sstevel@tonic-gate 				prime_arg, client_name, ret.code);
851*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_rename_principal",
852*0Sstevel@tonic-gate 		    prime_arg, ((ret.code == 0) ? "success" :
853*0Sstevel@tonic-gate 			error_message(ret.code)),
854*0Sstevel@tonic-gate 		    client_name, service_name, client_addr(rqstp, buf));
855*0Sstevel@tonic-gate 	}
856*0Sstevel@tonic-gate 
857*0Sstevel@tonic-gate error:
858*0Sstevel@tonic-gate 	if (name)
859*0Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
860*0Sstevel@tonic-gate 	free_server_handle(handle);
861*0Sstevel@tonic-gate 	if (prime_arg1)
862*0Sstevel@tonic-gate 		free(prime_arg1);
863*0Sstevel@tonic-gate 	if (prime_arg2)
864*0Sstevel@tonic-gate 		free(prime_arg2);
865*0Sstevel@tonic-gate 	if (client_name)
866*0Sstevel@tonic-gate 		free(client_name);
867*0Sstevel@tonic-gate 	if (service_name)
868*0Sstevel@tonic-gate 		free(service_name);
869*0Sstevel@tonic-gate 	return (&ret);
870*0Sstevel@tonic-gate }
871*0Sstevel@tonic-gate 
872*0Sstevel@tonic-gate gprinc_ret *
873*0Sstevel@tonic-gate get_principal_1(gprinc_arg * arg, struct svc_req * rqstp)
874*0Sstevel@tonic-gate {
875*0Sstevel@tonic-gate 	static gprinc_ret ret;
876*0Sstevel@tonic-gate 	kadm5_principal_ent_t_v1 e;
877*0Sstevel@tonic-gate 	char *prime_arg = NULL, *funcname;
878*0Sstevel@tonic-gate 	char *client_name = NULL, *service_name = NULL;
879*0Sstevel@tonic-gate 	OM_uint32 min_stat;
880*0Sstevel@tonic-gate 	kadm5_server_handle_t handle;
881*0Sstevel@tonic-gate 	gss_name_t name = NULL;
882*0Sstevel@tonic-gate 
883*0Sstevel@tonic-gate 	xdr_free(xdr_gprinc_ret, (char *) &ret);
884*0Sstevel@tonic-gate 
885*0Sstevel@tonic-gate 	if (ret.code = new_server_handle(arg->api_version, rqstp, &handle))
886*0Sstevel@tonic-gate 		return (&ret);
887*0Sstevel@tonic-gate 
888*0Sstevel@tonic-gate 	if (ret.code = check_handle((void *) handle))
889*0Sstevel@tonic-gate 		goto error;
890*0Sstevel@tonic-gate 	ret.api_version = handle->api_version;
891*0Sstevel@tonic-gate 
892*0Sstevel@tonic-gate 	funcname = handle->api_version == KADM5_API_VERSION_1 ?
893*0Sstevel@tonic-gate 	    "kadm5_get_principal (V1)" : "kadm5_get_principal";
894*0Sstevel@tonic-gate 
895*0Sstevel@tonic-gate 	if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
896*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
897*0Sstevel@tonic-gate 		goto error;
898*0Sstevel@tonic-gate 	}
899*0Sstevel@tonic-gate 	if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
900*0Sstevel@tonic-gate 		ret.code = KADM5_BAD_PRINCIPAL;
901*0Sstevel@tonic-gate 		goto error;
902*0Sstevel@tonic-gate 	}
903*0Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
904*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
905*0Sstevel@tonic-gate 		goto error;
906*0Sstevel@tonic-gate 	}
907*0Sstevel@tonic-gate 
908*0Sstevel@tonic-gate 	if (!cmp_gss_krb5_name(handle, name, arg->princ) &&
909*0Sstevel@tonic-gate 	    (CHANGEPW_SERVICE(rqstp) || !acl_check(handle->context,
910*0Sstevel@tonic-gate 						name,
911*0Sstevel@tonic-gate 						ACL_INQUIRE,
912*0Sstevel@tonic-gate 						arg->princ,
913*0Sstevel@tonic-gate 						NULL))) {
914*0Sstevel@tonic-gate 		ret.code = KADM5_AUTH_GET;
915*0Sstevel@tonic-gate 
916*0Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
917*0Sstevel@tonic-gate 				    funcname,
918*0Sstevel@tonic-gate 				    prime_arg, client_name);
919*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, funcname,
920*0Sstevel@tonic-gate 		    prime_arg, client_name, service_name,
921*0Sstevel@tonic-gate 		    client_addr(rqstp, buf));
922*0Sstevel@tonic-gate 	} else {
923*0Sstevel@tonic-gate 		if (handle->api_version == KADM5_API_VERSION_1) {
924*0Sstevel@tonic-gate 			ret.code = kadm5_get_principal_v1((void *) handle,
925*0Sstevel@tonic-gate 			    arg->princ, &e);
926*0Sstevel@tonic-gate 			if (ret.code == KADM5_OK) {
927*0Sstevel@tonic-gate 				memcpy(&ret.rec, e,
928*0Sstevel@tonic-gate 					sizeof (kadm5_principal_ent_rec_v1));
929*0Sstevel@tonic-gate 				free(e);
930*0Sstevel@tonic-gate 			}
931*0Sstevel@tonic-gate 		} else {
932*0Sstevel@tonic-gate 			ret.code = kadm5_get_principal((void *) handle,
933*0Sstevel@tonic-gate 			    arg->princ, &ret.rec,
934*0Sstevel@tonic-gate 			    arg->mask);
935*0Sstevel@tonic-gate 		}
936*0Sstevel@tonic-gate 
937*0Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
938*0Sstevel@tonic-gate 				funcname,
939*0Sstevel@tonic-gate 				prime_arg, client_name, ret.code);
940*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_DONE, funcname,
941*0Sstevel@tonic-gate 		    prime_arg,
942*0Sstevel@tonic-gate 		    ((ret.code == 0) ? "success" : error_message(ret.code)),
943*0Sstevel@tonic-gate 		    client_name, service_name, client_addr(rqstp, buf));
944*0Sstevel@tonic-gate 	}
945*0Sstevel@tonic-gate 
946*0Sstevel@tonic-gate error:
947*0Sstevel@tonic-gate 	if (name)
948*0Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
949*0Sstevel@tonic-gate 	free_server_handle(handle);
950*0Sstevel@tonic-gate 	if (prime_arg)
951*0Sstevel@tonic-gate 		free(prime_arg);
952*0Sstevel@tonic-gate 	if (client_name)
953*0Sstevel@tonic-gate 		free(client_name);
954*0Sstevel@tonic-gate 	if (service_name)
955*0Sstevel@tonic-gate 		free(service_name);
956*0Sstevel@tonic-gate 	return (&ret);
957*0Sstevel@tonic-gate }
958*0Sstevel@tonic-gate 
959*0Sstevel@tonic-gate gprincs_ret *
960*0Sstevel@tonic-gate get_princs_1(gprincs_arg * arg, struct svc_req * rqstp)
961*0Sstevel@tonic-gate {
962*0Sstevel@tonic-gate 	static gprincs_ret ret;
963*0Sstevel@tonic-gate 	char *prime_arg = NULL;
964*0Sstevel@tonic-gate 	char *client_name = NULL, *service_name = NULL;
965*0Sstevel@tonic-gate 	OM_uint32 min_stat;
966*0Sstevel@tonic-gate 	kadm5_server_handle_t handle;
967*0Sstevel@tonic-gate 	gss_name_t name = NULL;
968*0Sstevel@tonic-gate 
969*0Sstevel@tonic-gate 	xdr_free(xdr_gprincs_ret, (char *) &ret);
970*0Sstevel@tonic-gate 
971*0Sstevel@tonic-gate 	if (ret.code = new_server_handle(arg->api_version, rqstp, &handle))
972*0Sstevel@tonic-gate 		return (&ret);
973*0Sstevel@tonic-gate 
974*0Sstevel@tonic-gate 	if (ret.code = check_handle((void *) handle))
975*0Sstevel@tonic-gate 		goto error;
976*0Sstevel@tonic-gate 	ret.api_version = handle->api_version;
977*0Sstevel@tonic-gate 
978*0Sstevel@tonic-gate 	if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
979*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
980*0Sstevel@tonic-gate 		goto error;
981*0Sstevel@tonic-gate 	}
982*0Sstevel@tonic-gate 	prime_arg = arg->exp;
983*0Sstevel@tonic-gate 	if (prime_arg == NULL)
984*0Sstevel@tonic-gate 		prime_arg = "*";
985*0Sstevel@tonic-gate 
986*0Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
987*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
988*0Sstevel@tonic-gate 		goto error;
989*0Sstevel@tonic-gate 	}
990*0Sstevel@tonic-gate 
991*0Sstevel@tonic-gate 	if (CHANGEPW_SERVICE(rqstp) || !acl_check(handle->context,
992*0Sstevel@tonic-gate 						name,
993*0Sstevel@tonic-gate 						ACL_LIST,
994*0Sstevel@tonic-gate 						NULL,
995*0Sstevel@tonic-gate 						NULL)) {
996*0Sstevel@tonic-gate 		ret.code = KADM5_AUTH_LIST;
997*0Sstevel@tonic-gate 
998*0Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
999*0Sstevel@tonic-gate 				    "kadm5_get_principals",
1000*0Sstevel@tonic-gate 				    prime_arg, client_name);
1001*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_get_principals",
1002*0Sstevel@tonic-gate 		    prime_arg, client_name,
1003*0Sstevel@tonic-gate 		    service_name, client_addr(rqstp, buf));
1004*0Sstevel@tonic-gate 	} else {
1005*0Sstevel@tonic-gate 		ret.code = kadm5_get_principals((void *) handle,
1006*0Sstevel@tonic-gate 		    arg->exp, &ret.princs,
1007*0Sstevel@tonic-gate 		    &ret.count);
1008*0Sstevel@tonic-gate 
1009*0Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1010*0Sstevel@tonic-gate 				"kadm5_get_principals",
1011*0Sstevel@tonic-gate 				prime_arg, client_name, ret.code);
1012*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_get_principals",
1013*0Sstevel@tonic-gate 		    prime_arg,
1014*0Sstevel@tonic-gate 		    ((ret.code == 0) ? "success" : error_message(ret.code)),
1015*0Sstevel@tonic-gate 		    client_name, service_name, client_addr(rqstp, buf));
1016*0Sstevel@tonic-gate 	}
1017*0Sstevel@tonic-gate 
1018*0Sstevel@tonic-gate error:
1019*0Sstevel@tonic-gate 	if (name)
1020*0Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
1021*0Sstevel@tonic-gate 	free_server_handle(handle);
1022*0Sstevel@tonic-gate 	if (client_name)
1023*0Sstevel@tonic-gate 		free(client_name);
1024*0Sstevel@tonic-gate 	if (service_name)
1025*0Sstevel@tonic-gate 		free(service_name);
1026*0Sstevel@tonic-gate 	return (&ret);
1027*0Sstevel@tonic-gate }
1028*0Sstevel@tonic-gate 
1029*0Sstevel@tonic-gate generic_ret *
1030*0Sstevel@tonic-gate chpass_principal_1(chpass_arg * arg, struct svc_req * rqstp)
1031*0Sstevel@tonic-gate {
1032*0Sstevel@tonic-gate 	static generic_ret ret;
1033*0Sstevel@tonic-gate 	char *prime_arg = NULL;
1034*0Sstevel@tonic-gate 	char *client_name = NULL, *service_name = NULL;
1035*0Sstevel@tonic-gate 	OM_uint32 min_stat;
1036*0Sstevel@tonic-gate 	kadm5_server_handle_t handle;
1037*0Sstevel@tonic-gate 	gss_name_t name = NULL;
1038*0Sstevel@tonic-gate 
1039*0Sstevel@tonic-gate 	xdr_free(xdr_generic_ret, (char *) &ret);
1040*0Sstevel@tonic-gate 
1041*0Sstevel@tonic-gate 	if (ret.code = new_server_handle(arg->api_version, rqstp, &handle))
1042*0Sstevel@tonic-gate 		return (&ret);
1043*0Sstevel@tonic-gate 
1044*0Sstevel@tonic-gate 	if (ret.code = check_handle((void *) handle))
1045*0Sstevel@tonic-gate 		goto error;
1046*0Sstevel@tonic-gate 	ret.api_version = handle->api_version;
1047*0Sstevel@tonic-gate 
1048*0Sstevel@tonic-gate 	if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1049*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
1050*0Sstevel@tonic-gate 		goto error;
1051*0Sstevel@tonic-gate 	}
1052*0Sstevel@tonic-gate 	if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
1053*0Sstevel@tonic-gate 		ret.code = KADM5_BAD_PRINCIPAL;
1054*0Sstevel@tonic-gate 		goto error;
1055*0Sstevel@tonic-gate 	}
1056*0Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
1057*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
1058*0Sstevel@tonic-gate 		goto error;
1059*0Sstevel@tonic-gate 	}
1060*0Sstevel@tonic-gate 
1061*0Sstevel@tonic-gate 	if (cmp_gss_krb5_name(handle, name, arg->princ)) {
1062*0Sstevel@tonic-gate 		ret.code = chpass_principal_wrapper((void *) handle, arg->princ,
1063*0Sstevel@tonic-gate 		    arg->pass);
1064*0Sstevel@tonic-gate 	} else if (!(CHANGEPW_SERVICE(rqstp)) &&
1065*0Sstevel@tonic-gate 		    acl_check(handle->context, name,
1066*0Sstevel@tonic-gate 			    ACL_CHANGEPW, arg->princ, NULL)) {
1067*0Sstevel@tonic-gate 		ret.code = kadm5_chpass_principal((void *) handle, arg->princ,
1068*0Sstevel@tonic-gate 		    arg->pass);
1069*0Sstevel@tonic-gate 	} else {
1070*0Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
1071*0Sstevel@tonic-gate 				    "kadm5_chpass_principal",
1072*0Sstevel@tonic-gate 				    prime_arg, client_name);
1073*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH,
1074*0Sstevel@tonic-gate 		    "kadm5_chpass_principal", prime_arg, client_name,
1075*0Sstevel@tonic-gate 		    service_name, client_addr(rqstp, buf));
1076*0Sstevel@tonic-gate 		ret.code = KADM5_AUTH_CHANGEPW;
1077*0Sstevel@tonic-gate 	}
1078*0Sstevel@tonic-gate 
1079*0Sstevel@tonic-gate 	if (ret.code != KADM5_AUTH_CHANGEPW) {
1080*0Sstevel@tonic-gate 
1081*0Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1082*0Sstevel@tonic-gate 				"kadm5_chpass_principal",
1083*0Sstevel@tonic-gate 				prime_arg, client_name, ret.code);
1084*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_chpass_principal",
1085*0Sstevel@tonic-gate 		    prime_arg, ((ret.code == 0) ? "success" :
1086*0Sstevel@tonic-gate 			error_message(ret.code)),
1087*0Sstevel@tonic-gate 		    client_name, service_name, client_addr(rqstp, buf));
1088*0Sstevel@tonic-gate 	}
1089*0Sstevel@tonic-gate 
1090*0Sstevel@tonic-gate error:
1091*0Sstevel@tonic-gate 	if (name)
1092*0Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
1093*0Sstevel@tonic-gate 	free_server_handle(handle);
1094*0Sstevel@tonic-gate 	if (prime_arg)
1095*0Sstevel@tonic-gate 		free(prime_arg);
1096*0Sstevel@tonic-gate 	if (client_name)
1097*0Sstevel@tonic-gate 		free(client_name);
1098*0Sstevel@tonic-gate 	if (service_name)
1099*0Sstevel@tonic-gate 		free(service_name);
1100*0Sstevel@tonic-gate 	return (&ret);
1101*0Sstevel@tonic-gate }
1102*0Sstevel@tonic-gate 
1103*0Sstevel@tonic-gate generic_ret *
1104*0Sstevel@tonic-gate chpass_principal3_1(chpass3_arg *arg, struct svc_req *rqstp)
1105*0Sstevel@tonic-gate {
1106*0Sstevel@tonic-gate     static generic_ret		    ret;
1107*0Sstevel@tonic-gate     char			    *prime_arg = NULL;
1108*0Sstevel@tonic-gate     char       			    *client_name = NULL,
1109*0Sstevel@tonic-gate 				    *service_name = NULL;
1110*0Sstevel@tonic-gate     OM_uint32			    min_stat;
1111*0Sstevel@tonic-gate     kadm5_server_handle_t	    handle;
1112*0Sstevel@tonic-gate     gss_name_t name = NULL;
1113*0Sstevel@tonic-gate 
1114*0Sstevel@tonic-gate     xdr_free(xdr_generic_ret, (char *) &ret);
1115*0Sstevel@tonic-gate 
1116*0Sstevel@tonic-gate     if (ret.code = new_server_handle(arg->api_version, rqstp, &handle))
1117*0Sstevel@tonic-gate 	 return &ret;
1118*0Sstevel@tonic-gate 
1119*0Sstevel@tonic-gate     if (ret.code = check_handle((void *)handle))
1120*0Sstevel@tonic-gate 	goto error;
1121*0Sstevel@tonic-gate     ret.api_version = handle->api_version;
1122*0Sstevel@tonic-gate 
1123*0Sstevel@tonic-gate     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1124*0Sstevel@tonic-gate 	ret.code = KADM5_FAILURE;
1125*0Sstevel@tonic-gate 	goto error;
1126*0Sstevel@tonic-gate     }
1127*0Sstevel@tonic-gate     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
1128*0Sstevel@tonic-gate 	ret.code = KADM5_BAD_PRINCIPAL;
1129*0Sstevel@tonic-gate 	goto error;
1130*0Sstevel@tonic-gate     }
1131*0Sstevel@tonic-gate     if (!(name = get_clnt_name(rqstp))) {
1132*0Sstevel@tonic-gate 	ret.code = KADM5_FAILURE;
1133*0Sstevel@tonic-gate 	goto error;
1134*0Sstevel@tonic-gate     }
1135*0Sstevel@tonic-gate 
1136*0Sstevel@tonic-gate     if (cmp_gss_krb5_name(handle, name, arg->princ)) {
1137*0Sstevel@tonic-gate 	 ret.code = chpass_principal_wrapper((void *)handle, arg->princ,
1138*0Sstevel@tonic-gate 					     arg->pass);
1139*0Sstevel@tonic-gate     } else if (!(CHANGEPW_SERVICE(rqstp)) &&
1140*0Sstevel@tonic-gate 	       acl_check(handle->context, name,
1141*0Sstevel@tonic-gate 			 ACL_CHANGEPW, arg->princ, NULL)) {
1142*0Sstevel@tonic-gate 	 ret.code = kadm5_chpass_principal_3((void *)handle, arg->princ,
1143*0Sstevel@tonic-gate 					     arg->keepold,
1144*0Sstevel@tonic-gate 					     arg->n_ks_tuple,
1145*0Sstevel@tonic-gate 					     arg->ks_tuple,
1146*0Sstevel@tonic-gate 					     arg->pass);
1147*0Sstevel@tonic-gate     } else {
1148*0Sstevel@tonic-gate 	 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_chpass_principal",
1149*0Sstevel@tonic-gate 			  prime_arg, client_name, service_name,
1150*0Sstevel@tonic-gate 			  client_addr(rqstp, buf));
1151*0Sstevel@tonic-gate 	 ret.code = KADM5_AUTH_CHANGEPW;
1152*0Sstevel@tonic-gate     }
1153*0Sstevel@tonic-gate 
1154*0Sstevel@tonic-gate     if(ret.code != KADM5_AUTH_CHANGEPW) {
1155*0Sstevel@tonic-gate 	krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_chpass_principal",
1156*0Sstevel@tonic-gate 			prime_arg, ((ret.code == 0) ? "success" :
1157*0Sstevel@tonic-gate 				    error_message(ret.code)),
1158*0Sstevel@tonic-gate 			client_name, service_name,
1159*0Sstevel@tonic-gate 			client_addr(rqstp, buf));
1160*0Sstevel@tonic-gate     }
1161*0Sstevel@tonic-gate 
1162*0Sstevel@tonic-gate error:
1163*0Sstevel@tonic-gate     if (name)
1164*0Sstevel@tonic-gate     	gss_release_name(&min_stat, &name);
1165*0Sstevel@tonic-gate     free_server_handle(handle);
1166*0Sstevel@tonic-gate     if (client_name)
1167*0Sstevel@tonic-gate 	free(client_name);
1168*0Sstevel@tonic-gate     if (service_name)
1169*0Sstevel@tonic-gate 	free(service_name);
1170*0Sstevel@tonic-gate     if (prime_arg)
1171*0Sstevel@tonic-gate 	free(prime_arg);
1172*0Sstevel@tonic-gate     return (&ret);
1173*0Sstevel@tonic-gate }
1174*0Sstevel@tonic-gate 
1175*0Sstevel@tonic-gate #ifdef SUNWOFF
1176*0Sstevel@tonic-gate generic_ret *
1177*0Sstevel@tonic-gate setv4key_principal_1(setv4key_arg *arg, struct svc_req *rqstp)
1178*0Sstevel@tonic-gate {
1179*0Sstevel@tonic-gate     static generic_ret		    ret;
1180*0Sstevel@tonic-gate     char			    *prime_arg = NULL;
1181*0Sstevel@tonic-gate     char 			    *client_name = NULL,
1182*0Sstevel@tonic-gate 				    *service_name = NULL;
1183*0Sstevel@tonic-gate     OM_uint32			    min_stat;
1184*0Sstevel@tonic-gate     kadm5_server_handle_t	    handle;
1185*0Sstevel@tonic-gate     gss_name_t name = NULL;
1186*0Sstevel@tonic-gate 
1187*0Sstevel@tonic-gate     xdr_free(xdr_generic_ret, (char *) &ret);
1188*0Sstevel@tonic-gate 
1189*0Sstevel@tonic-gate     if (ret.code = new_server_handle(arg->api_version, rqstp, &handle))
1190*0Sstevel@tonic-gate 	 return &ret;
1191*0Sstevel@tonic-gate 
1192*0Sstevel@tonic-gate     if (ret.code = check_handle((void *)handle))
1193*0Sstevel@tonic-gate 	goto error;
1194*0Sstevel@tonic-gate     ret.api_version = handle->api_version;
1195*0Sstevel@tonic-gate 
1196*0Sstevel@tonic-gate     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1197*0Sstevel@tonic-gate 	ret.code = KADM5_FAILURE;
1198*0Sstevel@tonic-gate 	goto error;
1199*0Sstevel@tonic-gate     }
1200*0Sstevel@tonic-gate     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
1201*0Sstevel@tonic-gate 	ret.code = KADM5_BAD_PRINCIPAL;
1202*0Sstevel@tonic-gate 	goto error;
1203*0Sstevel@tonic-gate     }
1204*0Sstevel@tonic-gate     if (!(name = get_clnt_name(rqstp))) {
1205*0Sstevel@tonic-gate 	ret.code = KADM5_FAILURE;
1206*0Sstevel@tonic-gate 	goto error;
1207*0Sstevel@tonic-gate     }
1208*0Sstevel@tonic-gate 
1209*0Sstevel@tonic-gate     if (!(CHANGEPW_SERVICE(rqstp)) &&
1210*0Sstevel@tonic-gate 	       acl_check(handle->context, name, ACL_SETKEY, arg->princ, NULL)) {
1211*0Sstevel@tonic-gate 	 ret.code = kadm5_setv4key_principal((void *)handle, arg->princ,
1212*0Sstevel@tonic-gate 					     arg->keyblock);
1213*0Sstevel@tonic-gate     } else {
1214*0Sstevel@tonic-gate       krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_setv4key_principal",
1215*0Sstevel@tonic-gate 		       prime_arg, client_name, service_name,
1216*0Sstevel@tonic-gate 		       client_addr(rqstp, buf));
1217*0Sstevel@tonic-gate 	 ret.code = KADM5_AUTH_SETKEY;
1218*0Sstevel@tonic-gate     }
1219*0Sstevel@tonic-gate 
1220*0Sstevel@tonic-gate     if(ret.code != KADM5_AUTH_SETKEY) {
1221*0Sstevel@tonic-gate 	krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_setv4key_principal",
1222*0Sstevel@tonic-gate 	       prime_arg, ((ret.code == 0) ? "success" :
1223*0Sstevel@tonic-gate 			   error_message(ret.code)),
1224*0Sstevel@tonic-gate 	       client_name, service_name,
1225*0Sstevel@tonic-gate 		    client_addr(rqstp, buf));
1226*0Sstevel@tonic-gate     }
1227*0Sstevel@tonic-gate 
1228*0Sstevel@tonic-gate error:
1229*0Sstevel@tonic-gate     if (name)
1230*0Sstevel@tonic-gate 	gss_release_name(&min_stat, &name);
1231*0Sstevel@tonic-gate     free_server_handle(handle);
1232*0Sstevel@tonic-gate     if (client_name)
1233*0Sstevel@tonic-gate 	free(client_name);
1234*0Sstevel@tonic-gate     if (service_name)
1235*0Sstevel@tonic-gate 	free(service_name);
1236*0Sstevel@tonic-gate     if (prime_arg)
1237*0Sstevel@tonic-gate 	free(prime_arg);
1238*0Sstevel@tonic-gate     return (&ret);
1239*0Sstevel@tonic-gate }
1240*0Sstevel@tonic-gate #endif
1241*0Sstevel@tonic-gate 
1242*0Sstevel@tonic-gate generic_ret *
1243*0Sstevel@tonic-gate setkey_principal_1(setkey_arg *arg, struct svc_req *rqstp)
1244*0Sstevel@tonic-gate {
1245*0Sstevel@tonic-gate     static generic_ret		    ret;
1246*0Sstevel@tonic-gate     char			    *prime_arg;
1247*0Sstevel@tonic-gate     char			    *client_name,
1248*0Sstevel@tonic-gate 				    *service_name;
1249*0Sstevel@tonic-gate     OM_uint32			    min_stat;
1250*0Sstevel@tonic-gate     kadm5_server_handle_t	    handle;
1251*0Sstevel@tonic-gate     gss_name_t name;
1252*0Sstevel@tonic-gate 
1253*0Sstevel@tonic-gate     xdr_free(xdr_generic_ret, (char *) &ret);
1254*0Sstevel@tonic-gate 
1255*0Sstevel@tonic-gate     if (ret.code = new_server_handle(arg->api_version, rqstp, &handle))
1256*0Sstevel@tonic-gate 	 return &ret;
1257*0Sstevel@tonic-gate 
1258*0Sstevel@tonic-gate     if (ret.code = check_handle((void *)handle))
1259*0Sstevel@tonic-gate 	goto error;
1260*0Sstevel@tonic-gate     ret.api_version = handle->api_version;
1261*0Sstevel@tonic-gate 
1262*0Sstevel@tonic-gate     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1263*0Sstevel@tonic-gate 	ret.code = KADM5_FAILURE;
1264*0Sstevel@tonic-gate 	goto error;
1265*0Sstevel@tonic-gate     }
1266*0Sstevel@tonic-gate     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
1267*0Sstevel@tonic-gate 	ret.code = KADM5_BAD_PRINCIPAL;
1268*0Sstevel@tonic-gate 	goto error;
1269*0Sstevel@tonic-gate     }
1270*0Sstevel@tonic-gate     if (!(name = get_clnt_name(rqstp))) {
1271*0Sstevel@tonic-gate 	ret.code = KADM5_FAILURE;
1272*0Sstevel@tonic-gate 	goto error;
1273*0Sstevel@tonic-gate     }
1274*0Sstevel@tonic-gate 
1275*0Sstevel@tonic-gate     if (!(CHANGEPW_SERVICE(rqstp)) &&
1276*0Sstevel@tonic-gate 	       acl_check(handle->context, name, ACL_SETKEY, arg->princ, NULL)) {
1277*0Sstevel@tonic-gate 	 ret.code = kadm5_setkey_principal((void *)handle, arg->princ,
1278*0Sstevel@tonic-gate 					   arg->keyblocks, arg->n_keys);
1279*0Sstevel@tonic-gate     } else {
1280*0Sstevel@tonic-gate 	 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_setkey_principal",
1281*0Sstevel@tonic-gate 		prime_arg, client_name, service_name,
1282*0Sstevel@tonic-gate 		    client_addr(rqstp, buf));
1283*0Sstevel@tonic-gate 	 ret.code = KADM5_AUTH_SETKEY;
1284*0Sstevel@tonic-gate     }
1285*0Sstevel@tonic-gate 
1286*0Sstevel@tonic-gate     if(ret.code != KADM5_AUTH_SETKEY) {
1287*0Sstevel@tonic-gate 	krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_setkey_principal",
1288*0Sstevel@tonic-gate 	       prime_arg, ((ret.code == 0) ? "success" :
1289*0Sstevel@tonic-gate 			   error_message(ret.code)),
1290*0Sstevel@tonic-gate 	       client_name, service_name,
1291*0Sstevel@tonic-gate 		    client_addr(rqstp, buf));
1292*0Sstevel@tonic-gate     }
1293*0Sstevel@tonic-gate 
1294*0Sstevel@tonic-gate error:
1295*0Sstevel@tonic-gate     if (name)
1296*0Sstevel@tonic-gate 	gss_release_name(&min_stat, &name);
1297*0Sstevel@tonic-gate     free_server_handle(handle);
1298*0Sstevel@tonic-gate     if (client_name)
1299*0Sstevel@tonic-gate 	free(client_name);
1300*0Sstevel@tonic-gate     if (service_name)
1301*0Sstevel@tonic-gate 	free(service_name);
1302*0Sstevel@tonic-gate     if (prime_arg)
1303*0Sstevel@tonic-gate 	free(prime_arg);
1304*0Sstevel@tonic-gate     return (&ret);
1305*0Sstevel@tonic-gate }
1306*0Sstevel@tonic-gate 
1307*0Sstevel@tonic-gate generic_ret *
1308*0Sstevel@tonic-gate setkey_principal3_1(setkey3_arg *arg, struct svc_req *rqstp)
1309*0Sstevel@tonic-gate {
1310*0Sstevel@tonic-gate     static generic_ret		    ret;
1311*0Sstevel@tonic-gate     char			    *prime_arg = NULL;
1312*0Sstevel@tonic-gate     char			    *client_name = NULL,
1313*0Sstevel@tonic-gate 				    *service_name = NULL;
1314*0Sstevel@tonic-gate     OM_uint32			    min_stat;
1315*0Sstevel@tonic-gate     kadm5_server_handle_t	    handle;
1316*0Sstevel@tonic-gate     gss_name_t name = NULL;
1317*0Sstevel@tonic-gate 
1318*0Sstevel@tonic-gate     xdr_free(xdr_generic_ret, (char *) &ret);
1319*0Sstevel@tonic-gate 
1320*0Sstevel@tonic-gate     if (ret.code = new_server_handle(arg->api_version, rqstp, &handle))
1321*0Sstevel@tonic-gate 	 return &ret;
1322*0Sstevel@tonic-gate 
1323*0Sstevel@tonic-gate     if (ret.code = check_handle((void *)handle))
1324*0Sstevel@tonic-gate 	goto error;
1325*0Sstevel@tonic-gate     ret.api_version = handle->api_version;
1326*0Sstevel@tonic-gate 
1327*0Sstevel@tonic-gate     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1328*0Sstevel@tonic-gate 	ret.code = KADM5_FAILURE;
1329*0Sstevel@tonic-gate 	goto error;
1330*0Sstevel@tonic-gate     }
1331*0Sstevel@tonic-gate     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
1332*0Sstevel@tonic-gate 	ret.code = KADM5_BAD_PRINCIPAL;
1333*0Sstevel@tonic-gate 	goto error;
1334*0Sstevel@tonic-gate     }
1335*0Sstevel@tonic-gate     if (!(name = get_clnt_name(rqstp))) {
1336*0Sstevel@tonic-gate 	ret.code = KADM5_FAILURE;
1337*0Sstevel@tonic-gate 	goto error;
1338*0Sstevel@tonic-gate     }
1339*0Sstevel@tonic-gate 
1340*0Sstevel@tonic-gate     if (!(CHANGEPW_SERVICE(rqstp)) &&
1341*0Sstevel@tonic-gate 	       acl_check(handle->context, name, ACL_SETKEY, arg->princ, NULL)) {
1342*0Sstevel@tonic-gate 	 ret.code = kadm5_setkey_principal_3((void *)handle, arg->princ,
1343*0Sstevel@tonic-gate 					     arg->keepold,
1344*0Sstevel@tonic-gate 					     arg->n_ks_tuple,
1345*0Sstevel@tonic-gate 					     arg->ks_tuple,
1346*0Sstevel@tonic-gate 					     arg->keyblocks, arg->n_keys);
1347*0Sstevel@tonic-gate     } else {
1348*0Sstevel@tonic-gate 	 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_setkey_principal",
1349*0Sstevel@tonic-gate 		prime_arg, client_name, service_name,
1350*0Sstevel@tonic-gate 		    client_addr(rqstp, buf));
1351*0Sstevel@tonic-gate 	 ret.code = KADM5_AUTH_SETKEY;
1352*0Sstevel@tonic-gate     }
1353*0Sstevel@tonic-gate 
1354*0Sstevel@tonic-gate     if(ret.code != KADM5_AUTH_SETKEY) {
1355*0Sstevel@tonic-gate         krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_setkey_principal",
1356*0Sstevel@tonic-gate 	       prime_arg, ((ret.code == 0) ? "success" :
1357*0Sstevel@tonic-gate 	       error_message(ret.code)),
1358*0Sstevel@tonic-gate 	  client_name, service_name,
1359*0Sstevel@tonic-gate 	  client_addr(rqstp, buf));
1360*0Sstevel@tonic-gate     }
1361*0Sstevel@tonic-gate 
1362*0Sstevel@tonic-gate error:
1363*0Sstevel@tonic-gate     if (name)
1364*0Sstevel@tonic-gate 	gss_release_name(&min_stat, &name);
1365*0Sstevel@tonic-gate     free_server_handle(handle);
1366*0Sstevel@tonic-gate     if (client_name)
1367*0Sstevel@tonic-gate 	free(client_name);
1368*0Sstevel@tonic-gate     if (service_name)
1369*0Sstevel@tonic-gate 	free(service_name);
1370*0Sstevel@tonic-gate     if (prime_arg)
1371*0Sstevel@tonic-gate 	free(prime_arg);
1372*0Sstevel@tonic-gate     return (&ret);
1373*0Sstevel@tonic-gate }
1374*0Sstevel@tonic-gate 
1375*0Sstevel@tonic-gate chrand_ret *
1376*0Sstevel@tonic-gate chrand_principal_1(chrand_arg * arg, struct svc_req * rqstp)
1377*0Sstevel@tonic-gate {
1378*0Sstevel@tonic-gate 	static chrand_ret ret;
1379*0Sstevel@tonic-gate 	krb5_keyblock *k;
1380*0Sstevel@tonic-gate 	int nkeys;
1381*0Sstevel@tonic-gate 	char *prime_arg = NULL, *funcname;
1382*0Sstevel@tonic-gate 	char *client_name = NULL, *service_name = NULL;
1383*0Sstevel@tonic-gate 	OM_uint32 min_stat;
1384*0Sstevel@tonic-gate 	kadm5_server_handle_t handle;
1385*0Sstevel@tonic-gate 	gss_name_t name = NULL;
1386*0Sstevel@tonic-gate 
1387*0Sstevel@tonic-gate 	xdr_free(xdr_chrand_ret, (char *) &ret);
1388*0Sstevel@tonic-gate 
1389*0Sstevel@tonic-gate 	if (ret.code = new_server_handle(arg->api_version, rqstp, &handle))
1390*0Sstevel@tonic-gate 		return (&ret);
1391*0Sstevel@tonic-gate 
1392*0Sstevel@tonic-gate 	if (ret.code = check_handle((void *) handle))
1393*0Sstevel@tonic-gate 		goto error;
1394*0Sstevel@tonic-gate 	ret.api_version = handle->api_version;
1395*0Sstevel@tonic-gate 
1396*0Sstevel@tonic-gate 	funcname = handle->api_version == KADM5_API_VERSION_1 ?
1397*0Sstevel@tonic-gate 	    "kadm5_randkey_principal (V1)" : "kadm5_randkey_principal";
1398*0Sstevel@tonic-gate 
1399*0Sstevel@tonic-gate 	if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1400*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
1401*0Sstevel@tonic-gate 		goto error;
1402*0Sstevel@tonic-gate 	}
1403*0Sstevel@tonic-gate 	if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
1404*0Sstevel@tonic-gate 		ret.code = KADM5_BAD_PRINCIPAL;
1405*0Sstevel@tonic-gate 		goto error;
1406*0Sstevel@tonic-gate 	}
1407*0Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
1408*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
1409*0Sstevel@tonic-gate 		goto error;
1410*0Sstevel@tonic-gate 	}
1411*0Sstevel@tonic-gate 
1412*0Sstevel@tonic-gate 	if (cmp_gss_krb5_name(handle, name, arg->princ)) {
1413*0Sstevel@tonic-gate 		ret.code = randkey_principal_wrapper((void *) handle,
1414*0Sstevel@tonic-gate 		    arg->princ, &k, &nkeys);
1415*0Sstevel@tonic-gate 	} else if (!(CHANGEPW_SERVICE(rqstp)) &&
1416*0Sstevel@tonic-gate 		acl_check(handle->context, name,
1417*0Sstevel@tonic-gate 			ACL_CHANGEPW, arg->princ, NULL)) {
1418*0Sstevel@tonic-gate 		ret.code = kadm5_randkey_principal((void *) handle, arg->princ,
1419*0Sstevel@tonic-gate 		    &k, &nkeys);
1420*0Sstevel@tonic-gate 	} else {
1421*0Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
1422*0Sstevel@tonic-gate 				    funcname, prime_arg, client_name);
1423*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, funcname,
1424*0Sstevel@tonic-gate 		    prime_arg, client_name, service_name,
1425*0Sstevel@tonic-gate 		    client_addr(rqstp, buf));
1426*0Sstevel@tonic-gate 		ret.code = KADM5_AUTH_CHANGEPW;
1427*0Sstevel@tonic-gate 	}
1428*0Sstevel@tonic-gate 
1429*0Sstevel@tonic-gate 	if (ret.code == KADM5_OK) {
1430*0Sstevel@tonic-gate 		if (handle->api_version == KADM5_API_VERSION_1) {
1431*0Sstevel@tonic-gate 			krb5_copy_keyblock_contents(handle->context,
1432*0Sstevel@tonic-gate 							k, &ret.key);
1433*0Sstevel@tonic-gate 			krb5_free_keyblock(handle->context, k);
1434*0Sstevel@tonic-gate 		} else {
1435*0Sstevel@tonic-gate 			ret.keys = k;
1436*0Sstevel@tonic-gate 			ret.n_keys = nkeys;
1437*0Sstevel@tonic-gate 		}
1438*0Sstevel@tonic-gate 	}
1439*0Sstevel@tonic-gate 	if (ret.code != KADM5_AUTH_CHANGEPW) {
1440*0Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1441*0Sstevel@tonic-gate 				funcname, prime_arg, client_name, ret.code);
1442*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_DONE, funcname,
1443*0Sstevel@tonic-gate 		    prime_arg, ((ret.code == 0) ? "success" :
1444*0Sstevel@tonic-gate 			error_message(ret.code)),
1445*0Sstevel@tonic-gate 		    client_name, service_name, client_addr(rqstp, buf));
1446*0Sstevel@tonic-gate 	}
1447*0Sstevel@tonic-gate 
1448*0Sstevel@tonic-gate error:
1449*0Sstevel@tonic-gate 	if (name)
1450*0Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
1451*0Sstevel@tonic-gate 	free_server_handle(handle);
1452*0Sstevel@tonic-gate 	if (prime_arg)
1453*0Sstevel@tonic-gate 		free(prime_arg);
1454*0Sstevel@tonic-gate 	if (client_name)
1455*0Sstevel@tonic-gate 		free(client_name);
1456*0Sstevel@tonic-gate 	if (service_name)
1457*0Sstevel@tonic-gate 		free(service_name);
1458*0Sstevel@tonic-gate 	return (&ret);
1459*0Sstevel@tonic-gate }
1460*0Sstevel@tonic-gate 
1461*0Sstevel@tonic-gate chrand_ret *
1462*0Sstevel@tonic-gate chrand_principal3_1(chrand3_arg *arg, struct svc_req *rqstp)
1463*0Sstevel@tonic-gate {
1464*0Sstevel@tonic-gate     static chrand_ret		ret;
1465*0Sstevel@tonic-gate     krb5_keyblock		*k;
1466*0Sstevel@tonic-gate     int				nkeys;
1467*0Sstevel@tonic-gate     char			*prime_arg = NULL, *funcname;
1468*0Sstevel@tonic-gate     char			*client_name = NULL,
1469*0Sstevel@tonic-gate 	    			*service_name = NULL;
1470*0Sstevel@tonic-gate     OM_uint32			min_stat;
1471*0Sstevel@tonic-gate     kadm5_server_handle_t	handle;
1472*0Sstevel@tonic-gate     gss_name_t name = NULL;
1473*0Sstevel@tonic-gate 
1474*0Sstevel@tonic-gate     xdr_free(xdr_chrand_ret, (char *) &ret);
1475*0Sstevel@tonic-gate 
1476*0Sstevel@tonic-gate     if (ret.code = new_server_handle(arg->api_version, rqstp, &handle))
1477*0Sstevel@tonic-gate 	 return &ret;
1478*0Sstevel@tonic-gate 
1479*0Sstevel@tonic-gate     if (ret.code = check_handle((void *)handle))
1480*0Sstevel@tonic-gate 	goto error;
1481*0Sstevel@tonic-gate     ret.api_version = handle->api_version;
1482*0Sstevel@tonic-gate 
1483*0Sstevel@tonic-gate     funcname = handle->api_version == KADM5_API_VERSION_1 ?
1484*0Sstevel@tonic-gate 	 "kadm5_randkey_principal (V1)" : "kadm5_randkey_principal";
1485*0Sstevel@tonic-gate 
1486*0Sstevel@tonic-gate     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1487*0Sstevel@tonic-gate 	ret.code = KADM5_FAILURE;
1488*0Sstevel@tonic-gate 	goto error;
1489*0Sstevel@tonic-gate     }
1490*0Sstevel@tonic-gate     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
1491*0Sstevel@tonic-gate 	ret.code = KADM5_BAD_PRINCIPAL;
1492*0Sstevel@tonic-gate 	goto error;
1493*0Sstevel@tonic-gate     }
1494*0Sstevel@tonic-gate     if (!(name = get_clnt_name(rqstp))) {
1495*0Sstevel@tonic-gate 	ret.code = KADM5_FAILURE;
1496*0Sstevel@tonic-gate 	goto error;
1497*0Sstevel@tonic-gate     }
1498*0Sstevel@tonic-gate 
1499*0Sstevel@tonic-gate     if (cmp_gss_krb5_name(handle, name, arg->princ)) {
1500*0Sstevel@tonic-gate 	 ret.code = randkey_principal_wrapper((void *)handle,
1501*0Sstevel@tonic-gate 					      arg->princ, &k, &nkeys);
1502*0Sstevel@tonic-gate     } else if (!(CHANGEPW_SERVICE(rqstp)) &&
1503*0Sstevel@tonic-gate 	       acl_check(handle->context, name,
1504*0Sstevel@tonic-gate 			 ACL_CHANGEPW, arg->princ, NULL)) {
1505*0Sstevel@tonic-gate 	 ret.code = kadm5_randkey_principal_3((void *)handle, arg->princ,
1506*0Sstevel@tonic-gate 					      arg->keepold,
1507*0Sstevel@tonic-gate 					      arg->n_ks_tuple,
1508*0Sstevel@tonic-gate 					      arg->ks_tuple,
1509*0Sstevel@tonic-gate 					      &k, &nkeys);
1510*0Sstevel@tonic-gate     } else {
1511*0Sstevel@tonic-gate 	 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, funcname,
1512*0Sstevel@tonic-gate 			  prime_arg, client_name, service_name,
1513*0Sstevel@tonic-gate 			  client_addr(rqstp, buf));
1514*0Sstevel@tonic-gate 	 ret.code = KADM5_AUTH_CHANGEPW;
1515*0Sstevel@tonic-gate     }
1516*0Sstevel@tonic-gate 
1517*0Sstevel@tonic-gate     if(ret.code == KADM5_OK) {
1518*0Sstevel@tonic-gate 	 if (handle->api_version == KADM5_API_VERSION_1) {
1519*0Sstevel@tonic-gate 	      krb5_copy_keyblock_contents(handle->context, k, &ret.key);
1520*0Sstevel@tonic-gate 	      krb5_free_keyblock(handle->context, k);
1521*0Sstevel@tonic-gate 	 } else {
1522*0Sstevel@tonic-gate 	      ret.keys = k;
1523*0Sstevel@tonic-gate 	      ret.n_keys = nkeys;
1524*0Sstevel@tonic-gate 	 }
1525*0Sstevel@tonic-gate     }
1526*0Sstevel@tonic-gate 
1527*0Sstevel@tonic-gate     if(ret.code != KADM5_AUTH_CHANGEPW) {
1528*0Sstevel@tonic-gate 	krb5_klog_syslog(LOG_NOTICE, LOG_DONE, funcname,
1529*0Sstevel@tonic-gate 			 prime_arg, ((ret.code == 0) ? "success" :
1530*0Sstevel@tonic-gate 			   error_message(ret.code)),
1531*0Sstevel@tonic-gate 			 client_name, service_name,
1532*0Sstevel@tonic-gate 			 client_addr(rqstp, buf));
1533*0Sstevel@tonic-gate     }
1534*0Sstevel@tonic-gate 
1535*0Sstevel@tonic-gate error:
1536*0Sstevel@tonic-gate     if (name)
1537*0Sstevel@tonic-gate 	gss_release_name(&min_stat, &name);
1538*0Sstevel@tonic-gate     free_server_handle(handle);
1539*0Sstevel@tonic-gate     if (client_name)
1540*0Sstevel@tonic-gate 	free(client_name);
1541*0Sstevel@tonic-gate     if (service_name)
1542*0Sstevel@tonic-gate 	free(service_name);
1543*0Sstevel@tonic-gate     if (prime_arg)
1544*0Sstevel@tonic-gate 	free(prime_arg);
1545*0Sstevel@tonic-gate     return (&ret);
1546*0Sstevel@tonic-gate }
1547*0Sstevel@tonic-gate 
1548*0Sstevel@tonic-gate 
1549*0Sstevel@tonic-gate generic_ret *
1550*0Sstevel@tonic-gate create_policy_1(cpol_arg * arg, struct svc_req * rqstp)
1551*0Sstevel@tonic-gate {
1552*0Sstevel@tonic-gate 	static generic_ret ret;
1553*0Sstevel@tonic-gate 	char *prime_arg = NULL;
1554*0Sstevel@tonic-gate 	char *client_name = NULL, *service_name = NULL;
1555*0Sstevel@tonic-gate 	OM_uint32 min_stat;
1556*0Sstevel@tonic-gate 	kadm5_server_handle_t handle;
1557*0Sstevel@tonic-gate 	gss_name_t name = NULL;
1558*0Sstevel@tonic-gate 
1559*0Sstevel@tonic-gate 	xdr_free(xdr_generic_ret, (char *) &ret);
1560*0Sstevel@tonic-gate 
1561*0Sstevel@tonic-gate 	if (ret.code = new_server_handle(arg->api_version, rqstp, &handle))
1562*0Sstevel@tonic-gate 		return (&ret);
1563*0Sstevel@tonic-gate 
1564*0Sstevel@tonic-gate 	if (ret.code = check_handle((void *) handle))
1565*0Sstevel@tonic-gate 		goto error;
1566*0Sstevel@tonic-gate 	ret.api_version = handle->api_version;
1567*0Sstevel@tonic-gate 
1568*0Sstevel@tonic-gate 	if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1569*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
1570*0Sstevel@tonic-gate 		goto error;
1571*0Sstevel@tonic-gate 	}
1572*0Sstevel@tonic-gate 	prime_arg = arg->rec.policy;
1573*0Sstevel@tonic-gate 
1574*0Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
1575*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
1576*0Sstevel@tonic-gate 		goto error;
1577*0Sstevel@tonic-gate 	}
1578*0Sstevel@tonic-gate 
1579*0Sstevel@tonic-gate 	if (CHANGEPW_SERVICE(rqstp) || !acl_check(handle->context,
1580*0Sstevel@tonic-gate 						name,
1581*0Sstevel@tonic-gate 						ACL_ADD, NULL, NULL)) {
1582*0Sstevel@tonic-gate 		ret.code = KADM5_AUTH_ADD;
1583*0Sstevel@tonic-gate 
1584*0Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
1585*0Sstevel@tonic-gate 				    "kadm5_create_policy",
1586*0Sstevel@tonic-gate 				    prime_arg, client_name);
1587*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_create_policy",
1588*0Sstevel@tonic-gate 		    prime_arg, client_name,
1589*0Sstevel@tonic-gate 		    service_name, client_addr(rqstp, buf));
1590*0Sstevel@tonic-gate 
1591*0Sstevel@tonic-gate 	} else {
1592*0Sstevel@tonic-gate 		ret.code = kadm5_create_policy((void *) handle, &arg->rec,
1593*0Sstevel@tonic-gate 		    arg->mask);
1594*0Sstevel@tonic-gate 
1595*0Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1596*0Sstevel@tonic-gate 				"kadm5_create_policy",
1597*0Sstevel@tonic-gate 				prime_arg, client_name, ret.code);
1598*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_create_policy",
1599*0Sstevel@tonic-gate 		    ((prime_arg == NULL) ? "(null)" : prime_arg),
1600*0Sstevel@tonic-gate 		    ((ret.code == 0) ? "success" : error_message(ret.code)),
1601*0Sstevel@tonic-gate 		    client_name, service_name, client_addr(rqstp, buf));
1602*0Sstevel@tonic-gate 	}
1603*0Sstevel@tonic-gate 
1604*0Sstevel@tonic-gate error:
1605*0Sstevel@tonic-gate 	if (name)
1606*0Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
1607*0Sstevel@tonic-gate 	free_server_handle(handle);
1608*0Sstevel@tonic-gate 	if (client_name)
1609*0Sstevel@tonic-gate 		free(client_name);
1610*0Sstevel@tonic-gate 	if (service_name)
1611*0Sstevel@tonic-gate 		free(service_name);
1612*0Sstevel@tonic-gate 	return (&ret);
1613*0Sstevel@tonic-gate }
1614*0Sstevel@tonic-gate 
1615*0Sstevel@tonic-gate generic_ret *
1616*0Sstevel@tonic-gate delete_policy_1(dpol_arg * arg, struct svc_req * rqstp)
1617*0Sstevel@tonic-gate {
1618*0Sstevel@tonic-gate 	static generic_ret ret;
1619*0Sstevel@tonic-gate 	char *prime_arg = NULL;
1620*0Sstevel@tonic-gate 	char *client_name = NULL, *service_name = NULL;
1621*0Sstevel@tonic-gate 	OM_uint32 min_stat;
1622*0Sstevel@tonic-gate 	kadm5_server_handle_t handle;
1623*0Sstevel@tonic-gate 	gss_name_t name = NULL;
1624*0Sstevel@tonic-gate 
1625*0Sstevel@tonic-gate 	xdr_free(xdr_generic_ret, (char *) &ret);
1626*0Sstevel@tonic-gate 
1627*0Sstevel@tonic-gate 	if (ret.code = new_server_handle(arg->api_version, rqstp, &handle))
1628*0Sstevel@tonic-gate 		return (&ret);
1629*0Sstevel@tonic-gate 
1630*0Sstevel@tonic-gate 	if (ret.code = check_handle((void *) handle))
1631*0Sstevel@tonic-gate 		goto error;
1632*0Sstevel@tonic-gate 	ret.api_version = handle->api_version;
1633*0Sstevel@tonic-gate 
1634*0Sstevel@tonic-gate 	if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1635*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
1636*0Sstevel@tonic-gate 		goto error;
1637*0Sstevel@tonic-gate 	}
1638*0Sstevel@tonic-gate 	prime_arg = arg->name;
1639*0Sstevel@tonic-gate 
1640*0Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
1641*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
1642*0Sstevel@tonic-gate 		goto error;
1643*0Sstevel@tonic-gate 	}
1644*0Sstevel@tonic-gate 
1645*0Sstevel@tonic-gate 	if (CHANGEPW_SERVICE(rqstp) || !acl_check(handle->context,
1646*0Sstevel@tonic-gate 						name,
1647*0Sstevel@tonic-gate 						ACL_DELETE, NULL, NULL)) {
1648*0Sstevel@tonic-gate 
1649*0Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
1650*0Sstevel@tonic-gate 				    "kadm5_delete_policy",
1651*0Sstevel@tonic-gate 				    prime_arg, client_name);
1652*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_delete_policy",
1653*0Sstevel@tonic-gate 		    prime_arg, client_name, service_name,
1654*0Sstevel@tonic-gate 		    client_addr(rqstp, buf));
1655*0Sstevel@tonic-gate 		ret.code = KADM5_AUTH_DELETE;
1656*0Sstevel@tonic-gate 	} else {
1657*0Sstevel@tonic-gate 		ret.code = kadm5_delete_policy((void *) handle, arg->name);
1658*0Sstevel@tonic-gate 
1659*0Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1660*0Sstevel@tonic-gate 				"kadm5_delete_policy",
1661*0Sstevel@tonic-gate 				prime_arg, client_name, ret.code);
1662*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_delete_policy",
1663*0Sstevel@tonic-gate 		    ((prime_arg == NULL) ? "(null)" : prime_arg),
1664*0Sstevel@tonic-gate 		    ((ret.code == 0) ? "success" : error_message(ret.code)),
1665*0Sstevel@tonic-gate 		    client_name, service_name, client_addr(rqstp, buf));
1666*0Sstevel@tonic-gate 	}
1667*0Sstevel@tonic-gate 
1668*0Sstevel@tonic-gate error:
1669*0Sstevel@tonic-gate 	if (name)
1670*0Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
1671*0Sstevel@tonic-gate 	free_server_handle(handle);
1672*0Sstevel@tonic-gate 	if (client_name)
1673*0Sstevel@tonic-gate 		free(client_name);
1674*0Sstevel@tonic-gate 	if (service_name)
1675*0Sstevel@tonic-gate 		free(service_name);
1676*0Sstevel@tonic-gate 	return (&ret);
1677*0Sstevel@tonic-gate }
1678*0Sstevel@tonic-gate 
1679*0Sstevel@tonic-gate generic_ret *
1680*0Sstevel@tonic-gate modify_policy_1(mpol_arg * arg, struct svc_req * rqstp)
1681*0Sstevel@tonic-gate {
1682*0Sstevel@tonic-gate 	static generic_ret ret;
1683*0Sstevel@tonic-gate 	char *prime_arg = NULL;
1684*0Sstevel@tonic-gate 	char *client_name = NULL, *service_name = NULL;
1685*0Sstevel@tonic-gate 	OM_uint32 min_stat;
1686*0Sstevel@tonic-gate 	kadm5_server_handle_t handle;
1687*0Sstevel@tonic-gate 	gss_name_t name = NULL;
1688*0Sstevel@tonic-gate 
1689*0Sstevel@tonic-gate 	xdr_free(xdr_generic_ret, (char *) &ret);
1690*0Sstevel@tonic-gate 
1691*0Sstevel@tonic-gate 	if (ret.code = new_server_handle(arg->api_version, rqstp, &handle))
1692*0Sstevel@tonic-gate 		return (&ret);
1693*0Sstevel@tonic-gate 
1694*0Sstevel@tonic-gate 	if (ret.code = check_handle((void *) handle))
1695*0Sstevel@tonic-gate 		goto error;
1696*0Sstevel@tonic-gate 	ret.api_version = handle->api_version;
1697*0Sstevel@tonic-gate 
1698*0Sstevel@tonic-gate 	if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1699*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
1700*0Sstevel@tonic-gate 		goto error;
1701*0Sstevel@tonic-gate 	}
1702*0Sstevel@tonic-gate 	prime_arg = arg->rec.policy;
1703*0Sstevel@tonic-gate 
1704*0Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
1705*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
1706*0Sstevel@tonic-gate 		goto error;
1707*0Sstevel@tonic-gate 	}
1708*0Sstevel@tonic-gate 
1709*0Sstevel@tonic-gate 	if (CHANGEPW_SERVICE(rqstp) || !acl_check(handle->context,
1710*0Sstevel@tonic-gate 						name,
1711*0Sstevel@tonic-gate 						ACL_MODIFY, NULL, NULL)) {
1712*0Sstevel@tonic-gate 
1713*0Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
1714*0Sstevel@tonic-gate 				    "kadm5_modify_policy",
1715*0Sstevel@tonic-gate 				    prime_arg, client_name);
1716*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_modify_policy",
1717*0Sstevel@tonic-gate 		    prime_arg, client_name,
1718*0Sstevel@tonic-gate 		    service_name, client_addr(rqstp, buf));
1719*0Sstevel@tonic-gate 		ret.code = KADM5_AUTH_MODIFY;
1720*0Sstevel@tonic-gate 	} else {
1721*0Sstevel@tonic-gate 		ret.code = kadm5_modify_policy((void *) handle, &arg->rec,
1722*0Sstevel@tonic-gate 		    arg->mask);
1723*0Sstevel@tonic-gate 
1724*0Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1725*0Sstevel@tonic-gate 				"kadm5_modify_policy",
1726*0Sstevel@tonic-gate 				prime_arg, client_name, ret.code);
1727*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_modify_policy",
1728*0Sstevel@tonic-gate 		    ((prime_arg == NULL) ? "(null)" : prime_arg),
1729*0Sstevel@tonic-gate 		    ((ret.code == 0) ? "success" : error_message(ret.code)),
1730*0Sstevel@tonic-gate 		    client_name, service_name, client_addr(rqstp, buf));
1731*0Sstevel@tonic-gate 	}
1732*0Sstevel@tonic-gate 
1733*0Sstevel@tonic-gate error:
1734*0Sstevel@tonic-gate 	if (name)
1735*0Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
1736*0Sstevel@tonic-gate 	free_server_handle(handle);
1737*0Sstevel@tonic-gate 	if (client_name)
1738*0Sstevel@tonic-gate 		free(client_name);
1739*0Sstevel@tonic-gate 	if (service_name)
1740*0Sstevel@tonic-gate 		free(service_name);
1741*0Sstevel@tonic-gate 	return (&ret);
1742*0Sstevel@tonic-gate }
1743*0Sstevel@tonic-gate 
1744*0Sstevel@tonic-gate gpol_ret *
1745*0Sstevel@tonic-gate get_policy_1(gpol_arg * arg, struct svc_req * rqstp)
1746*0Sstevel@tonic-gate {
1747*0Sstevel@tonic-gate 	static gpol_ret ret;
1748*0Sstevel@tonic-gate 	kadm5_ret_t ret2;
1749*0Sstevel@tonic-gate 	char *prime_arg = NULL, *funcname;
1750*0Sstevel@tonic-gate 	char *client_name = NULL, *service_name = NULL;
1751*0Sstevel@tonic-gate 	OM_uint32 min_stat;
1752*0Sstevel@tonic-gate 	kadm5_policy_ent_t e;
1753*0Sstevel@tonic-gate 	kadm5_principal_ent_rec caller_ent;
1754*0Sstevel@tonic-gate 	krb5_principal caller;
1755*0Sstevel@tonic-gate 	kadm5_server_handle_t handle;
1756*0Sstevel@tonic-gate 	gss_name_t name = NULL;
1757*0Sstevel@tonic-gate 
1758*0Sstevel@tonic-gate 	xdr_free(xdr_gpol_ret, (char *) &ret);
1759*0Sstevel@tonic-gate 
1760*0Sstevel@tonic-gate 	if (ret.code = new_server_handle(arg->api_version, rqstp, &handle))
1761*0Sstevel@tonic-gate 		return (&ret);
1762*0Sstevel@tonic-gate 
1763*0Sstevel@tonic-gate 	if (ret.code = check_handle((void *) handle))
1764*0Sstevel@tonic-gate 		goto error;
1765*0Sstevel@tonic-gate 	ret.api_version = handle->api_version;
1766*0Sstevel@tonic-gate 
1767*0Sstevel@tonic-gate 	funcname = handle->api_version == KADM5_API_VERSION_1 ?
1768*0Sstevel@tonic-gate 	    "kadm5_get_policy (V1)" : "kadm5_get_policy";
1769*0Sstevel@tonic-gate 
1770*0Sstevel@tonic-gate 	if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1771*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
1772*0Sstevel@tonic-gate 		goto error;
1773*0Sstevel@tonic-gate 	}
1774*0Sstevel@tonic-gate 	prime_arg = arg->name;
1775*0Sstevel@tonic-gate 	ret.code = KADM5_AUTH_GET;
1776*0Sstevel@tonic-gate 
1777*0Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
1778*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
1779*0Sstevel@tonic-gate 		goto error;
1780*0Sstevel@tonic-gate 	}
1781*0Sstevel@tonic-gate 
1782*0Sstevel@tonic-gate 	if (!CHANGEPW_SERVICE(rqstp) && acl_check(handle->context,
1783*0Sstevel@tonic-gate 						name,
1784*0Sstevel@tonic-gate 						ACL_INQUIRE, NULL, NULL))
1785*0Sstevel@tonic-gate 		ret.code = KADM5_OK;
1786*0Sstevel@tonic-gate 	else {
1787*0Sstevel@tonic-gate 		ret.code = kadm5_get_principal(handle->lhandle,
1788*0Sstevel@tonic-gate 		    handle->current_caller,
1789*0Sstevel@tonic-gate 		    &caller_ent,
1790*0Sstevel@tonic-gate 		    KADM5_PRINCIPAL_NORMAL_MASK);
1791*0Sstevel@tonic-gate 		if (ret.code == KADM5_OK) {
1792*0Sstevel@tonic-gate 			if (caller_ent.aux_attributes & KADM5_POLICY &&
1793*0Sstevel@tonic-gate 			    strcmp(caller_ent.policy, arg->name) == 0) {
1794*0Sstevel@tonic-gate 				ret.code = KADM5_OK;
1795*0Sstevel@tonic-gate 			} else
1796*0Sstevel@tonic-gate 				ret.code = KADM5_AUTH_GET;
1797*0Sstevel@tonic-gate 			ret2 = kadm5_free_principal_ent(handle->lhandle,
1798*0Sstevel@tonic-gate 			    &caller_ent);
1799*0Sstevel@tonic-gate 			ret.code = ret.code ? ret.code : ret2;
1800*0Sstevel@tonic-gate 		}
1801*0Sstevel@tonic-gate 	}
1802*0Sstevel@tonic-gate 
1803*0Sstevel@tonic-gate 	if (ret.code == KADM5_OK) {
1804*0Sstevel@tonic-gate 		if (handle->api_version == KADM5_API_VERSION_1) {
1805*0Sstevel@tonic-gate 			ret.code = kadm5_get_policy_v1((void *) handle,
1806*0Sstevel@tonic-gate 							arg->name, &e);
1807*0Sstevel@tonic-gate 			if (ret.code == KADM5_OK) {
1808*0Sstevel@tonic-gate 				memcpy(&ret.rec, e,
1809*0Sstevel@tonic-gate 					sizeof (kadm5_policy_ent_rec));
1810*0Sstevel@tonic-gate 				free(e);
1811*0Sstevel@tonic-gate 			}
1812*0Sstevel@tonic-gate 		} else {
1813*0Sstevel@tonic-gate 			ret.code = kadm5_get_policy((void *) handle, arg->name,
1814*0Sstevel@tonic-gate 			    &ret.rec);
1815*0Sstevel@tonic-gate 		}
1816*0Sstevel@tonic-gate 
1817*0Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1818*0Sstevel@tonic-gate 				funcname, prime_arg, client_name, ret.code);
1819*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_DONE, funcname,
1820*0Sstevel@tonic-gate 		    ((prime_arg == NULL) ? "(null)" : prime_arg),
1821*0Sstevel@tonic-gate 		    ((ret.code == 0) ? "success" : error_message(ret.code)),
1822*0Sstevel@tonic-gate 		    client_name, service_name, client_addr(rqstp, buf));
1823*0Sstevel@tonic-gate 	} else {
1824*0Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
1825*0Sstevel@tonic-gate 				    funcname, prime_arg, client_name);
1826*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, funcname,
1827*0Sstevel@tonic-gate 		    prime_arg, client_name,
1828*0Sstevel@tonic-gate 		    service_name, client_addr(rqstp, buf));
1829*0Sstevel@tonic-gate 	}
1830*0Sstevel@tonic-gate 
1831*0Sstevel@tonic-gate error:
1832*0Sstevel@tonic-gate 	if (name)
1833*0Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
1834*0Sstevel@tonic-gate 	free_server_handle(handle);
1835*0Sstevel@tonic-gate 	if (client_name)
1836*0Sstevel@tonic-gate 		free(client_name);
1837*0Sstevel@tonic-gate 	if (service_name)
1838*0Sstevel@tonic-gate 		free(service_name);
1839*0Sstevel@tonic-gate 	return (&ret);
1840*0Sstevel@tonic-gate 
1841*0Sstevel@tonic-gate }
1842*0Sstevel@tonic-gate 
1843*0Sstevel@tonic-gate gpols_ret *
1844*0Sstevel@tonic-gate get_pols_1(gpols_arg * arg, struct svc_req * rqstp)
1845*0Sstevel@tonic-gate {
1846*0Sstevel@tonic-gate 	static gpols_ret ret;
1847*0Sstevel@tonic-gate 	char *prime_arg = NULL;
1848*0Sstevel@tonic-gate 	char *client_name = NULL, *service_name = NULL;
1849*0Sstevel@tonic-gate 	OM_uint32 min_stat;
1850*0Sstevel@tonic-gate 	kadm5_server_handle_t handle;
1851*0Sstevel@tonic-gate 	gss_name_t name = NULL;
1852*0Sstevel@tonic-gate 
1853*0Sstevel@tonic-gate 	xdr_free(xdr_gpols_ret, (char *) &ret);
1854*0Sstevel@tonic-gate 
1855*0Sstevel@tonic-gate 	if (ret.code = new_server_handle(arg->api_version, rqstp, &handle))
1856*0Sstevel@tonic-gate 		return (&ret);
1857*0Sstevel@tonic-gate 
1858*0Sstevel@tonic-gate 	if (ret.code = check_handle((void *) handle))
1859*0Sstevel@tonic-gate 		goto error;
1860*0Sstevel@tonic-gate 	ret.api_version = handle->api_version;
1861*0Sstevel@tonic-gate 
1862*0Sstevel@tonic-gate 	if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1863*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
1864*0Sstevel@tonic-gate 		goto error;
1865*0Sstevel@tonic-gate 	}
1866*0Sstevel@tonic-gate 	prime_arg = arg->exp;
1867*0Sstevel@tonic-gate 	if (prime_arg == NULL)
1868*0Sstevel@tonic-gate 		prime_arg = "*";
1869*0Sstevel@tonic-gate 
1870*0Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
1871*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
1872*0Sstevel@tonic-gate 		goto error;
1873*0Sstevel@tonic-gate 	}
1874*0Sstevel@tonic-gate 
1875*0Sstevel@tonic-gate 	if (CHANGEPW_SERVICE(rqstp) || !acl_check(handle->context,
1876*0Sstevel@tonic-gate 						name,
1877*0Sstevel@tonic-gate 						ACL_LIST, NULL, NULL)) {
1878*0Sstevel@tonic-gate 		ret.code = KADM5_AUTH_LIST;
1879*0Sstevel@tonic-gate 
1880*0Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
1881*0Sstevel@tonic-gate 				    "kadm5_get_policies",
1882*0Sstevel@tonic-gate 				    prime_arg, client_name);
1883*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_get_policies",
1884*0Sstevel@tonic-gate 		    prime_arg, client_name, service_name,
1885*0Sstevel@tonic-gate 		    client_addr(rqstp, buf));
1886*0Sstevel@tonic-gate 	} else {
1887*0Sstevel@tonic-gate 		ret.code = kadm5_get_policies((void *) handle,
1888*0Sstevel@tonic-gate 		    arg->exp, &ret.pols,
1889*0Sstevel@tonic-gate 		    &ret.count);
1890*0Sstevel@tonic-gate 
1891*0Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1892*0Sstevel@tonic-gate 				"kadm5_get_policies",
1893*0Sstevel@tonic-gate 				prime_arg, client_name, ret.code);
1894*0Sstevel@tonic-gate 		krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_get_policies",
1895*0Sstevel@tonic-gate 		    prime_arg,
1896*0Sstevel@tonic-gate 		    ((ret.code == 0) ? "success" : error_message(ret.code)),
1897*0Sstevel@tonic-gate 		    client_name, service_name, client_addr(rqstp, buf));
1898*0Sstevel@tonic-gate 	}
1899*0Sstevel@tonic-gate 
1900*0Sstevel@tonic-gate error:
1901*0Sstevel@tonic-gate 	if (name)
1902*0Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
1903*0Sstevel@tonic-gate 	free_server_handle(handle);
1904*0Sstevel@tonic-gate 	if (client_name)
1905*0Sstevel@tonic-gate 		free(client_name);
1906*0Sstevel@tonic-gate 	if (service_name)
1907*0Sstevel@tonic-gate 		free(service_name);
1908*0Sstevel@tonic-gate 	return (&ret);
1909*0Sstevel@tonic-gate }
1910*0Sstevel@tonic-gate 
1911*0Sstevel@tonic-gate getprivs_ret *
1912*0Sstevel@tonic-gate get_privs_1(krb5_ui_4 * arg, struct svc_req * rqstp)
1913*0Sstevel@tonic-gate {
1914*0Sstevel@tonic-gate 	static getprivs_ret ret;
1915*0Sstevel@tonic-gate 	char *client_name = NULL, *service_name = NULL;
1916*0Sstevel@tonic-gate 	OM_uint32 min_stat;
1917*0Sstevel@tonic-gate 	kadm5_server_handle_t handle;
1918*0Sstevel@tonic-gate 	gss_name_t name = NULL;
1919*0Sstevel@tonic-gate 
1920*0Sstevel@tonic-gate 	xdr_free(xdr_getprivs_ret, (char *) &ret);
1921*0Sstevel@tonic-gate 
1922*0Sstevel@tonic-gate 	if (ret.code = new_server_handle(*arg, rqstp, &handle))
1923*0Sstevel@tonic-gate 		return (&ret);
1924*0Sstevel@tonic-gate 
1925*0Sstevel@tonic-gate 	if (ret.code = check_handle((void *) handle))
1926*0Sstevel@tonic-gate 		goto error;
1927*0Sstevel@tonic-gate 	ret.api_version = handle->api_version;
1928*0Sstevel@tonic-gate 
1929*0Sstevel@tonic-gate 	if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1930*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
1931*0Sstevel@tonic-gate 		goto error;
1932*0Sstevel@tonic-gate 	}
1933*0Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
1934*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
1935*0Sstevel@tonic-gate 		goto error;
1936*0Sstevel@tonic-gate 	}
1937*0Sstevel@tonic-gate 
1938*0Sstevel@tonic-gate 	ret.code = __kadm5_get_priv((void *) handle, &ret.privs, name);
1939*0Sstevel@tonic-gate 
1940*0Sstevel@tonic-gate 	audit_kadmind_auth(rqstp->rq_xprt, l_port,
1941*0Sstevel@tonic-gate 			"kadm5_get_privs", NULL, client_name,
1942*0Sstevel@tonic-gate 			ret.code);
1943*0Sstevel@tonic-gate 	krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_get_privs",
1944*0Sstevel@tonic-gate 	    client_name,
1945*0Sstevel@tonic-gate 	    ((ret.code == 0) ? "success" : error_message(ret.code)),
1946*0Sstevel@tonic-gate 	    client_name, service_name, client_addr(rqstp, buf));
1947*0Sstevel@tonic-gate 
1948*0Sstevel@tonic-gate error:
1949*0Sstevel@tonic-gate 	if (name)
1950*0Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
1951*0Sstevel@tonic-gate 	free_server_handle(handle);
1952*0Sstevel@tonic-gate 	if (client_name)
1953*0Sstevel@tonic-gate 		free(client_name);
1954*0Sstevel@tonic-gate 	if (service_name)
1955*0Sstevel@tonic-gate 		free(service_name);
1956*0Sstevel@tonic-gate 	return (&ret);
1957*0Sstevel@tonic-gate }
1958*0Sstevel@tonic-gate 
1959*0Sstevel@tonic-gate generic_ret *
1960*0Sstevel@tonic-gate init_1(krb5_ui_4 * arg, struct svc_req * rqstp)
1961*0Sstevel@tonic-gate {
1962*0Sstevel@tonic-gate 	static generic_ret ret;
1963*0Sstevel@tonic-gate 	char *client_name, *service_name;
1964*0Sstevel@tonic-gate 	kadm5_server_handle_t handle;
1965*0Sstevel@tonic-gate 
1966*0Sstevel@tonic-gate 	xdr_free(xdr_generic_ret, (char *) &ret);
1967*0Sstevel@tonic-gate 
1968*0Sstevel@tonic-gate 	if (ret.code = new_server_handle(*arg, rqstp, &handle))
1969*0Sstevel@tonic-gate 		return (&ret);
1970*0Sstevel@tonic-gate 	if (!(ret.code = check_handle((void *) handle))) {
1971*0Sstevel@tonic-gate 		ret.api_version = handle->api_version;
1972*0Sstevel@tonic-gate 	}
1973*0Sstevel@tonic-gate 	free_server_handle(handle);
1974*0Sstevel@tonic-gate 
1975*0Sstevel@tonic-gate 	if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1976*0Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
1977*0Sstevel@tonic-gate 		return (&ret);
1978*0Sstevel@tonic-gate 	}
1979*0Sstevel@tonic-gate 
1980*0Sstevel@tonic-gate 	audit_kadmind_auth(rqstp->rq_xprt, l_port,
1981*0Sstevel@tonic-gate 			(ret.api_version == KADM5_API_VERSION_1 ?
1982*0Sstevel@tonic-gate 			"kadm5_init (V1)" : "kadm5_init"),
1983*0Sstevel@tonic-gate 			NULL, client_name, ret.code);
1984*0Sstevel@tonic-gate 	krb5_klog_syslog(LOG_NOTICE, LOG_DONE,
1985*0Sstevel@tonic-gate 	    (ret.api_version == KADM5_API_VERSION_1 ?
1986*0Sstevel@tonic-gate 		"kadm5_init (V1)" : "kadm5_init"),
1987*0Sstevel@tonic-gate 	    client_name, (ret.code == 0) ? "success" : error_message(ret.code),
1988*0Sstevel@tonic-gate 	    client_name, service_name, client_addr(rqstp, buf));
1989*0Sstevel@tonic-gate 	free(client_name);
1990*0Sstevel@tonic-gate 	free(service_name);
1991*0Sstevel@tonic-gate 
1992*0Sstevel@tonic-gate 	return (&ret);
1993*0Sstevel@tonic-gate }
1994