xref: /titanic_50/usr/src/cmd/krb5/kadmin/server/server_stubs.c (revision ae115bc77f6fcde83175c75b4206dc2e50747966)
1 /*
2  * Copyright 2006 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 generic_ret *
448 create_principal_1_svc(cprinc_arg *arg, struct svc_req *rqstp)
449 {
450     static generic_ret		ret;
451     char			*prime_arg = NULL;
452     char *client_name = NULL, *service_name = NULL;
453     int policy_migrate = 0;
454 
455     OM_uint32			minor_stat;
456     kadm5_server_handle_t	handle;
457     kadm5_ret_t retval;
458     restriction_t		*rp;
459     gss_name_t name = NULL;
460 
461     xdr_free(xdr_generic_ret, (char *) &ret);
462 
463     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
464 	 return &ret;
465 
466     if ((ret.code = check_handle((void *)handle)))
467 		goto error;
468     ret.api_version = handle->api_version;
469 
470     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
471 	 ret.code = KADM5_FAILURE;
472 	goto error;
473     }
474     if (krb5_unparse_name(handle->context, arg->rec.principal, &prime_arg)) {
475 	 ret.code = KADM5_BAD_PRINCIPAL;
476 	 goto error;
477     }
478 	if (!(name = get_clnt_name(rqstp))) {
479 		ret.code = KADM5_FAILURE;
480 		goto error;
481 	}
482 
483 	if (kadm5int_acl_check(handle->context, name, ACL_MIGRATE,
484 	    arg->rec.principal, &rp) &&
485 	    verify_pam_pw(prime_arg, arg->passwd)) {
486 		policy_migrate = 1;
487 	}
488 
489     if (CHANGEPW_SERVICE(rqstp)
490 	|| (!kadm5int_acl_check(handle->context, name, ACL_ADD,
491 			arg->rec.principal, &rp) &&
492 		!(policy_migrate))
493 	|| kadm5int_acl_impose_restrictions(handle->context,
494 				   &arg->rec, &arg->mask, rp)) {
495 	 ret.code = KADM5_AUTH_ADD;
496 
497 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
498 				    "kadm5_create_principal",
499 				    prime_arg, client_name);
500 	 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_create_principal",
501 		prime_arg, client_name,
502 			service_name, client_addr(rqstp, buf));
503     } else {
504 	 ret.code = kadm5_create_principal((void *)handle,
505 						&arg->rec, arg->mask,
506 						arg->passwd);
507 
508 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
509 				"kadm5_create_principal",
510 				prime_arg, client_name, ret.code);
511 	 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_create_principal",
512 		prime_arg,((ret.code == 0) ? "success" :
513 			   error_message(ret.code)),
514 		client_name, service_name, client_addr(rqstp, buf));
515 
516 		if (policy_migrate && (ret.code == 0)) {
517 			arg->rec.policy = strdup("default");
518 			if ((arg->mask & KADM5_PW_EXPIRATION)) {
519 				arg->mask = 0;
520 				arg->mask |= KADM5_POLICY;
521 				arg->mask |= KADM5_PW_EXPIRATION;
522 			} else {
523 				arg->mask = 0;
524 				arg->mask |= KADM5_POLICY;
525 			}
526 
527 			retval = kadm5_modify_principal((void *)handle,
528 					&arg->rec, arg->mask);
529 			krb5_klog_syslog(LOG_NOTICE, LOG_DONE,
530 				"kadm5_modify_principal",
531 				prime_arg, ((retval == 0) ? "success" :
532 				error_message(retval)), client_name,
533 				service_name, client_addr(rqstp, buf));
534 		}
535 	}
536 
537 error:
538     if (name)
539     	gss_release_name(&minor_stat, &name);
540     free_server_handle(handle);
541     if (prime_arg)
542     	free(prime_arg);
543     if (client_name)
544     	free(client_name);
545     if (service_name)
546     	free(service_name);
547     return (&ret);
548 }
549 
550 generic_ret *
551 create_principal3_1_svc(cprinc3_arg *arg, struct svc_req *rqstp)
552 {
553     static generic_ret		ret;
554     char			*prime_arg = NULL;
555     char			*client_name = NULL, *service_name = NULL;
556     int				policy_migrate = 0;
557 
558     OM_uint32			minor_stat;
559     kadm5_server_handle_t	handle;
560     kadm5_ret_t			retval;
561     restriction_t		*rp;
562     gss_name_t			name = NULL;
563 
564     xdr_free(xdr_generic_ret, (char *) &ret);
565 
566     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
567 	 return &ret;
568 
569     if ((ret.code = check_handle((void *)handle)))
570 	goto error;
571     ret.api_version = handle->api_version;
572 
573     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
574 	 ret.code = KADM5_FAILURE;
575 	goto error;
576     }
577     if (krb5_unparse_name(handle->context, arg->rec.principal, &prime_arg)) {
578 	 ret.code = KADM5_BAD_PRINCIPAL;
579 	goto error;
580     }
581     if (!(name = get_clnt_name(rqstp))) {
582 	ret.code = KADM5_FAILURE;
583 	goto error;
584     }
585 
586     if (kadm5int_acl_check(handle->context, name, ACL_MIGRATE,
587 		arg->rec.principal, &rp) &&
588 		verify_pam_pw(prime_arg, arg->passwd)) {
589 	policy_migrate = 1;
590     }
591 
592     if (CHANGEPW_SERVICE(rqstp)
593 	|| (!kadm5int_acl_check(handle->context, name, ACL_ADD,
594 			arg->rec.principal, &rp) &&
595 	    !(policy_migrate))
596 	|| kadm5int_acl_impose_restrictions(handle->context,
597 				   &arg->rec, &arg->mask, rp)) {
598 	 ret.code = KADM5_AUTH_ADD;
599 	 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_create_principal",
600 		prime_arg, client_name, service_name,
601 		client_addr(rqstp, buf));
602     } else {
603 	 ret.code = kadm5_create_principal_3((void *)handle,
604 					     &arg->rec, arg->mask,
605 					     arg->n_ks_tuple,
606 					     arg->ks_tuple,
607 					     arg->passwd);
608 	 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_create_principal",
609 		prime_arg,((ret.code == 0) ? "success" :
610 			   error_message(ret.code)),
611 			  client_name, service_name,
612 			  client_addr(rqstp, buf));
613 
614 	 if (policy_migrate && (ret.code == 0)) {
615 	 	arg->rec.policy = strdup("default");
616 	 	if ((arg->mask & KADM5_PW_EXPIRATION)) {
617 	 		arg->mask = 0;
618 	 		arg->mask |= KADM5_POLICY;
619 	 		arg->mask |= KADM5_PW_EXPIRATION;
620 	 	} else {
621 	 		arg->mask = 0;
622 	 		arg->mask |= KADM5_POLICY;
623 	 	}
624 
625 		retval = kadm5_modify_principal((void *)handle,
626 					   &arg->rec, arg->mask);
627 		krb5_klog_syslog(LOG_NOTICE, LOG_DONE,
628 			    "kadm5_modify_principal",
629 			    prime_arg, ((retval == 0) ? "success" :
630 					error_message(retval)), client_name,
631 			    service_name, client_addr(rqstp, buf));
632 	 }
633     }
634 
635 error:
636     if (name)
637     	gss_release_name(&minor_stat, &name);
638     free_server_handle(handle);
639     if (client_name)
640     	free(client_name);
641     if (service_name)
642     	free(service_name);
643     if (prime_arg)
644     	free(prime_arg);
645     return &ret;
646 }
647 
648 generic_ret *
649 delete_principal_1_svc(dprinc_arg *arg, struct svc_req *rqstp)
650 {
651     static generic_ret		    ret;
652     char			    *prime_arg = NULL;
653     char *client_name = NULL, *service_name = NULL;
654     OM_uint32 min_stat;
655     kadm5_server_handle_t handle;
656     gss_name_t name = NULL;
657 
658     xdr_free(xdr_generic_ret, (char *) &ret);
659 
660     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
661 	 return &ret;
662 
663     if ((ret.code = check_handle((void *)handle)))
664 		goto error;
665     ret.api_version = handle->api_version;
666 
667     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
668 	 ret.code = KADM5_FAILURE;
669 		goto error;
670     }
671     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
672 	 ret.code = KADM5_BAD_PRINCIPAL;
673 		goto error;
674     }
675 	if (!(name = get_clnt_name(rqstp))) {
676 		ret.code = KADM5_FAILURE;
677 		goto error;
678 	}
679 
680     if (CHANGEPW_SERVICE(rqstp)
681 	|| !kadm5int_acl_check(handle->context, name, ACL_DELETE,
682 		      arg->princ, NULL)) {
683 	 ret.code = KADM5_AUTH_DELETE;
684 
685 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
686 				    "kadm5_delete_principal",
687 				    prime_arg, client_name);
688 	 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_delete_principal",
689 		prime_arg, client_name,
690 			service_name, client_addr(rqstp, buf));
691     } else {
692 	 ret.code = kadm5_delete_principal((void *)handle, arg->princ);
693 
694 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
695 				"kadm5_delete_principal",
696 				prime_arg, client_name, ret.code);
697 	 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_delete_principal", prime_arg,
698 		((ret.code == 0) ? "success" : error_message(ret.code)),
699 		client_name, service_name, client_addr(rqstp, buf));
700     }
701 
702 error:
703     if (name)
704     	gss_release_name(&min_stat, &name);
705     if (prime_arg)
706     	free(prime_arg);
707     free_server_handle(handle);
708     if (client_name)
709     	free(client_name);
710     if (service_name)
711     	free(service_name);
712     return &ret;
713 }
714 
715 generic_ret *
716 modify_principal_1_svc(mprinc_arg *arg, struct svc_req *rqstp)
717 {
718     static generic_ret		    ret;
719     char *prime_arg = NULL;
720     char *client_name = NULL, *service_name = NULL;
721     OM_uint32 min_stat;
722     kadm5_server_handle_t handle;
723     restriction_t *rp;
724     gss_name_t name = NULL;
725 
726     xdr_free(xdr_generic_ret, (char *) &ret);
727 
728     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
729 	 return &ret;
730 
731     if ((ret.code = check_handle((void *)handle)))
732 		goto error;
733    if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
734 	 ret.code = KADM5_FAILURE;
735 		goto error;
736     }
737     if (krb5_unparse_name(handle->context, arg->rec.principal, &prime_arg)) {
738 	 ret.code = KADM5_BAD_PRINCIPAL;
739 	 goto error;
740     }
741 	if (!(name = get_clnt_name(rqstp))) {
742 		ret.code = KADM5_FAILURE;
743 		goto error;
744 	}
745 
746     if (CHANGEPW_SERVICE(rqstp)
747 	|| !kadm5int_acl_check(handle->context, name, ACL_MODIFY,
748 		      arg->rec.principal, &rp)
749 	|| kadm5int_acl_impose_restrictions(handle->context,
750 				   &arg->rec, &arg->mask, rp)) {
751 	 ret.code = KADM5_AUTH_MODIFY;
752 
753 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
754 				    "kadm5_modify_principal",
755 				    prime_arg, client_name);
756 	 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_modify_principal",
757 		prime_arg, client_name,
758 		    service_name, client_addr(rqstp, buf));
759     } else {
760 	 ret.code = kadm5_modify_principal((void *)handle, &arg->rec,
761 						arg->mask);
762 
763 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
764 				"kadm5_modify_principal",
765 				prime_arg, client_name, ret.code);
766 	 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_modify_principal",
767 		prime_arg, ((ret.code == 0) ? "success" :
768 			    error_message(ret.code)),
769 		client_name, service_name, client_addr(rqstp, buf));
770     }
771 
772 error:
773     if (name)
774     	gss_release_name(&min_stat, &name);
775     free_server_handle(handle);
776     if (prime_arg)
777     	free(prime_arg);
778     if (client_name)
779     	free(client_name);
780     if (service_name)
781     	free(service_name);
782     return &ret;
783 }
784 
785 generic_ret *
786 rename_principal_1_svc(rprinc_arg *arg, struct svc_req *rqstp)
787 {
788     static generic_ret		ret;
789     char			*prime_arg1 = NULL, *prime_arg2 = NULL;
790     char prime_arg[BUFSIZ];
791     char *client_name = NULL, *service_name = NULL;
792     OM_uint32 min_stat;
793     kadm5_server_handle_t handle;
794     restriction_t *rp;
795     gss_name_t name = NULL;
796 
797     xdr_free(xdr_generic_ret, (char *) &ret);
798 
799     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
800 	 return &ret;
801 
802     if ((ret.code = check_handle((void *)handle)))
803 	 goto error;
804     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
805 	 ret.code = KADM5_FAILURE;
806 	 goto error;
807     }
808     if (krb5_unparse_name(handle->context, arg->src, &prime_arg1) ||
809         krb5_unparse_name(handle->context, arg->dest, &prime_arg2)) {
810 	 ret.code = KADM5_BAD_PRINCIPAL;
811 	 goto error;
812     }
813     sprintf(prime_arg, "%s to %s", prime_arg1, prime_arg2);
814 
815     ret.code = KADM5_OK;
816 
817 	if (!(name = get_clnt_name(rqstp))) {
818 		ret.code = KADM5_FAILURE;
819 		goto error;
820 	}
821 
822     if (! CHANGEPW_SERVICE(rqstp)) {
823 	 if (!kadm5int_acl_check(handle->context, name,
824 			ACL_DELETE, arg->src, NULL))
825 	      ret.code = KADM5_AUTH_DELETE;
826 	 /* any restrictions at all on the ADD kills the RENAME */
827 	 if (!kadm5int_acl_check(handle->context, name,
828 			ACL_ADD, arg->dest, &rp)) {
829 	      if (ret.code == KADM5_AUTH_DELETE)
830 		   ret.code = KADM5_AUTH_INSUFFICIENT;
831 	      else
832 		   ret.code = KADM5_AUTH_ADD;
833 	 }
834     } else
835 	 ret.code = KADM5_AUTH_INSUFFICIENT;
836     if (ret.code != KADM5_OK) {
837 
838 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
839 				    "kadm5_rename_principal",
840 				    prime_arg, client_name);
841 	 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_rename_principal",
842 		prime_arg, client_name,
843 		    service_name, client_addr(rqstp, buf));
844     } else {
845 	 ret.code = kadm5_rename_principal((void *)handle, arg->src,
846 						arg->dest);
847 
848 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
849 				"kadm5_rename_principal",
850 				prime_arg, client_name, ret.code);
851 	 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_rename_principal",
852 		prime_arg, ((ret.code == 0) ? "success" :
853 			    error_message(ret.code)),
854 		client_name, service_name, client_addr(rqstp, buf));
855     }
856 
857 error:
858     if (name)
859     	gss_release_name(&min_stat, &name);
860     free_server_handle(handle);
861     if (prime_arg1)
862     	free(prime_arg1);
863     if (prime_arg2)
864     	free(prime_arg2);
865     if (client_name)
866     	free(client_name);
867     if (service_name)
868     	free(service_name);
869     return &ret;
870 }
871 
872 gprinc_ret *
873 get_principal_1_svc(gprinc_arg *arg, struct svc_req *rqstp)
874 {
875     static gprinc_ret		    ret;
876     kadm5_principal_ent_t_v1	    e;
877     char			    *prime_arg = NULL, *funcname;
878     char *client_name = NULL, *service_name = NULL;
879     OM_uint32			    min_stat;
880     kadm5_server_handle_t	    handle;
881     gss_name_t name = NULL;
882 
883     xdr_free(xdr_gprinc_ret, (char *) &ret);
884 
885     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
886 	 return &ret;
887 
888     if ((ret.code = check_handle((void *)handle)))
889 		goto error;
890     ret.api_version = handle->api_version;
891 
892     funcname = handle->api_version == KADM5_API_VERSION_1 ?
893 	 "kadm5_get_principal (V1)" : "kadm5_get_principal";
894 
895     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
896 	 ret.code = KADM5_FAILURE;
897 		goto error;
898     }
899     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
900 	 ret.code = KADM5_BAD_PRINCIPAL;
901 		goto error;
902     }
903 	if (!(name = get_clnt_name(rqstp))) {
904 		ret.code = KADM5_FAILURE;
905 		goto error;
906 	}
907 
908     if (! cmp_gss_krb5_name(handle, name, arg->princ) &&
909 	(CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
910 					       name,
911 					       ACL_INQUIRE,
912 					       arg->princ,
913 					       NULL))) {
914 	 ret.code = KADM5_AUTH_GET;
915 
916 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
917 				    funcname,
918 				    prime_arg, client_name);
919 	 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, funcname,
920 		prime_arg, client_name, service_name,
921 		    client_addr(rqstp, buf));
922     } else {
923 	 if (handle->api_version == KADM5_API_VERSION_1) {
924 	      ret.code  = kadm5_get_principal_v1((void *)handle,
925 						 arg->princ, &e);
926 	      if(ret.code == KADM5_OK) {
927 		   memcpy(&ret.rec, e, sizeof(kadm5_principal_ent_rec_v1));
928 		   free(e);
929 	      }
930 	 } else {
931 	      ret.code  = kadm5_get_principal((void *)handle,
932 					      arg->princ, &ret.rec,
933 					      arg->mask);
934 	 }
935 
936 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
937 				funcname,
938 				prime_arg, client_name, ret.code);
939 	 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, funcname,
940 		prime_arg,
941 		((ret.code == 0) ? "success" : error_message(ret.code)),
942 		client_name, service_name, client_addr(rqstp, buf));
943     }
944 
945 error:
946 	if (name)
947     	gss_release_name(&min_stat, &name);
948     free_server_handle(handle);
949     if (prime_arg)
950     	free(prime_arg);
951     if (client_name)
952     	free(client_name);
953     if (service_name)
954     	free(service_name);
955     return &ret;
956 }
957 
958 gprincs_ret *
959 get_princs_1_svc(gprincs_arg *arg, struct svc_req *rqstp)
960 {
961     static gprincs_ret		    ret;
962     char			    *prime_arg = NULL;
963     char *client_name = NULL, *service_name = NULL;
964     OM_uint32			    min_stat;
965     kadm5_server_handle_t handle;
966     gss_name_t name = NULL;
967 
968     xdr_free(xdr_gprincs_ret, (char *) &ret);
969 
970     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
971 	 return &ret;
972 
973     if ((ret.code = check_handle((void *)handle)))
974 		goto error;
975     ret.api_version = handle->api_version;
976 
977     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
978 	 ret.code = KADM5_FAILURE;
979 		goto error;
980     }
981     prime_arg = arg->exp;
982     if (prime_arg == NULL)
983 	 prime_arg = "*";
984 
985 	if (!(name = get_clnt_name(rqstp))) {
986 		ret.code = KADM5_FAILURE;
987 		goto error;
988 	}
989 
990     if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
991 					      name,
992 					      ACL_LIST,
993 					      NULL,
994 					      NULL)) {
995 	 ret.code = KADM5_AUTH_LIST;
996 
997 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
998 				    "kadm5_get_principals",
999 				    prime_arg, client_name);
1000 	 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_get_principals",
1001 		prime_arg, client_name,
1002 		    service_name, client_addr(rqstp, buf));
1003     } else {
1004 	 ret.code  = kadm5_get_principals((void *)handle,
1005 					       arg->exp, &ret.princs,
1006 					       &ret.count);
1007 
1008 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1009 				"kadm5_get_principals",
1010 				prime_arg, client_name, ret.code);
1011 	 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_get_principals",
1012 		prime_arg,
1013 		((ret.code == 0) ? "success" : error_message(ret.code)),
1014 		client_name, service_name, client_addr(rqstp, buf));
1015 	}
1016 
1017 error:
1018 	if (name)
1019 		gss_release_name(&min_stat, &name);
1020 	free_server_handle(handle);
1021 	if (client_name)
1022 		free(client_name);
1023 	if (service_name)
1024 		free(service_name);
1025 	return (&ret);
1026 }
1027 
1028 generic_ret *
1029 chpass_principal_1_svc(chpass_arg *arg, struct svc_req *rqstp)
1030 {
1031     static generic_ret		    ret;
1032     char			    *prime_arg = NULL;
1033     char *client_name = NULL, *service_name = NULL;
1034     OM_uint32 min_stat;
1035     kadm5_server_handle_t	    handle;
1036     gss_name_t name = NULL;
1037 
1038     xdr_free(xdr_generic_ret, (char *) &ret);
1039 
1040     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1041 	 return &ret;
1042 
1043     if ((ret.code = check_handle((void *)handle)))
1044 		goto error;
1045     ret.api_version = handle->api_version;
1046 
1047     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1048 	 ret.code = KADM5_FAILURE;
1049 		goto error;
1050     }
1051     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
1052 	 ret.code = KADM5_BAD_PRINCIPAL;
1053 		goto error;
1054 	}
1055 	if (!(name = get_clnt_name(rqstp))) {
1056 		ret.code = KADM5_FAILURE;
1057 		goto error;
1058 	}
1059 
1060     if (cmp_gss_krb5_name(handle, name, arg->princ)) {
1061 	 ret.code = chpass_principal_wrapper_3((void *)handle, arg->princ,
1062 					       FALSE, 0, NULL, arg->pass);
1063     } else if (!(CHANGEPW_SERVICE(rqstp)) &&
1064 	       kadm5int_acl_check(handle->context, name,
1065 			 ACL_CHANGEPW, arg->princ, NULL)) {
1066 	 ret.code = kadm5_chpass_principal((void *)handle, arg->princ,
1067 						arg->pass);
1068     } else {
1069 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
1070 				    "kadm5_chpass_principal",
1071 				    prime_arg, client_name);
1072 	 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_chpass_principal",
1073 		prime_arg, client_name,
1074 		    service_name, client_addr(rqstp, buf));
1075 	 ret.code = KADM5_AUTH_CHANGEPW;
1076     }
1077 
1078     if(ret.code != KADM5_AUTH_CHANGEPW) {
1079 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1080 				"kadm5_chpass_principal",
1081 				prime_arg, client_name, ret.code);
1082 	krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_chpass_principal",
1083 	       prime_arg, ((ret.code == 0) ? "success" :
1084 			   error_message(ret.code)),
1085 	       client_name, service_name, client_addr(rqstp, buf));
1086     }
1087 
1088 error:
1089 	if (name)
1090 		gss_release_name(&min_stat, &name);
1091 	free_server_handle(handle);
1092 	if (prime_arg)
1093 		free(prime_arg);
1094 	if (client_name)
1095 		free(client_name);
1096 	if (service_name)
1097 		free(service_name);
1098 	return (&ret);
1099 }
1100 
1101 generic_ret *
1102 chpass_principal3_1_svc(chpass3_arg *arg, struct svc_req *rqstp)
1103 {
1104     static generic_ret		    ret;
1105     char			    *prime_arg = NULL;
1106     char       			    *client_name = NULL,
1107 				    *service_name = NULL;
1108     OM_uint32			    min_stat;
1109     kadm5_server_handle_t	    handle;
1110     gss_name_t name = NULL;
1111 
1112     xdr_free(xdr_generic_ret, (char *) &ret);
1113 
1114     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1115 	 return &ret;
1116 
1117     if ((ret.code = check_handle((void *)handle)))
1118 	goto error;
1119     ret.api_version = handle->api_version;
1120 
1121     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1122 	 ret.code = KADM5_FAILURE;
1123 	goto error;
1124     }
1125     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
1126 	 ret.code = KADM5_BAD_PRINCIPAL;
1127 	goto error;
1128     }
1129     if (!(name = get_clnt_name(rqstp))) {
1130 	ret.code = KADM5_FAILURE;
1131 	goto error;
1132     }
1133 
1134     if (cmp_gss_krb5_name(handle, name, arg->princ)) {
1135 	 ret.code = chpass_principal_wrapper_3((void *)handle, arg->princ,
1136 					       arg->keepold,
1137 					       arg->n_ks_tuple,
1138 					       arg->ks_tuple,
1139 					       arg->pass);
1140     } else if (!(CHANGEPW_SERVICE(rqstp)) &&
1141 	       kadm5int_acl_check(handle->context, name,
1142 			 ACL_CHANGEPW, arg->princ, NULL)) {
1143 	 ret.code = kadm5_chpass_principal_3((void *)handle, arg->princ,
1144 					     arg->keepold,
1145 					     arg->n_ks_tuple,
1146 					     arg->ks_tuple,
1147 					     arg->pass);
1148     } else {
1149 	 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_chpass_principal",
1150 		prime_arg, client_name, service_name,
1151 		client_addr(rqstp, buf));
1152 	 ret.code = KADM5_AUTH_CHANGEPW;
1153     }
1154 
1155     if(ret.code != KADM5_AUTH_CHANGEPW) {
1156 	krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_chpass_principal",
1157 	       prime_arg, ((ret.code == 0) ? "success" :
1158 				    error_message(ret.code)),
1159 			client_name, service_name,
1160 			client_addr(rqstp, buf));
1161     }
1162 
1163 error:
1164     if (name)
1165     	gss_release_name(&min_stat, &name);
1166     free_server_handle(handle);
1167     if (client_name)
1168     	free(client_name);
1169     if (service_name)
1170     	free(service_name);
1171     if (prime_arg)
1172     	free(prime_arg);
1173     return (&ret);
1174 }
1175 
1176 #ifdef SUNWOFF
1177 generic_ret *
1178 setv4key_principal_1_svc(setv4key_arg *arg, struct svc_req *rqstp)
1179 {
1180     static generic_ret		    ret;
1181     char			    *prime_arg = NULL;
1182     char 			    *client_name = NULL,
1183 				    *service_name = NULL;
1184     OM_uint32			    min_stat;
1185     kadm5_server_handle_t	    handle;
1186     gss_name_t name = NULL;
1187 
1188     xdr_free(xdr_generic_ret, (char *) &ret);
1189 
1190     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1191 	 return &ret;
1192 
1193     if ((ret.code = check_handle((void *)handle)))
1194 	goto error;
1195     ret.api_version = handle->api_version;
1196 
1197     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1198 	 ret.code = KADM5_FAILURE;
1199 	goto error;
1200     }
1201     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
1202 	 ret.code = KADM5_BAD_PRINCIPAL;
1203 	goto error;
1204     }
1205     if (!(name = get_clnt_name(rqstp))) {
1206 	ret.code = KADM5_FAILURE;
1207 	goto error;
1208     }
1209 
1210     if (!(CHANGEPW_SERVICE(rqstp)) &&
1211 	       kadm5int_acl_check(handle->context, name,
1212 			 ACL_SETKEY, arg->princ, NULL)) {
1213 	 ret.code = kadm5_setv4key_principal((void *)handle, arg->princ,
1214 					     arg->keyblock);
1215     } else {
1216 	 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_setv4key_principal",
1217 		prime_arg, client_name, service_name,
1218 		client_addr(rqstp, buf));
1219 	 ret.code = KADM5_AUTH_SETKEY;
1220     }
1221 
1222     if(ret.code != KADM5_AUTH_SETKEY) {
1223 	krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_setv4key_principal",
1224 	       prime_arg, ((ret.code == 0) ? "success" :
1225 			   error_message(ret.code)),
1226 	       client_name, service_name,
1227 		    client_addr(rqstp, buf));
1228     }
1229 
1230 error:
1231     if (name)
1232 	gss_release_name(&min_stat, &name);
1233     free_server_handle(handle);
1234     if (client_name)
1235 	free(client_name);
1236     if (service_name)
1237 	free(service_name);
1238     if (prime_arg)
1239 	free(prime_arg);
1240     return (&ret);
1241 }
1242 #endif
1243 
1244 generic_ret *
1245 setkey_principal_1_svc(setkey_arg *arg, struct svc_req *rqstp)
1246 {
1247     static generic_ret		    ret;
1248     char			    *prime_arg;
1249     char			    *client_name,
1250 				    *service_name;
1251     OM_uint32			    min_stat;
1252     kadm5_server_handle_t	    handle;
1253     gss_name_t name;
1254 
1255     xdr_free(xdr_generic_ret, (char *) &ret);
1256 
1257     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1258 	 return &ret;
1259 
1260     if ((ret.code = check_handle((void *)handle)))
1261 	goto error;
1262     ret.api_version = handle->api_version;
1263 
1264     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1265 	 ret.code = KADM5_FAILURE;
1266 	goto error;
1267     }
1268     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
1269 	 ret.code = KADM5_BAD_PRINCIPAL;
1270 	goto error;
1271     }
1272     if (!(name = get_clnt_name(rqstp))) {
1273 	 ret.code = KADM5_FAILURE;
1274 	goto error;
1275     }
1276 
1277     if (!(CHANGEPW_SERVICE(rqstp)) &&
1278 	       kadm5int_acl_check(handle->context, name, ACL_SETKEY, arg->princ, NULL)) {
1279 	 ret.code = kadm5_setkey_principal((void *)handle, arg->princ,
1280 					   arg->keyblocks, arg->n_keys);
1281     } else {
1282 	 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_setkey_principal",
1283 		prime_arg, client_name, service_name,
1284 		    client_addr(rqstp, buf));
1285 	 ret.code = KADM5_AUTH_SETKEY;
1286     }
1287 
1288     if(ret.code != KADM5_AUTH_SETKEY) {
1289 	krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_setkey_principal",
1290 	       prime_arg, ((ret.code == 0) ? "success" :
1291 			   error_message(ret.code)),
1292 	       client_name, service_name,
1293 		    client_addr(rqstp, buf));
1294     }
1295 
1296 error:
1297     if (name)
1298 	gss_release_name(&min_stat, &name);
1299     free_server_handle(handle);
1300     if (client_name)
1301     	free(client_name);
1302     if (service_name)
1303     	free(service_name);
1304     if (prime_arg)
1305     	free(prime_arg);
1306     return (&ret);
1307 }
1308 
1309 generic_ret *
1310 setkey_principal3_1_svc(setkey3_arg *arg, struct svc_req *rqstp)
1311 {
1312     static generic_ret		    ret;
1313     char			    *prime_arg = NULL;
1314     char			    *client_name = NULL,
1315 				    *service_name = NULL;
1316     OM_uint32			    min_stat;
1317     kadm5_server_handle_t	    handle;
1318     gss_name_t name = NULL;
1319 
1320     xdr_free(xdr_generic_ret, (char *) &ret);
1321 
1322     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1323 	 return &ret;
1324 
1325     if ((ret.code = check_handle((void *)handle)))
1326 	goto error;
1327     ret.api_version = handle->api_version;
1328 
1329     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1330 	 ret.code = KADM5_FAILURE;
1331 	goto error;
1332     }
1333     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
1334 	 ret.code = KADM5_BAD_PRINCIPAL;
1335 	goto error;
1336     }
1337     if (!(name = get_clnt_name(rqstp))) {
1338 	 ret.code = KADM5_FAILURE;
1339 	goto error;
1340     }
1341 
1342     if (!(CHANGEPW_SERVICE(rqstp)) &&
1343 	       kadm5int_acl_check(handle->context, name,
1344 			 ACL_SETKEY, arg->princ, NULL)) {
1345 	 ret.code = kadm5_setkey_principal_3((void *)handle, arg->princ,
1346 					     arg->keepold,
1347 					     arg->n_ks_tuple,
1348 					     arg->ks_tuple,
1349 					     arg->keyblocks, arg->n_keys);
1350     } else {
1351 	 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_setkey_principal",
1352 		prime_arg, client_name, service_name,
1353 		    client_addr(rqstp, buf));
1354 	 ret.code = KADM5_AUTH_SETKEY;
1355     }
1356 
1357     if(ret.code != KADM5_AUTH_SETKEY) {
1358 	krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_setkey_principal",
1359 	       prime_arg, ((ret.code == 0) ? "success" :
1360 			   error_message(ret.code)),
1361 	       client_name, service_name,
1362 	       client_addr(rqstp, buf));
1363     }
1364 
1365 error:
1366     if (name)
1367 	gss_release_name(&min_stat, &name);
1368     free_server_handle(handle);
1369     if (client_name)
1370 	free(client_name);
1371     if (service_name)
1372     	free(service_name);
1373     if (prime_arg)
1374     	free(prime_arg);
1375     return &ret;
1376 }
1377 
1378 chrand_ret *
1379 chrand_principal_1_svc(chrand_arg *arg, struct svc_req *rqstp)
1380 {
1381     static chrand_ret		ret;
1382     krb5_keyblock		*k;
1383     int				nkeys;
1384     char			*prime_arg = NULL, *funcname;
1385     char *client_name = NULL, *service_name = NULL;
1386     OM_uint32			min_stat;
1387     kadm5_server_handle_t	handle;
1388     gss_name_t name = NULL;
1389 
1390     xdr_free(xdr_chrand_ret, (char *) &ret);
1391 
1392     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1393 	 return &ret;
1394 
1395     if ((ret.code = check_handle((void *)handle)))
1396 		goto error;
1397 
1398     ret.api_version = handle->api_version;
1399 
1400     funcname = handle->api_version == KADM5_API_VERSION_1 ?
1401 	 "kadm5_randkey_principal (V1)" : "kadm5_randkey_principal";
1402 
1403     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1404 	 ret.code = KADM5_FAILURE;
1405 		goto error;
1406     }
1407     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
1408 	 ret.code = KADM5_BAD_PRINCIPAL;
1409 		goto error;
1410     }
1411 	if (!(name = get_clnt_name(rqstp))) {
1412 		ret.code = KADM5_FAILURE;
1413 		goto error;
1414 	}
1415 
1416     if (cmp_gss_krb5_name(handle, name, arg->princ)) {
1417 	 ret.code = randkey_principal_wrapper_3((void *)handle, arg->princ,
1418 						FALSE, 0, NULL, &k, &nkeys);
1419     } else if (!(CHANGEPW_SERVICE(rqstp)) &&
1420 	       kadm5int_acl_check(handle->context, name,
1421 			 ACL_CHANGEPW, arg->princ, NULL)) {
1422 	 ret.code = kadm5_randkey_principal((void *)handle, arg->princ,
1423 					    &k, &nkeys);
1424     } else {
1425 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
1426 				    funcname, prime_arg, client_name);
1427 	 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, funcname,
1428 		prime_arg, client_name, service_name,
1429 		client_addr(rqstp, buf));
1430 	 ret.code = KADM5_AUTH_CHANGEPW;
1431     }
1432 
1433     if(ret.code == KADM5_OK) {
1434 	 if (handle->api_version == KADM5_API_VERSION_1) {
1435 	      krb5_copy_keyblock_contents(handle->context, k, &ret.key);
1436 	      krb5_free_keyblock(handle->context, k);
1437 	 } else {
1438 	      ret.keys = k;
1439 	      ret.n_keys = nkeys;
1440 	 }
1441     }
1442 
1443     if(ret.code != KADM5_AUTH_CHANGEPW) {
1444 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1445 				funcname, prime_arg, client_name, ret.code);
1446 	krb5_klog_syslog(LOG_NOTICE, LOG_DONE, funcname,
1447 	       prime_arg, ((ret.code == 0) ? "success" :
1448 			   error_message(ret.code)),
1449 	       client_name, service_name, client_addr(rqstp, buf));
1450      }
1451 
1452 error:
1453 	if (name)
1454 		gss_release_name(&min_stat, &name);
1455 	free_server_handle(handle);
1456 	if (prime_arg)
1457     	free(prime_arg);
1458     if (client_name)
1459     	free(client_name);
1460     if (service_name)
1461     	free(service_name);
1462     return &ret;
1463 }
1464 
1465 chrand_ret *
1466 chrand_principal3_1_svc(chrand3_arg *arg, struct svc_req *rqstp)
1467 {
1468     static chrand_ret		ret;
1469     krb5_keyblock		*k;
1470     int				nkeys;
1471     char			*prime_arg = NULL, *funcname;
1472     char			*client_name = NULL,
1473 	    			*service_name = NULL;
1474     OM_uint32			min_stat;
1475     kadm5_server_handle_t	handle;
1476     gss_name_t name = NULL;
1477 
1478     xdr_free(xdr_chrand_ret, (char *) &ret);
1479 
1480     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1481 	 return &ret;
1482 
1483     if ((ret.code = check_handle((void *)handle)))
1484 	goto error;
1485     ret.api_version = handle->api_version;
1486 
1487     funcname = handle->api_version == KADM5_API_VERSION_1 ?
1488 	 "kadm5_randkey_principal (V1)" : "kadm5_randkey_principal";
1489 
1490     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1491 	ret.code = KADM5_FAILURE;
1492 	goto error;
1493     }
1494     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
1495 	 ret.code = KADM5_BAD_PRINCIPAL;
1496 	goto error;
1497     }
1498     if (!(name = get_clnt_name(rqstp))) {
1499 	ret.code = KADM5_FAILURE;
1500 	goto error;
1501     }
1502 
1503     if (cmp_gss_krb5_name(handle, name, arg->princ)) {
1504 	 ret.code = randkey_principal_wrapper_3((void *)handle, arg->princ,
1505 						arg->keepold,
1506 						arg->n_ks_tuple,
1507 						arg->ks_tuple,
1508 						&k, &nkeys);
1509     } else if (!(CHANGEPW_SERVICE(rqstp)) &&
1510 	       kadm5int_acl_check(handle->context, name,
1511 			 ACL_CHANGEPW, arg->princ, NULL)) {
1512 	 ret.code = kadm5_randkey_principal_3((void *)handle, arg->princ,
1513 					      arg->keepold,
1514 					      arg->n_ks_tuple,
1515 					      arg->ks_tuple,
1516 					      &k, &nkeys);
1517     } else {
1518 	 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, funcname,
1519 		prime_arg, client_name, service_name,
1520 		client_addr(rqstp, buf));
1521 	 ret.code = KADM5_AUTH_CHANGEPW;
1522     }
1523 
1524     if(ret.code == KADM5_OK) {
1525 	 if (handle->api_version == KADM5_API_VERSION_1) {
1526 	      krb5_copy_keyblock_contents(handle->context, k, &ret.key);
1527 	      krb5_free_keyblock(handle->context, k);
1528 	 } else {
1529 	      ret.keys = k;
1530 	      ret.n_keys = nkeys;
1531 	 }
1532     }
1533 
1534     if(ret.code != KADM5_AUTH_CHANGEPW) {
1535 	krb5_klog_syslog(LOG_NOTICE, LOG_DONE, funcname,
1536 	       prime_arg, ((ret.code == 0) ? "success" :
1537 			   error_message(ret.code)),
1538 	       client_name, service_name,
1539 	       client_addr(rqstp, buf));
1540     }
1541 
1542 error:
1543     if (name)
1544 	gss_release_name(&min_stat, &name);
1545     free_server_handle(handle);
1546     if (client_name)
1547 	free(client_name);
1548     if (service_name)
1549 	free(service_name);
1550     if (prime_arg)
1551 	free(prime_arg);
1552     return (&ret);
1553 }
1554 
1555 generic_ret *
1556 create_policy_1_svc(cpol_arg *arg, struct svc_req *rqstp)
1557 {
1558     static generic_ret		    ret;
1559     char			    *prime_arg = NULL;
1560     char *client_name = NULL, *service_name = NULL;
1561     OM_uint32			    min_stat;
1562     kadm5_server_handle_t	    handle;
1563     gss_name_t name = NULL;
1564 
1565     xdr_free(xdr_generic_ret, (char *) &ret);
1566 
1567     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1568 	 return &ret;
1569 
1570     if ((ret.code = check_handle((void *)handle)))
1571 		goto error;
1572 
1573     ret.api_version = handle->api_version;
1574 
1575     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1576 	 ret.code = KADM5_FAILURE;
1577 		goto error;
1578     }
1579     prime_arg = arg->rec.policy;
1580 
1581 	if (!(name = get_clnt_name(rqstp))) {
1582 		ret.code = KADM5_FAILURE;
1583 		goto error;
1584 	}
1585 
1586     if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
1587 					      name,
1588 					      ACL_ADD, NULL, NULL)) {
1589 	 ret.code = KADM5_AUTH_ADD;
1590 
1591 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
1592 				    "kadm5_create_policy",
1593 				    prime_arg, client_name);
1594 	 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_create_policy",
1595 		prime_arg, client_name,
1596 		service_name, client_addr(rqstp, buf));
1597 
1598     } else {
1599 	 ret.code = kadm5_create_policy((void *)handle, &arg->rec,
1600 					     arg->mask);
1601 
1602 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1603 				"kadm5_create_policy",
1604 				prime_arg, client_name, ret.code);
1605 	 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_create_policy",
1606 		((prime_arg == NULL) ? "(null)" : prime_arg),
1607 		((ret.code == 0) ? "success" : error_message(ret.code)),
1608 		client_name, service_name, client_addr(rqstp, buf));
1609     }
1610 
1611 error:
1612 	if (name)
1613 		gss_release_name(&min_stat, &name);
1614     free_server_handle(handle);
1615     if (client_name)
1616     	free(client_name);
1617     if (service_name)
1618     	free(service_name);
1619     return &ret;
1620 }
1621 
1622 generic_ret *
1623 delete_policy_1_svc(dpol_arg *arg, struct svc_req *rqstp)
1624 {
1625     static generic_ret		    ret;
1626     char			    *prime_arg = NULL;
1627     char *client_name = NULL, *service_name = NULL;
1628     OM_uint32			    min_stat;
1629     kadm5_server_handle_t	    handle;
1630     gss_name_t name = NULL;
1631 
1632     xdr_free(xdr_generic_ret, (char *) &ret);
1633 
1634     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1635 	 return &ret;
1636 
1637     if ((ret.code = check_handle((void *)handle)))
1638 		goto error;
1639     ret.api_version = handle->api_version;
1640 
1641     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1642 	 ret.code = KADM5_FAILURE;
1643 		goto error;
1644     }
1645     prime_arg = arg->name;
1646 
1647 	if (!(name = get_clnt_name(rqstp))) {
1648 		ret.code = KADM5_FAILURE;
1649 		goto error;
1650 	}
1651 
1652     if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
1653 						name,
1654 					      ACL_DELETE, NULL, NULL)) {
1655 
1656 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
1657 				    "kadm5_delete_policy",
1658 				    prime_arg, client_name);
1659 	 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_delete_policy",
1660 		prime_arg, client_name, service_name,
1661 		client_addr(rqstp, buf));
1662 	 ret.code = KADM5_AUTH_DELETE;
1663     } else {
1664 	 ret.code = kadm5_delete_policy((void *)handle, arg->name);
1665 
1666 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1667 				"kadm5_delete_policy",
1668 				prime_arg, client_name, ret.code);
1669 	 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_delete_policy",
1670 		((prime_arg == NULL) ? "(null)" : prime_arg),
1671 		((ret.code == 0) ? "success" : error_message(ret.code)),
1672 		client_name, service_name, client_addr(rqstp, buf));
1673     }
1674 
1675 error:
1676 	if (name)
1677 		gss_release_name(&min_stat, &name);
1678     free_server_handle(handle);
1679     if (client_name)
1680     free(client_name);
1681     if (service_name)
1682     free(service_name);
1683     return &ret;
1684 }
1685 
1686 generic_ret *
1687 modify_policy_1_svc(mpol_arg *arg, struct svc_req *rqstp)
1688 {
1689     static generic_ret		    ret;
1690     char			    *prime_arg = NULL;
1691     char *client_name = NULL, *service_name = NULL;
1692     OM_uint32 min_stat;
1693     kadm5_server_handle_t	    handle;
1694     gss_name_t name = NULL;
1695 
1696     xdr_free(xdr_generic_ret, (char *) &ret);
1697 
1698     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1699 	 return &ret;
1700 
1701     if ((ret.code = check_handle((void *)handle)))
1702 		goto error;
1703     ret.api_version = handle->api_version;
1704 
1705     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1706 	 ret.code = KADM5_FAILURE;
1707 		goto error;
1708     }
1709     prime_arg = arg->rec.policy;
1710 
1711     if (!(name = get_clnt_name(rqstp))) {
1712 	 ret.code = KADM5_FAILURE;
1713 		goto error;
1714     }
1715 
1716     if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
1717 						name,
1718 					      ACL_MODIFY, NULL, NULL)) {
1719 
1720 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
1721 				    "kadm5_modify_policy",
1722 				    prime_arg, client_name);
1723 	 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_modify_policy",
1724 		prime_arg, client_name,
1725 		service_name, client_addr(rqstp, buf));
1726 	 ret.code = KADM5_AUTH_MODIFY;
1727     } else {
1728 	 ret.code = kadm5_modify_policy((void *)handle, &arg->rec,
1729 					     arg->mask);
1730 
1731 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1732 				"kadm5_modify_policy",
1733 				prime_arg, client_name, ret.code);
1734 	 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_modify_policy",
1735 		((prime_arg == NULL) ? "(null)" : prime_arg),
1736 		((ret.code == 0) ? "success" : error_message(ret.code)),
1737 		client_name, service_name, client_addr(rqstp, buf));
1738    }
1739 
1740 error:
1741 	if (name)
1742 		gss_release_name(&min_stat, &name);
1743 	free_server_handle(handle);
1744 	if (client_name)
1745 		free(client_name);
1746 	if (service_name)
1747 		free(service_name);
1748 	return (&ret);
1749 }
1750 
1751 gpol_ret *
1752 get_policy_1_svc(gpol_arg *arg, struct svc_req *rqstp)
1753 {
1754     static gpol_ret		ret;
1755     kadm5_ret_t		ret2;
1756     char *prime_arg = NULL, *funcname;
1757     char *client_name = NULL, *service_name = NULL;
1758     OM_uint32 min_stat;
1759     kadm5_policy_ent_t	e;
1760     kadm5_principal_ent_rec	caller_ent;
1761     krb5_principal caller;
1762     kadm5_server_handle_t	handle;
1763   gss_name_t name = NULL;
1764 
1765     xdr_free(xdr_gpol_ret, (char *) &ret);
1766 
1767     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1768 	 return &ret;
1769 
1770     if ((ret.code = check_handle((void *) handle)))
1771 		goto error;
1772 
1773     ret.api_version = handle->api_version;
1774 
1775     funcname = handle->api_version == KADM5_API_VERSION_1 ?
1776 	 "kadm5_get_policy (V1)" : "kadm5_get_policy";
1777 
1778     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1779 	 ret.code = KADM5_FAILURE;
1780 		goto error;
1781     }
1782     prime_arg = arg->name;
1783 	ret.code = KADM5_AUTH_GET;
1784 
1785 	if (!(name = get_clnt_name(rqstp))) {
1786 		ret.code = KADM5_FAILURE;
1787 		goto error;
1788 	}
1789 
1790     if (!CHANGEPW_SERVICE(rqstp) && kadm5int_acl_check(handle->context,
1791 						name,
1792 						ACL_INQUIRE, NULL, NULL))
1793 		ret.code = KADM5_OK;
1794 	else {
1795 		ret.code = kadm5_get_principal(handle->lhandle,
1796 		    handle->current_caller,
1797 		    &caller_ent,
1798 		    KADM5_PRINCIPAL_NORMAL_MASK);
1799 		if (ret.code == KADM5_OK) {
1800 			if (caller_ent.aux_attributes & KADM5_POLICY &&
1801 			    strcmp(caller_ent.policy, arg->name) == 0) {
1802 		   ret.code = KADM5_OK;
1803 	      } else ret.code = KADM5_AUTH_GET;
1804 	      ret2 = kadm5_free_principal_ent(handle->lhandle,
1805 					      &caller_ent);
1806 	      ret.code = ret.code ? ret.code : ret2;
1807 	 }
1808     }
1809 
1810     if (ret.code == KADM5_OK) {
1811 	 if (handle->api_version == KADM5_API_VERSION_1) {
1812 	      ret.code  = kadm5_get_policy_v1((void *)handle, arg->name, &e);
1813 	      if(ret.code == KADM5_OK) {
1814 		   memcpy(&ret.rec, e, sizeof(kadm5_policy_ent_rec));
1815 		   free(e);
1816 	      }
1817 	 } else {
1818 	      ret.code = kadm5_get_policy((void *)handle, arg->name,
1819 					  &ret.rec);
1820 	 }
1821 
1822 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1823 				funcname, prime_arg, client_name, ret.code);
1824 	 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, funcname,
1825 		((prime_arg == NULL) ? "(null)" : prime_arg),
1826 		((ret.code == 0) ? "success" : error_message(ret.code)),
1827 		client_name, service_name, client_addr(rqstp, buf));
1828 	} else {
1829 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
1830 				    funcname, prime_arg, client_name);
1831 	 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, funcname,
1832 		prime_arg, client_name,
1833 		service_name, client_addr(rqstp, buf));
1834     }
1835 
1836 error:
1837 	if (name)
1838 		gss_release_name(&min_stat, &name);
1839 	free_server_handle(handle);
1840 	if (client_name)
1841 		free(client_name);
1842 	if (service_name)
1843 		free(service_name);
1844 	return (&ret);
1845 
1846 }
1847 
1848 gpols_ret *
1849 get_pols_1_svc(gpols_arg *arg, struct svc_req *rqstp)
1850 {
1851     static gpols_ret		    ret;
1852     char			    *prime_arg = NULL;
1853     char *client_name = NULL, *service_name = NULL;
1854     OM_uint32 min_stat;
1855     kadm5_server_handle_t handle;
1856     gss_name_t name = NULL;
1857 
1858     xdr_free(xdr_gpols_ret, (char *) &ret);
1859 
1860     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
1861 	 return &ret;
1862 
1863     if ((ret.code = check_handle((void *)handle)))
1864 		goto error;
1865 
1866     ret.api_version = handle->api_version;
1867 
1868     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1869 	 ret.code = KADM5_FAILURE;
1870 	goto error;
1871     }
1872     prime_arg = arg->exp;
1873     if (prime_arg == NULL)
1874 	 prime_arg = "*";
1875 
1876 	if (!(name = get_clnt_name(rqstp))) {
1877 		ret.code = KADM5_FAILURE;
1878 		goto error;
1879 	}
1880 
1881     if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
1882 					      name,
1883 					      ACL_LIST, NULL, NULL)) {
1884 	 ret.code = KADM5_AUTH_LIST;
1885 
1886 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
1887 				    "kadm5_get_policies",
1888 				    prime_arg, client_name);
1889 	 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_get_policies",
1890 		prime_arg, client_name, service_name,
1891 		client_addr(rqstp, buf));
1892     } else {
1893 	 ret.code  = kadm5_get_policies((void *)handle,
1894 		    arg->exp, &ret.pols,
1895 		    &ret.count);
1896 
1897 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
1898 				"kadm5_get_policies",
1899 				prime_arg, client_name, ret.code);
1900 	 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_get_policies",
1901 		prime_arg,
1902 		((ret.code == 0) ? "success" : error_message(ret.code)),
1903 		client_name, service_name, client_addr(rqstp, buf));
1904     }
1905 
1906 error:
1907 	if (name)
1908 		gss_release_name(&min_stat, &name);
1909 	free_server_handle(handle);
1910 	if (client_name)
1911 		free(client_name);
1912 	if (service_name)
1913 		free(service_name);
1914 	return (&ret);
1915 }
1916 
1917 getprivs_ret * get_privs_1_svc(krb5_ui_4 *arg, struct svc_req *rqstp)
1918 {
1919      static getprivs_ret	    ret;
1920      char *client_name = NULL, *service_name = NULL;
1921      OM_uint32 min_stat;
1922      kadm5_server_handle_t handle;
1923      gss_name_t name = NULL;
1924 
1925      xdr_free(xdr_getprivs_ret, (char *) &ret);
1926 
1927      if ((ret.code = new_server_handle(*arg, rqstp, &handle)))
1928 	  return &ret;
1929 
1930      if ((ret.code = check_handle((void *)handle)))
1931 		goto error;
1932 
1933      ret.api_version = handle->api_version;
1934 
1935      if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1936 	  ret.code = KADM5_FAILURE;
1937 	  goto error;
1938      }
1939 	if (!(name = get_clnt_name(rqstp))) {
1940 		ret.code = KADM5_FAILURE;
1941 		goto error;
1942 	}
1943 
1944 	ret.code = __kadm5_get_priv((void *) handle, &ret.privs, name);
1945 
1946 	audit_kadmind_auth(rqstp->rq_xprt, l_port,
1947 			"kadm5_get_privs", NULL, client_name,
1948 			ret.code);
1949 	krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_get_privs",
1950 	    client_name,
1951 	    ((ret.code == 0) ? "success" : error_message(ret.code)),
1952 	    client_name, service_name, client_addr(rqstp, buf));
1953 
1954 error:
1955 	if (name)
1956 		gss_release_name(&min_stat, &name);
1957 	free_server_handle(handle);
1958 	if (client_name)
1959 		free(client_name);
1960 	if (service_name)
1961 		free(service_name);
1962 	return (&ret);
1963 }
1964 
1965 generic_ret *init_1_svc(krb5_ui_4 *arg, struct svc_req *rqstp)
1966 {
1967      static generic_ret		ret;
1968 	char *client_name, *service_name;
1969 	kadm5_server_handle_t handle;
1970 
1971      xdr_free(xdr_generic_ret, (char *) &ret);
1972 
1973      if ((ret.code = new_server_handle(*arg, rqstp, &handle)))
1974 	  return &ret;
1975      if (! (ret.code = check_handle((void *)handle))) {
1976 	 ret.api_version = handle->api_version;
1977      }
1978 
1979      free_server_handle(handle);
1980 
1981      if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
1982 	  ret.code = KADM5_FAILURE;
1983 	  return &ret;
1984      }
1985 
1986 	audit_kadmind_auth(rqstp->rq_xprt, l_port,
1987 			(ret.api_version == KADM5_API_VERSION_1 ?
1988 			"kadm5_init (V1)" : "kadm5_init"),
1989 			NULL, client_name, ret.code);
1990 	krb5_klog_syslog(LOG_NOTICE, LOG_DONE,
1991 	    (ret.api_version == KADM5_API_VERSION_1 ?
1992 	     "kadm5_init (V1)" : "kadm5_init"),
1993 	    client_name,
1994 	    (ret.code == 0) ? "success" : error_message(ret.code),
1995 	    client_name, service_name, client_addr(rqstp, buf));
1996 	free(client_name);
1997 	free(service_name);
1998 
1999 	return (&ret);
2000 }
2001