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