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