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