xref: /titanic_51/usr/src/cmd/krb5/kadmin/server/server_stubs.c (revision b7d3956b92a285d8dac2c7f5f7e28d2ef5347ef8)
1 /*
2  * Copyright 2008 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     size_t tlen1, tlen2, clen, slen;
841     char *tdots1, *tdots2, *cdots, *sdots;
842 
843     xdr_free(xdr_generic_ret, (char *) &ret);
844 
845     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
846 	 return &ret;
847 
848     if ((ret.code = check_handle((void *)handle)))
849 	 goto error;
850     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
851 	 ret.code = KADM5_FAILURE;
852 	 goto error;
853     }
854     if (krb5_unparse_name(handle->context, arg->src, &prime_arg1) ||
855         krb5_unparse_name(handle->context, arg->dest, &prime_arg2)) {
856 	 ret.code = KADM5_BAD_PRINCIPAL;
857 	 goto error;
858     }
859     tlen1 = strlen(prime_arg1);
860     trunc_name(&tlen1, &tdots1);
861     tlen2 = strlen(prime_arg2);
862     trunc_name(&tlen2, &tdots2);
863     clen = strlen(client_name);
864     trunc_name(&clen, &cdots);
865     slen = strlen(service_name);
866     trunc_name(&slen, &sdots);
867 
868     (void) snprintf(prime_arg, sizeof (prime_arg), "%.*s%s to %.*s*s",
869 	tlen1, prime_arg1, tdots1,
870 	tlen2, prime_arg2, tdots2);
871     ret.code = KADM5_OK;
872 
873 	if (!(name = get_clnt_name(rqstp))) {
874 		ret.code = KADM5_FAILURE;
875 		goto error;
876 	}
877 
878     if (! CHANGEPW_SERVICE(rqstp)) {
879 	 if (!kadm5int_acl_check(handle->context, name,
880 			ACL_DELETE, arg->src, NULL))
881 	      ret.code = KADM5_AUTH_DELETE;
882 	 /* any restrictions at all on the ADD kills the RENAME */
883 	 if (!kadm5int_acl_check(handle->context, name,
884 			ACL_ADD, arg->dest, &rp)) {
885 	      if (ret.code == KADM5_AUTH_DELETE)
886 		   ret.code = KADM5_AUTH_INSUFFICIENT;
887 	      else
888 		   ret.code = KADM5_AUTH_ADD;
889 	 }
890     } else
891 	 ret.code = KADM5_AUTH_INSUFFICIENT;
892     if (ret.code != KADM5_OK) {
893 
894 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
895 				    "kadm5_rename_principal",
896 				    prime_arg, client_name);
897 		krb5_klog_syslog(LOG_NOTICE,
898 		    "Unauthorized request: kadm5_rename_principal, "
899 		    "%.*s%s to %.*s%s, "
900 		    "client=%.*s%s, service=%.*s%s, addr=%s",
901 		    tlen1, prime_arg1, tdots1,
902 		    tlen2, prime_arg2, tdots2,
903 		    clen, client_name, cdots,
904 		    slen, service_name, sdots,
905 		    client_addr(rqstp, buf));
906     } else {
907 	 ret.code = kadm5_rename_principal((void *)handle, arg->src,
908 						arg->dest);
909 
910 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
911 				"kadm5_rename_principal",
912 				prime_arg, client_name, ret.code);
913 		krb5_klog_syslog(LOG_NOTICE,
914 		    "Request: kadm5_rename_principal, "
915 		    "%.*s%s to %.*s%s, %s, "
916 		    "client=%.*s%s, service=%.*s%s, addr=%s",
917 		    tlen1, prime_arg1, tdots1,
918 		    tlen2, prime_arg2, tdots2,
919 		    clen, client_name, cdots,
920 		    slen, service_name, sdots,
921 		    client_addr(rqstp, buf));
922     }
923 
924 error:
925     if (name)
926     	gss_release_name(&min_stat, &name);
927     free_server_handle(handle);
928     if (prime_arg1)
929     	free(prime_arg1);
930     if (prime_arg2)
931     	free(prime_arg2);
932     if (client_name)
933     	free(client_name);
934     if (service_name)
935     	free(service_name);
936     return &ret;
937 }
938 
939 gprinc_ret *
940 get_principal_1_svc(gprinc_arg *arg, struct svc_req *rqstp)
941 {
942     static gprinc_ret		    ret;
943     kadm5_principal_ent_t_v1	    e;
944     char			    *prime_arg = NULL, *funcname;
945     char *client_name = NULL, *service_name = NULL;
946     OM_uint32			    min_stat;
947     kadm5_server_handle_t	    handle;
948     gss_name_t name = NULL;
949 
950     xdr_free(xdr_gprinc_ret, (char *) &ret);
951 
952     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
953 	 return &ret;
954 
955     if ((ret.code = check_handle((void *)handle)))
956 		goto error;
957     ret.api_version = handle->api_version;
958 
959     funcname = handle->api_version == KADM5_API_VERSION_1 ?
960 	 "kadm5_get_principal (V1)" : "kadm5_get_principal";
961 
962     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
963 	 ret.code = KADM5_FAILURE;
964 		goto error;
965     }
966     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
967 	 ret.code = KADM5_BAD_PRINCIPAL;
968 		goto error;
969     }
970 	if (!(name = get_clnt_name(rqstp))) {
971 		ret.code = KADM5_FAILURE;
972 		goto error;
973 	}
974 
975     if (! cmp_gss_krb5_name(handle, name, arg->princ) &&
976 	(CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
977 					       name,
978 					       ACL_INQUIRE,
979 					       arg->princ,
980 					       NULL))) {
981 	 ret.code = KADM5_AUTH_GET;
982 
983 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
984 				    funcname,
985 				    prime_arg, client_name);
986 	 log_unauth(funcname, prime_arg, client_name, service_name,
987 		    client_addr(rqstp, buf));
988     } else {
989 	 if (handle->api_version == KADM5_API_VERSION_1) {
990 	      ret.code  = kadm5_get_principal_v1((void *)handle,
991 						 arg->princ, &e);
992 	      if(ret.code == KADM5_OK) {
993 		   memcpy(&ret.rec, e, sizeof(kadm5_principal_ent_rec_v1));
994 		   free(e);
995 	      }
996 	 } else {
997 	      ret.code  = kadm5_get_principal((void *)handle,
998 					      arg->princ, &ret.rec,
999 					      arg->mask);
1000 	 }
1001 
1002 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1003 				funcname,
1004 				prime_arg, client_name, ret.code);
1005 	 log_done(funcname, prime_arg,
1006 		((ret.code == 0) ? "success" : error_message(ret.code)),
1007 		client_name, service_name, client_addr(rqstp, buf));
1008     }
1009 
1010 error:
1011 	if (name)
1012     	gss_release_name(&min_stat, &name);
1013     free_server_handle(handle);
1014     if (prime_arg)
1015     	free(prime_arg);
1016     if (client_name)
1017     	free(client_name);
1018     if (service_name)
1019     	free(service_name);
1020     return &ret;
1021 }
1022 
1023 gprincs_ret *
1024 get_princs_1_svc(gprincs_arg *arg, struct svc_req *rqstp)
1025 {
1026     static gprincs_ret		    ret;
1027     char			    *prime_arg = NULL;
1028     char *client_name = NULL, *service_name = NULL;
1029     OM_uint32			    min_stat;
1030     kadm5_server_handle_t handle;
1031     gss_name_t name = NULL;
1032 
1033     xdr_free(xdr_gprincs_ret, (char *) &ret);
1034 
1035     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1036 	 return &ret;
1037 
1038     if ((ret.code = check_handle((void *)handle)))
1039 		goto error;
1040     ret.api_version = handle->api_version;
1041 
1042     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1043 	 ret.code = KADM5_FAILURE;
1044 		goto error;
1045     }
1046     prime_arg = arg->exp;
1047     if (prime_arg == NULL)
1048 	 prime_arg = "*";
1049 
1050 	if (!(name = get_clnt_name(rqstp))) {
1051 		ret.code = KADM5_FAILURE;
1052 		goto error;
1053 	}
1054 
1055     if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
1056 					      name,
1057 					      ACL_LIST,
1058 					      NULL,
1059 					      NULL)) {
1060 	 ret.code = KADM5_AUTH_LIST;
1061 
1062 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
1063 				    "kadm5_get_principals",
1064 				    prime_arg, client_name);
1065 	 log_unauth("kadm5_get_principals", prime_arg, client_name,
1066 		    service_name, client_addr(rqstp, buf));
1067     } else {
1068 	 ret.code  = kadm5_get_principals((void *)handle,
1069 					       arg->exp, &ret.princs,
1070 					       &ret.count);
1071 
1072 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1073 				"kadm5_get_principals",
1074 				prime_arg, client_name, ret.code);
1075 	 log_done("kadm5_get_principals", prime_arg,
1076 		((ret.code == 0) ? "success" : error_message(ret.code)),
1077 		client_name, service_name, client_addr(rqstp, buf));
1078 	}
1079 
1080 error:
1081 	if (name)
1082 		gss_release_name(&min_stat, &name);
1083 	free_server_handle(handle);
1084 	if (client_name)
1085 		free(client_name);
1086 	if (service_name)
1087 		free(service_name);
1088 	return (&ret);
1089 }
1090 
1091 generic_ret *
1092 chpass_principal_1_svc(chpass_arg *arg, struct svc_req *rqstp)
1093 {
1094     static generic_ret		    ret;
1095     char			    *prime_arg = NULL;
1096     char *client_name = NULL, *service_name = NULL;
1097     OM_uint32 min_stat;
1098     kadm5_server_handle_t	    handle;
1099     gss_name_t name = NULL;
1100 
1101     xdr_free(xdr_generic_ret, (char *) &ret);
1102 
1103     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1104 	 return &ret;
1105 
1106     if ((ret.code = check_handle((void *)handle)))
1107 		goto error;
1108     ret.api_version = handle->api_version;
1109 
1110     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1111 	 ret.code = KADM5_FAILURE;
1112 		goto error;
1113     }
1114     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
1115 	 ret.code = KADM5_BAD_PRINCIPAL;
1116 		goto error;
1117 	}
1118 	if (!(name = get_clnt_name(rqstp))) {
1119 		ret.code = KADM5_FAILURE;
1120 		goto error;
1121 	}
1122 
1123     if (cmp_gss_krb5_name(handle, name, arg->princ)) {
1124 	 ret.code = chpass_principal_wrapper_3((void *)handle, arg->princ,
1125 					       FALSE, 0, NULL, arg->pass);
1126     } else if (!(CHANGEPW_SERVICE(rqstp)) &&
1127 	       kadm5int_acl_check(handle->context, name,
1128 			 ACL_CHANGEPW, arg->princ, NULL)) {
1129 	 ret.code = kadm5_chpass_principal((void *)handle, arg->princ,
1130 						arg->pass);
1131     } else {
1132 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
1133 				    "kadm5_chpass_principal",
1134 				    prime_arg, client_name);
1135 	 log_unauth("kadm5_chpass_principal", prime_arg, client_name,
1136 		    service_name, client_addr(rqstp, buf));
1137 	 ret.code = KADM5_AUTH_CHANGEPW;
1138     }
1139 
1140     if(ret.code != KADM5_AUTH_CHANGEPW) {
1141 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1142 				"kadm5_chpass_principal",
1143 				prime_arg, client_name, ret.code);
1144 	log_done("kadm5_chpass_principal", prime_arg,
1145 		((ret.code == 0) ? "success" : error_message(ret.code)),
1146 		client_name, service_name, client_addr(rqstp, buf));
1147     }
1148 
1149 error:
1150 	if (name)
1151 		gss_release_name(&min_stat, &name);
1152 	free_server_handle(handle);
1153 	if (prime_arg)
1154 		free(prime_arg);
1155 	if (client_name)
1156 		free(client_name);
1157 	if (service_name)
1158 		free(service_name);
1159 	return (&ret);
1160 }
1161 
1162 generic_ret *
1163 chpass_principal3_1_svc(chpass3_arg *arg, struct svc_req *rqstp)
1164 {
1165     static generic_ret		    ret;
1166     char			    *prime_arg = NULL;
1167     char       			    *client_name = NULL,
1168 				    *service_name = NULL;
1169     OM_uint32			    min_stat;
1170     kadm5_server_handle_t	    handle;
1171     gss_name_t name = NULL;
1172 
1173     xdr_free(xdr_generic_ret, (char *) &ret);
1174 
1175     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1176 	 return &ret;
1177 
1178     if ((ret.code = check_handle((void *)handle)))
1179 	goto error;
1180     ret.api_version = handle->api_version;
1181 
1182     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1183 	 ret.code = KADM5_FAILURE;
1184 	goto error;
1185     }
1186     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
1187 	 ret.code = KADM5_BAD_PRINCIPAL;
1188 	goto error;
1189     }
1190     if (!(name = get_clnt_name(rqstp))) {
1191 	ret.code = KADM5_FAILURE;
1192 	goto error;
1193     }
1194 
1195     if (cmp_gss_krb5_name(handle, name, arg->princ)) {
1196 	 ret.code = chpass_principal_wrapper_3((void *)handle, arg->princ,
1197 					       arg->keepold,
1198 					       arg->n_ks_tuple,
1199 					       arg->ks_tuple,
1200 					       arg->pass);
1201     } else if (!(CHANGEPW_SERVICE(rqstp)) &&
1202 	       kadm5int_acl_check(handle->context, name,
1203 			 ACL_CHANGEPW, arg->princ, NULL)) {
1204 	 ret.code = kadm5_chpass_principal_3((void *)handle, arg->princ,
1205 					     arg->keepold,
1206 					     arg->n_ks_tuple,
1207 					     arg->ks_tuple,
1208 					     arg->pass);
1209     } else {
1210 	 log_unauth("kadm5_chpass_principal", prime_arg,
1211 		client_name, service_name, client_addr(rqstp, buf));
1212 	 ret.code = KADM5_AUTH_CHANGEPW;
1213     }
1214 
1215     if(ret.code != KADM5_AUTH_CHANGEPW) {
1216 	log_done("kadm5_chpass_principal", prime_arg,
1217 		((ret.code == 0) ? "success" : error_message(ret.code)),
1218 		client_name, service_name, client_addr(rqstp, buf));
1219     }
1220 
1221 error:
1222     if (name)
1223     	gss_release_name(&min_stat, &name);
1224     free_server_handle(handle);
1225     if (client_name)
1226     	free(client_name);
1227     if (service_name)
1228     	free(service_name);
1229     if (prime_arg)
1230     	free(prime_arg);
1231     return (&ret);
1232 }
1233 
1234 #ifdef SUNWOFF
1235 generic_ret *
1236 setv4key_principal_1_svc(setv4key_arg *arg, struct svc_req *rqstp)
1237 {
1238     static generic_ret		    ret;
1239     char			    *prime_arg = NULL;
1240     char 			    *client_name = NULL,
1241 				    *service_name = NULL;
1242     OM_uint32			    min_stat;
1243     kadm5_server_handle_t	    handle;
1244     gss_name_t name = NULL;
1245 
1246     xdr_free(xdr_generic_ret, (char *) &ret);
1247 
1248     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1249 	 return &ret;
1250 
1251     if ((ret.code = check_handle((void *)handle)))
1252 	goto error;
1253     ret.api_version = handle->api_version;
1254 
1255     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1256 	 ret.code = KADM5_FAILURE;
1257 	goto error;
1258     }
1259     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
1260 	 ret.code = KADM5_BAD_PRINCIPAL;
1261 	goto error;
1262     }
1263     if (!(name = get_clnt_name(rqstp))) {
1264 	ret.code = KADM5_FAILURE;
1265 	goto error;
1266     }
1267 
1268     if (!(CHANGEPW_SERVICE(rqstp)) &&
1269 	       kadm5int_acl_check(handle->context, name,
1270 			 ACL_SETKEY, arg->princ, NULL)) {
1271 	 ret.code = kadm5_setv4key_principal((void *)handle, arg->princ,
1272 					     arg->keyblock);
1273     } else {
1274 	 log_unauth("kadm5_setv4key_principal", prime_arg,
1275 		client_name, service_name, client_addr(rqstp, buf));
1276 	 ret.code = KADM5_AUTH_SETKEY;
1277     }
1278 
1279     if(ret.code != KADM5_AUTH_SETKEY) {
1280 	log_done("kadm5_setv4key_principal", prime_arg,
1281 		((ret.code == 0) ? "success" : error_message(ret.code)),
1282 		client_name, service_name, client_addr(rqstp, buf));
1283     }
1284 
1285 error:
1286     if (name)
1287 	gss_release_name(&min_stat, &name);
1288     free_server_handle(handle);
1289     if (client_name)
1290 	free(client_name);
1291     if (service_name)
1292 	free(service_name);
1293     if (prime_arg)
1294 	free(prime_arg);
1295     return (&ret);
1296 }
1297 #endif
1298 
1299 generic_ret *
1300 setkey_principal_1_svc(setkey_arg *arg, struct svc_req *rqstp)
1301 {
1302     static generic_ret		    ret;
1303     char			    *prime_arg;
1304     char			    *client_name,
1305 				    *service_name;
1306     OM_uint32			    min_stat;
1307     kadm5_server_handle_t	    handle;
1308     gss_name_t name;
1309 
1310     xdr_free(xdr_generic_ret, (char *) &ret);
1311 
1312     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1313 	 return &ret;
1314 
1315     if ((ret.code = check_handle((void *)handle)))
1316 	goto error;
1317     ret.api_version = handle->api_version;
1318 
1319     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1320 	 ret.code = KADM5_FAILURE;
1321 	goto error;
1322     }
1323     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
1324 	 ret.code = KADM5_BAD_PRINCIPAL;
1325 	goto error;
1326     }
1327     if (!(name = get_clnt_name(rqstp))) {
1328 	 ret.code = KADM5_FAILURE;
1329 	goto error;
1330     }
1331 
1332     if (!(CHANGEPW_SERVICE(rqstp)) &&
1333 	       kadm5int_acl_check(handle->context, name, ACL_SETKEY, arg->princ, NULL)) {
1334 	 ret.code = kadm5_setkey_principal((void *)handle, arg->princ,
1335 					   arg->keyblocks, arg->n_keys);
1336     } else {
1337 	 log_unauth("kadm5_setkey_principal", prime_arg,
1338 		client_name, service_name, client_addr(rqstp, buf));
1339 	 ret.code = KADM5_AUTH_SETKEY;
1340     }
1341 
1342     if(ret.code != KADM5_AUTH_SETKEY) {
1343 	log_done("kadm5_setkey_principal", prime_arg,
1344 		((ret.code == 0) ? "success" : error_message(ret.code)),
1345 		client_name, service_name, client_addr(rqstp, buf));
1346     }
1347 
1348 error:
1349     if (name)
1350 	gss_release_name(&min_stat, &name);
1351     free_server_handle(handle);
1352     if (client_name)
1353     	free(client_name);
1354     if (service_name)
1355     	free(service_name);
1356     if (prime_arg)
1357     	free(prime_arg);
1358     return (&ret);
1359 }
1360 
1361 generic_ret *
1362 setkey_principal3_1_svc(setkey3_arg *arg, struct svc_req *rqstp)
1363 {
1364     static generic_ret		    ret;
1365     char			    *prime_arg = NULL;
1366     char			    *client_name = NULL,
1367 				    *service_name = NULL;
1368     OM_uint32			    min_stat;
1369     kadm5_server_handle_t	    handle;
1370     gss_name_t name = NULL;
1371 
1372     xdr_free(xdr_generic_ret, (char *) &ret);
1373 
1374     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1375 	 return &ret;
1376 
1377     if ((ret.code = check_handle((void *)handle)))
1378 	goto error;
1379     ret.api_version = handle->api_version;
1380 
1381     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1382 	 ret.code = KADM5_FAILURE;
1383 	goto error;
1384     }
1385     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
1386 	 ret.code = KADM5_BAD_PRINCIPAL;
1387 	goto error;
1388     }
1389     if (!(name = get_clnt_name(rqstp))) {
1390 	 ret.code = KADM5_FAILURE;
1391 	goto error;
1392     }
1393 
1394     if (!(CHANGEPW_SERVICE(rqstp)) &&
1395 	       kadm5int_acl_check(handle->context, name,
1396 			 ACL_SETKEY, arg->princ, NULL)) {
1397 	 ret.code = kadm5_setkey_principal_3((void *)handle, arg->princ,
1398 					     arg->keepold,
1399 					     arg->n_ks_tuple,
1400 					     arg->ks_tuple,
1401 					     arg->keyblocks, arg->n_keys);
1402     } else {
1403 	 log_unauth("kadm5_setkey_principal", prime_arg,
1404 		client_name, service_name, client_addr(rqstp, buf));
1405 	 ret.code = KADM5_AUTH_SETKEY;
1406     }
1407 
1408     if(ret.code != KADM5_AUTH_SETKEY) {
1409 	log_done("kadm5_setkey_principal", prime_arg,
1410 		((ret.code == 0) ? "success" : error_message(ret.code)),
1411 		client_name, service_name, client_addr(rqstp, buf));
1412     }
1413 
1414 error:
1415     if (name)
1416 	gss_release_name(&min_stat, &name);
1417     free_server_handle(handle);
1418     if (client_name)
1419 	free(client_name);
1420     if (service_name)
1421     	free(service_name);
1422     if (prime_arg)
1423     	free(prime_arg);
1424     return &ret;
1425 }
1426 
1427 chrand_ret *
1428 chrand_principal_1_svc(chrand_arg *arg, struct svc_req *rqstp)
1429 {
1430     static chrand_ret		ret;
1431     krb5_keyblock		*k;
1432     int				nkeys;
1433     char			*prime_arg = NULL, *funcname;
1434     char *client_name = NULL, *service_name = NULL;
1435     OM_uint32			min_stat;
1436     kadm5_server_handle_t	handle;
1437     gss_name_t name = NULL;
1438 
1439     xdr_free(xdr_chrand_ret, (char *) &ret);
1440 
1441     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1442 	 return &ret;
1443 
1444     if ((ret.code = check_handle((void *)handle)))
1445 		goto error;
1446 
1447     ret.api_version = handle->api_version;
1448 
1449     funcname = handle->api_version == KADM5_API_VERSION_1 ?
1450 	 "kadm5_randkey_principal (V1)" : "kadm5_randkey_principal";
1451 
1452     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1453 	 ret.code = KADM5_FAILURE;
1454 		goto error;
1455     }
1456     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
1457 	 ret.code = KADM5_BAD_PRINCIPAL;
1458 		goto error;
1459     }
1460 	if (!(name = get_clnt_name(rqstp))) {
1461 		ret.code = KADM5_FAILURE;
1462 		goto error;
1463 	}
1464 
1465     if (cmp_gss_krb5_name(handle, name, arg->princ)) {
1466 	 ret.code = randkey_principal_wrapper((void *)handle, arg->princ, &k,
1467 						&nkeys);
1468     } else if (!(CHANGEPW_SERVICE(rqstp)) &&
1469 	       kadm5int_acl_check(handle->context, name,
1470 			 ACL_CHANGEPW, arg->princ, NULL)) {
1471 	 ret.code = kadm5_randkey_principal((void *)handle, arg->princ,
1472 					    &k, &nkeys);
1473     } else {
1474 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
1475 				    funcname, prime_arg, client_name);
1476 	 log_unauth(funcname, prime_arg,
1477 		client_name, service_name, client_addr(rqstp, buf));
1478 	 ret.code = KADM5_AUTH_CHANGEPW;
1479     }
1480 
1481     if(ret.code == KADM5_OK) {
1482 	 if (handle->api_version == KADM5_API_VERSION_1) {
1483 	      krb5_copy_keyblock_contents(handle->context, k, &ret.key);
1484 	      krb5_free_keyblock(handle->context, k);
1485 	 } else {
1486 	      ret.keys = k;
1487 	      ret.n_keys = nkeys;
1488 	 }
1489     }
1490 
1491     if(ret.code != KADM5_AUTH_CHANGEPW) {
1492 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1493 				funcname, prime_arg, client_name, ret.code);
1494 	log_done(funcname, prime_arg,
1495 		((ret.code == 0) ? "success" : error_message(ret.code)),
1496 		client_name, service_name, client_addr(rqstp, buf));
1497      }
1498 
1499 error:
1500 	if (name)
1501 		gss_release_name(&min_stat, &name);
1502 	free_server_handle(handle);
1503 	if (prime_arg)
1504     	free(prime_arg);
1505     if (client_name)
1506     	free(client_name);
1507     if (service_name)
1508     	free(service_name);
1509     return &ret;
1510 }
1511 
1512 chrand_ret *
1513 chrand_principal3_1_svc(chrand3_arg *arg, struct svc_req *rqstp)
1514 {
1515     static chrand_ret		ret;
1516     krb5_keyblock		*k;
1517     int				nkeys;
1518     char			*prime_arg = NULL, *funcname;
1519     char			*client_name = NULL,
1520 	    			*service_name = NULL;
1521     OM_uint32			min_stat;
1522     kadm5_server_handle_t	handle;
1523     gss_name_t name = NULL;
1524 
1525     xdr_free(xdr_chrand_ret, (char *) &ret);
1526 
1527     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1528 	 return &ret;
1529 
1530     if ((ret.code = check_handle((void *)handle)))
1531 	goto error;
1532     ret.api_version = handle->api_version;
1533 
1534     funcname = handle->api_version == KADM5_API_VERSION_1 ?
1535 	 "kadm5_randkey_principal (V1)" : "kadm5_randkey_principal";
1536 
1537     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1538 	ret.code = KADM5_FAILURE;
1539 	goto error;
1540     }
1541     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
1542 	 ret.code = KADM5_BAD_PRINCIPAL;
1543 	goto error;
1544     }
1545     if (!(name = get_clnt_name(rqstp))) {
1546 	ret.code = KADM5_FAILURE;
1547 	goto error;
1548     }
1549 
1550     if (cmp_gss_krb5_name(handle, name, arg->princ)) {
1551 	 ret.code = randkey_principal_wrapper_3((void *)handle, arg->princ,
1552 						arg->keepold,
1553 						arg->n_ks_tuple,
1554 						arg->ks_tuple,
1555 						&k, &nkeys);
1556     } else if (!(CHANGEPW_SERVICE(rqstp)) &&
1557 	       kadm5int_acl_check(handle->context, name,
1558 			 ACL_CHANGEPW, arg->princ, NULL)) {
1559 	 ret.code = kadm5_randkey_principal_3((void *)handle, arg->princ,
1560 					      arg->keepold,
1561 					      arg->n_ks_tuple,
1562 					      arg->ks_tuple,
1563 					      &k, &nkeys);
1564     } else {
1565 	 log_unauth(funcname, prime_arg,
1566 		client_name, service_name, client_addr(rqstp, buf));
1567 	 ret.code = KADM5_AUTH_CHANGEPW;
1568     }
1569 
1570     if(ret.code == KADM5_OK) {
1571 	 if (handle->api_version == KADM5_API_VERSION_1) {
1572 	      krb5_copy_keyblock_contents(handle->context, k, &ret.key);
1573 	      krb5_free_keyblock(handle->context, k);
1574 	 } else {
1575 	      ret.keys = k;
1576 	      ret.n_keys = nkeys;
1577 	 }
1578     }
1579 
1580     if(ret.code != KADM5_AUTH_CHANGEPW) {
1581 	/* Solaris Kerberos: Better error messages */
1582 	log_done(funcname, prime_arg, ((ret.code == 0) ? "success" :
1583 	    krb5_get_error_message(handle->context, ret.code)),
1584 	    client_name, service_name, client_addr(rqstp, buf));
1585     }
1586 
1587 error:
1588     if (name)
1589 	gss_release_name(&min_stat, &name);
1590     free_server_handle(handle);
1591     if (client_name)
1592 	free(client_name);
1593     if (service_name)
1594 	free(service_name);
1595     if (prime_arg)
1596 	free(prime_arg);
1597     return (&ret);
1598 }
1599 
1600 generic_ret *
1601 create_policy_1_svc(cpol_arg *arg, struct svc_req *rqstp)
1602 {
1603     static generic_ret		    ret;
1604     char			    *prime_arg = NULL;
1605     char *client_name = NULL, *service_name = NULL;
1606     OM_uint32			    min_stat;
1607     kadm5_server_handle_t	    handle;
1608     gss_name_t name = NULL;
1609 
1610     xdr_free(xdr_generic_ret, (char *) &ret);
1611 
1612     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1613 	 return &ret;
1614 
1615     if ((ret.code = check_handle((void *)handle)))
1616 		goto error;
1617 
1618     ret.api_version = handle->api_version;
1619 
1620     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1621 	 ret.code = KADM5_FAILURE;
1622 		goto error;
1623     }
1624     prime_arg = arg->rec.policy;
1625 
1626 	if (!(name = get_clnt_name(rqstp))) {
1627 		ret.code = KADM5_FAILURE;
1628 		goto error;
1629 	}
1630 
1631     if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
1632 					      name,
1633 					      ACL_ADD, NULL, NULL)) {
1634 	 ret.code = KADM5_AUTH_ADD;
1635 
1636 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
1637 				    "kadm5_create_policy",
1638 				    prime_arg, client_name);
1639 	 log_unauth("kadm5_create_policy", prime_arg,
1640 		client_name, service_name, client_addr(rqstp, buf));
1641 
1642     } else {
1643 	 ret.code = kadm5_create_policy((void *)handle, &arg->rec,
1644 					     arg->mask);
1645 
1646 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1647 				"kadm5_create_policy",
1648 				prime_arg, client_name, ret.code);
1649 	 log_done("kadm5_create_policy",
1650 		((prime_arg == NULL) ? "(null)" : prime_arg),
1651 		((ret.code == 0) ? "success" : error_message(ret.code)),
1652 		client_name, service_name, client_addr(rqstp, buf));
1653     }
1654 
1655 error:
1656 	if (name)
1657 		gss_release_name(&min_stat, &name);
1658     free_server_handle(handle);
1659     if (client_name)
1660     	free(client_name);
1661     if (service_name)
1662     	free(service_name);
1663     return &ret;
1664 }
1665 
1666 generic_ret *
1667 delete_policy_1_svc(dpol_arg *arg, struct svc_req *rqstp)
1668 {
1669     static generic_ret		    ret;
1670     char			    *prime_arg = NULL;
1671     char *client_name = NULL, *service_name = NULL;
1672     OM_uint32			    min_stat;
1673     kadm5_server_handle_t	    handle;
1674     gss_name_t name = NULL;
1675 
1676     xdr_free(xdr_generic_ret, (char *) &ret);
1677 
1678     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1679 	 return &ret;
1680 
1681     if ((ret.code = check_handle((void *)handle)))
1682 		goto error;
1683     ret.api_version = handle->api_version;
1684 
1685     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1686 	 ret.code = KADM5_FAILURE;
1687 		goto error;
1688     }
1689     prime_arg = arg->name;
1690 
1691 	if (!(name = get_clnt_name(rqstp))) {
1692 		ret.code = KADM5_FAILURE;
1693 		goto error;
1694 	}
1695 
1696     if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
1697 						name,
1698 					      ACL_DELETE, NULL, NULL)) {
1699 
1700 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
1701 				    "kadm5_delete_policy",
1702 				    prime_arg, client_name);
1703 	 log_unauth("kadm5_delete_policy", prime_arg,
1704 		client_name, service_name, client_addr(rqstp, buf));
1705 	 ret.code = KADM5_AUTH_DELETE;
1706     } else {
1707 	 ret.code = kadm5_delete_policy((void *)handle, arg->name);
1708 
1709 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1710 				"kadm5_delete_policy",
1711 				prime_arg, client_name, ret.code);
1712 	 log_done("kadm5_delete_policy",
1713 		((prime_arg == NULL) ? "(null)" : prime_arg),
1714 		((ret.code == 0) ? "success" : error_message(ret.code)),
1715 		client_name, service_name, client_addr(rqstp, buf));
1716     }
1717 
1718 error:
1719 	if (name)
1720 		gss_release_name(&min_stat, &name);
1721     free_server_handle(handle);
1722     if (client_name)
1723     free(client_name);
1724     if (service_name)
1725     free(service_name);
1726     return &ret;
1727 }
1728 
1729 generic_ret *
1730 modify_policy_1_svc(mpol_arg *arg, struct svc_req *rqstp)
1731 {
1732     static generic_ret		    ret;
1733     char			    *prime_arg = NULL;
1734     char *client_name = NULL, *service_name = NULL;
1735     OM_uint32 min_stat;
1736     kadm5_server_handle_t	    handle;
1737     gss_name_t name = NULL;
1738 
1739     xdr_free(xdr_generic_ret, (char *) &ret);
1740 
1741     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1742 	 return &ret;
1743 
1744     if ((ret.code = check_handle((void *)handle)))
1745 		goto error;
1746     ret.api_version = handle->api_version;
1747 
1748     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1749 	 ret.code = KADM5_FAILURE;
1750 		goto error;
1751     }
1752     prime_arg = arg->rec.policy;
1753 
1754     if (!(name = get_clnt_name(rqstp))) {
1755 	 ret.code = KADM5_FAILURE;
1756 		goto error;
1757     }
1758 
1759     if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
1760 						name,
1761 					      ACL_MODIFY, NULL, NULL)) {
1762 
1763 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
1764 				    "kadm5_modify_policy",
1765 				    prime_arg, client_name);
1766 	 log_unauth("kadm5_modify_policy", prime_arg,
1767 		client_name, service_name, client_addr(rqstp, buf));
1768 	 ret.code = KADM5_AUTH_MODIFY;
1769     } else {
1770 	 ret.code = kadm5_modify_policy((void *)handle, &arg->rec,
1771 					     arg->mask);
1772 
1773 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1774 				"kadm5_modify_policy",
1775 				prime_arg, client_name, ret.code);
1776 	 log_done("kadm5_modify_policy",
1777 		((prime_arg == NULL) ? "(null)" : prime_arg),
1778 		((ret.code == 0) ? "success" : error_message(ret.code)),
1779 		client_name, service_name, client_addr(rqstp, buf));
1780    }
1781 
1782 error:
1783 	if (name)
1784 		gss_release_name(&min_stat, &name);
1785 	free_server_handle(handle);
1786 	if (client_name)
1787 		free(client_name);
1788 	if (service_name)
1789 		free(service_name);
1790 	return (&ret);
1791 }
1792 
1793 gpol_ret *
1794 get_policy_1_svc(gpol_arg *arg, struct svc_req *rqstp)
1795 {
1796     static gpol_ret		ret;
1797     kadm5_ret_t		ret2;
1798     char *prime_arg = NULL, *funcname;
1799     char *client_name = NULL, *service_name = NULL;
1800     OM_uint32 min_stat;
1801     kadm5_policy_ent_t	e;
1802     kadm5_principal_ent_rec	caller_ent;
1803     krb5_principal caller;
1804     kadm5_server_handle_t	handle;
1805   gss_name_t name = NULL;
1806 
1807     xdr_free(xdr_gpol_ret, (char *) &ret);
1808 
1809     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1810 	 return &ret;
1811 
1812     if ((ret.code = check_handle((void *) handle)))
1813 		goto error;
1814 
1815     ret.api_version = handle->api_version;
1816 
1817     funcname = handle->api_version == KADM5_API_VERSION_1 ?
1818 	 "kadm5_get_policy (V1)" : "kadm5_get_policy";
1819 
1820     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1821 	 ret.code = KADM5_FAILURE;
1822 		goto error;
1823     }
1824     prime_arg = arg->name;
1825 	ret.code = KADM5_AUTH_GET;
1826 
1827 	if (!(name = get_clnt_name(rqstp))) {
1828 		ret.code = KADM5_FAILURE;
1829 		goto error;
1830 	}
1831 
1832     if (!CHANGEPW_SERVICE(rqstp) && kadm5int_acl_check(handle->context,
1833 						name,
1834 						ACL_INQUIRE, NULL, NULL))
1835 		ret.code = KADM5_OK;
1836 	else {
1837 		ret.code = kadm5_get_principal(handle->lhandle,
1838 		    handle->current_caller,
1839 		    &caller_ent,
1840 		    KADM5_PRINCIPAL_NORMAL_MASK);
1841 		if (ret.code == KADM5_OK) {
1842 			if (caller_ent.aux_attributes & KADM5_POLICY &&
1843 			    strcmp(caller_ent.policy, arg->name) == 0) {
1844 		   ret.code = KADM5_OK;
1845 	      } else ret.code = KADM5_AUTH_GET;
1846 	      ret2 = kadm5_free_principal_ent(handle->lhandle,
1847 					      &caller_ent);
1848 	      ret.code = ret.code ? ret.code : ret2;
1849 	 }
1850     }
1851 
1852     if (ret.code == KADM5_OK) {
1853 	 if (handle->api_version == KADM5_API_VERSION_1) {
1854 	      ret.code  = kadm5_get_policy_v1((void *)handle, arg->name, &e);
1855 	      if(ret.code == KADM5_OK) {
1856 		   memcpy(&ret.rec, e, sizeof(kadm5_policy_ent_rec));
1857 		   free(e);
1858 	      }
1859 	 } else {
1860 	      ret.code = kadm5_get_policy((void *)handle, arg->name,
1861 					  &ret.rec);
1862 	 }
1863 
1864 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1865 				funcname, prime_arg, client_name, ret.code);
1866 	 log_done(funcname, ((prime_arg == NULL) ? "(null)" : prime_arg),
1867 		((ret.code == 0) ? "success" : error_message(ret.code)),
1868 		client_name, service_name, client_addr(rqstp, buf));
1869 	} else {
1870 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
1871 				    funcname, prime_arg, client_name);
1872 	 log_unauth(funcname, prime_arg, client_name,
1873 		service_name, client_addr(rqstp, buf));
1874     }
1875 
1876 error:
1877 	if (name)
1878 		gss_release_name(&min_stat, &name);
1879 	free_server_handle(handle);
1880 	if (client_name)
1881 		free(client_name);
1882 	if (service_name)
1883 		free(service_name);
1884 	return (&ret);
1885 
1886 }
1887 
1888 gpols_ret *
1889 get_pols_1_svc(gpols_arg *arg, struct svc_req *rqstp)
1890 {
1891     static gpols_ret		    ret;
1892     char			    *prime_arg = NULL;
1893     char *client_name = NULL, *service_name = NULL;
1894     OM_uint32 min_stat;
1895     kadm5_server_handle_t handle;
1896     gss_name_t name = NULL;
1897 
1898     xdr_free(xdr_gpols_ret, (char *) &ret);
1899 
1900     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1901 	 return &ret;
1902 
1903     if ((ret.code = check_handle((void *)handle)))
1904 		goto error;
1905 
1906     ret.api_version = handle->api_version;
1907 
1908     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1909 	 ret.code = KADM5_FAILURE;
1910 	goto error;
1911     }
1912     prime_arg = arg->exp;
1913     if (prime_arg == NULL)
1914 	 prime_arg = "*";
1915 
1916 	if (!(name = get_clnt_name(rqstp))) {
1917 		ret.code = KADM5_FAILURE;
1918 		goto error;
1919 	}
1920 
1921     if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
1922 					      name,
1923 					      ACL_LIST, NULL, NULL)) {
1924 	 ret.code = KADM5_AUTH_LIST;
1925 
1926 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
1927 				    "kadm5_get_policies",
1928 				    prime_arg, client_name);
1929 	 log_unauth("kadm5_get_policies", prime_arg,
1930 		client_name, service_name, client_addr(rqstp, buf));
1931     } else {
1932 	 ret.code  = kadm5_get_policies((void *)handle,
1933 		    arg->exp, &ret.pols,
1934 		    &ret.count);
1935 
1936 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1937 				"kadm5_get_policies",
1938 				prime_arg, client_name, ret.code);
1939 	 log_done("kadm5_get_policies", prime_arg,
1940 		((ret.code == 0) ? "success" : error_message(ret.code)),
1941 		client_name, service_name, client_addr(rqstp, buf));
1942     }
1943 
1944 error:
1945 	if (name)
1946 		gss_release_name(&min_stat, &name);
1947 	free_server_handle(handle);
1948 	if (client_name)
1949 		free(client_name);
1950 	if (service_name)
1951 		free(service_name);
1952 	return (&ret);
1953 }
1954 
1955 getprivs_ret * get_privs_1_svc(krb5_ui_4 *arg, struct svc_req *rqstp)
1956 {
1957      static getprivs_ret	    ret;
1958      char *client_name = NULL, *service_name = NULL;
1959      OM_uint32 min_stat;
1960      kadm5_server_handle_t handle;
1961      gss_name_t name = NULL;
1962 
1963      xdr_free(xdr_getprivs_ret, (char *) &ret);
1964 
1965      if ((ret.code = new_server_handle(*arg, rqstp, &handle)))
1966 	  return &ret;
1967 
1968      if ((ret.code = check_handle((void *)handle)))
1969 		goto error;
1970 
1971      ret.api_version = handle->api_version;
1972 
1973      if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1974 	  ret.code = KADM5_FAILURE;
1975 	  goto error;
1976      }
1977 	if (!(name = get_clnt_name(rqstp))) {
1978 		ret.code = KADM5_FAILURE;
1979 		goto error;
1980 	}
1981 
1982 	ret.code = __kadm5_get_priv((void *) handle, &ret.privs, name);
1983 
1984 	audit_kadmind_auth(rqstp->rq_xprt, l_port,
1985 			"kadm5_get_privs", NULL, client_name,
1986 			ret.code);
1987 	log_done("kadm5_get_privs", client_name,
1988 	    ((ret.code == 0) ? "success" : error_message(ret.code)),
1989 	    client_name, service_name, client_addr(rqstp, buf));
1990 
1991 error:
1992 	if (name)
1993 		gss_release_name(&min_stat, &name);
1994 	free_server_handle(handle);
1995 	if (client_name)
1996 		free(client_name);
1997 	if (service_name)
1998 		free(service_name);
1999 	return (&ret);
2000 }
2001 
2002 generic_ret *init_1_svc(krb5_ui_4 *arg, struct svc_req *rqstp)
2003 {
2004      static generic_ret		ret;
2005      char *client_name, *service_name;
2006      kadm5_server_handle_t handle;
2007      size_t clen, slen;
2008      char *cdots, *sdots;
2009 
2010      xdr_free(xdr_generic_ret, (char *) &ret);
2011 
2012      if ((ret.code = new_server_handle(*arg, rqstp, &handle)))
2013 	  return &ret;
2014      if (! (ret.code = check_handle((void *)handle))) {
2015 	 ret.api_version = handle->api_version;
2016      }
2017 
2018      free_server_handle(handle);
2019 
2020      if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
2021 	  ret.code = KADM5_FAILURE;
2022 	  return &ret;
2023      }
2024 
2025 	audit_kadmind_auth(rqstp->rq_xprt, l_port,
2026 			(ret.api_version == KADM5_API_VERSION_1 ?
2027 			"kadm5_init (V1)" : "kadm5_init"),
2028 			NULL, client_name, ret.code);
2029 
2030 	clen = strlen(client_name);
2031 	trunc_name(&clen, &cdots);
2032 	slen = strlen(service_name);
2033 	trunc_name(&slen, &sdots);
2034 	krb5_klog_syslog(LOG_NOTICE, "Request %s, %.*s%s, %s, "
2035 	    "client=%.*s%s, service=%.*s%s, addr=%s, flavor=%d",
2036 	    (ret.api_version == KADM5_API_VERSION_1 ?
2037 	    "kadm5_init (V1)" : "kadm5_init"),
2038 	    clen, client_name, cdots,
2039 	    (ret.code == 0) ? "success" : error_message(ret.code),
2040 	    clen, client_name, cdots,
2041 	    slen, service_name, sdots,
2042 	    client_addr(rqstp, buf),
2043 	    rqstp->rq_cred.oa_flavor);
2044 	free(client_name);
2045 	free(service_name);
2046 
2047 	return (&ret);
2048 }
2049