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