xref: /onnv-gate/usr/src/cmd/krb5/kadmin/server/server_stubs.c (revision 4819:4cfca1e49f16)
10Sstevel@tonic-gate /*
23641Ssemery  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
30Sstevel@tonic-gate  * Use is subject to license terms.
40Sstevel@tonic-gate  */
50Sstevel@tonic-gate 
60Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
70Sstevel@tonic-gate 
80Sstevel@tonic-gate /*
90Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
100Sstevel@tonic-gate  *
110Sstevel@tonic-gate  *	Openvision retains the copyright to derivative works of
120Sstevel@tonic-gate  *	this source code.  Do *NOT* create a derivative of this
130Sstevel@tonic-gate  *	source code before consulting with your legal department.
140Sstevel@tonic-gate  *	Do *NOT* integrate *ANY* of this source code into another
150Sstevel@tonic-gate  *	product before consulting with your legal department.
160Sstevel@tonic-gate  *
170Sstevel@tonic-gate  *	For further information, read the top-level Openvision
180Sstevel@tonic-gate  *	copyright which is contained in the top-level MIT Kerberos
190Sstevel@tonic-gate  *	copyright.
200Sstevel@tonic-gate  *
210Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
220Sstevel@tonic-gate  *
230Sstevel@tonic-gate  */
240Sstevel@tonic-gate 
250Sstevel@tonic-gate 
260Sstevel@tonic-gate /*
270Sstevel@tonic-gate  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
280Sstevel@tonic-gate  *
290Sstevel@tonic-gate  */
300Sstevel@tonic-gate 
310Sstevel@tonic-gate #include <gssapi/gssapi.h>
320Sstevel@tonic-gate #include <gssapi_krb5.h>   /* for gss_nt_krb5_name */
330Sstevel@tonic-gate #include <krb5.h>
340Sstevel@tonic-gate #include <kadm5/admin.h>
350Sstevel@tonic-gate #include <kadm5/kadm_rpc.h>
360Sstevel@tonic-gate #include <kadm5/server_internal.h>
370Sstevel@tonic-gate #include <kadm5/srv/server_acl.h>
380Sstevel@tonic-gate #include <security/pam_appl.h>
390Sstevel@tonic-gate 
400Sstevel@tonic-gate #include <syslog.h>
412881Smp153739 #include <arpa/inet.h>  /* inet_ntoa */
422881Smp153739 #include <krb5/adm_proto.h>  /* krb5_klog_syslog */
430Sstevel@tonic-gate #include <libintl.h>
440Sstevel@tonic-gate #include "misc.h"
450Sstevel@tonic-gate 
462881Smp153739 #define LOG_UNAUTH  gettext("Unauthorized request: %s, %s, " \
470Sstevel@tonic-gate 			    "client=%s, service=%s, addr=%s")
482881Smp153739 #define	LOG_DONE   gettext("Request: %s, %s, %s, client=%s, " \
490Sstevel@tonic-gate 			    "service=%s, addr=%s")
500Sstevel@tonic-gate 
512881Smp153739 extern gss_name_t 			gss_changepw_name;
522881Smp153739 extern gss_name_t			gss_oldchangepw_name;
532881Smp153739 extern void *				global_server_handle;
540Sstevel@tonic-gate extern short l_port;
550Sstevel@tonic-gate 
560Sstevel@tonic-gate char buf[33];
570Sstevel@tonic-gate 
582881Smp153739 #define CHANGEPW_SERVICE(rqstp) \
590Sstevel@tonic-gate 	(cmp_gss_names_rel_1(acceptor_name(rqstp), gss_changepw_name) |\
602881Smp153739 	 (gss_oldchangepw_name && \
612881Smp153739 	  cmp_gss_names_rel_1(acceptor_name(rqstp), \
620Sstevel@tonic-gate 			gss_oldchangepw_name)))
630Sstevel@tonic-gate 
642881Smp153739 
652881Smp153739 static int gss_to_krb5_name(kadm5_server_handle_t handle,
662881Smp153739 		     gss_name_t gss_name, krb5_principal *princ);
672881Smp153739 
682881Smp153739 static int gss_name_to_string(gss_name_t gss_name, gss_buffer_desc *str);
692881Smp153739 
702881Smp153739 static gss_name_t acceptor_name(struct svc_req * rqstp);
712881Smp153739 
720Sstevel@tonic-gate kadm5_ret_t
730Sstevel@tonic-gate kadm5_get_priv(void *server_handle,
740Sstevel@tonic-gate     long *privs, gss_name_t clnt);
750Sstevel@tonic-gate 
760Sstevel@tonic-gate gss_name_t
770Sstevel@tonic-gate get_clnt_name(struct svc_req * rqstp)
780Sstevel@tonic-gate {
790Sstevel@tonic-gate 	OM_uint32 maj_stat, min_stat;
800Sstevel@tonic-gate 	gss_name_t name;
810Sstevel@tonic-gate 	rpc_gss_rawcred_t *raw_cred;
820Sstevel@tonic-gate 	void *cookie;
830Sstevel@tonic-gate 	gss_buffer_desc name_buff;
840Sstevel@tonic-gate 
850Sstevel@tonic-gate 	rpc_gss_getcred(rqstp, &raw_cred, NULL, &cookie);
860Sstevel@tonic-gate 	name_buff.value = raw_cred->client_principal->name;
870Sstevel@tonic-gate 	name_buff.length = raw_cred->client_principal->len;
880Sstevel@tonic-gate 	maj_stat = gss_import_name(&min_stat, &name_buff,
890Sstevel@tonic-gate 	    (gss_OID) GSS_C_NT_EXPORT_NAME, &name);
900Sstevel@tonic-gate 	if (maj_stat != GSS_S_COMPLETE) {
910Sstevel@tonic-gate 		return (NULL);
920Sstevel@tonic-gate 	}
930Sstevel@tonic-gate 	return (name);
940Sstevel@tonic-gate }
950Sstevel@tonic-gate 
960Sstevel@tonic-gate char *
970Sstevel@tonic-gate client_addr(struct svc_req * req, char *buf)
980Sstevel@tonic-gate {
990Sstevel@tonic-gate 	struct sockaddr *ca;
1000Sstevel@tonic-gate 	u_char *b;
1010Sstevel@tonic-gate 	char *frontspace = " ";
1020Sstevel@tonic-gate 
1030Sstevel@tonic-gate 	/*
1040Sstevel@tonic-gate 	 * Convert the caller's IP address to a dotted string
1050Sstevel@tonic-gate 	 */
1060Sstevel@tonic-gate 	ca = (struct sockaddr *)
1070Sstevel@tonic-gate 	    svc_getrpccaller(req->rq_xprt)->buf;
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate 	if (ca->sa_family == AF_INET) {
1100Sstevel@tonic-gate 		b = (u_char *) & ((struct sockaddr_in *) ca)->sin_addr;
1110Sstevel@tonic-gate 		(void) sprintf(buf, "%s(%d.%d.%d.%d) ", frontspace,
1120Sstevel@tonic-gate 		    b[0] & 0xFF, b[1] & 0xFF, b[2] & 0xFF, b[3] & 0xFF);
1130Sstevel@tonic-gate 	} else {
1140Sstevel@tonic-gate 		/*
1150Sstevel@tonic-gate 		 * No IP address to print. If there was a host name
1160Sstevel@tonic-gate 		 * printed, then we print a space.
1170Sstevel@tonic-gate 		 */
1180Sstevel@tonic-gate 		(void) sprintf(buf, frontspace);
1190Sstevel@tonic-gate 	}
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate 	return (buf);
1220Sstevel@tonic-gate }
1230Sstevel@tonic-gate 
1242881Smp153739 static int cmp_gss_names(gss_name_t n1, gss_name_t n2)
1250Sstevel@tonic-gate {
1262881Smp153739    OM_uint32 emaj, emin;
1272881Smp153739    int equal;
1280Sstevel@tonic-gate 
1292881Smp153739    if (GSS_ERROR(emaj = gss_compare_name(&emin, n1, n2, &equal)))
1302881Smp153739       return(0);
1310Sstevel@tonic-gate 
1322881Smp153739    return(equal);
1330Sstevel@tonic-gate }
1340Sstevel@tonic-gate 
1350Sstevel@tonic-gate /* Does a comparison of the names and then releases the first entity */
1360Sstevel@tonic-gate /* For use above in CHANGEPW_SERVICE */
1372881Smp153739 static int cmp_gss_names_rel_1(gss_name_t n1, gss_name_t n2)
1380Sstevel@tonic-gate {
1390Sstevel@tonic-gate    OM_uint32 min_stat;
1400Sstevel@tonic-gate    int ret;
1412881Smp153739 
1422881Smp153739    ret = cmp_gss_names(n1, n2);
1430Sstevel@tonic-gate    if (n1) (void) gss_release_name(&min_stat, &n1);
1440Sstevel@tonic-gate    return ret;
1450Sstevel@tonic-gate }
1460Sstevel@tonic-gate 
1470Sstevel@tonic-gate /*
1480Sstevel@tonic-gate  * Function check_handle
1490Sstevel@tonic-gate  *
1500Sstevel@tonic-gate  * Purpose: Check a server handle and return a com_err code if it is
1510Sstevel@tonic-gate  * invalid or 0 if it is valid.
1520Sstevel@tonic-gate  *
1530Sstevel@tonic-gate  * Arguments:
1540Sstevel@tonic-gate  *
1550Sstevel@tonic-gate  * 	handle		The server handle.
1560Sstevel@tonic-gate  */
1570Sstevel@tonic-gate 
1582881Smp153739 static int check_handle(void *handle)
1590Sstevel@tonic-gate {
1602881Smp153739      CHECK_HANDLE(handle);
1612881Smp153739      return 0;
1620Sstevel@tonic-gate }
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate /*
1650Sstevel@tonic-gate  * Function: new_server_handle
1660Sstevel@tonic-gate  *
1670Sstevel@tonic-gate  * Purpose: Constructs a server handle suitable for passing into the
1680Sstevel@tonic-gate  * server library API functions, by folding the client's API version
1690Sstevel@tonic-gate  * and calling principal into the server handle returned by
1700Sstevel@tonic-gate  * kadm5_init.
1710Sstevel@tonic-gate  *
1720Sstevel@tonic-gate  * Arguments:
1730Sstevel@tonic-gate  * 	api_version	(input) The API version specified by the client
1740Sstevel@tonic-gate  * 	rqstp		(input) The RPC request
1750Sstevel@tonic-gate  * 	handle		(output) The returned handle
1760Sstevel@tonic-gate  *	<return value>	(output) An error code, or 0 if no error occurred
1772881Smp153739  *
1780Sstevel@tonic-gate  * Effects:
1790Sstevel@tonic-gate  * 	Returns a pointer to allocated storage containing the server
1800Sstevel@tonic-gate  * 	handle.  If an error occurs, then no allocated storage is
1810Sstevel@tonic-gate  *	returned, and the return value of the function will be a
1820Sstevel@tonic-gate  * 	non-zero com_err code.
1832881Smp153739  *
1840Sstevel@tonic-gate  *      The allocated storage for the handle should be freed with
1850Sstevel@tonic-gate  * 	free_server_handle (see below) when it is no longer needed.
1860Sstevel@tonic-gate  */
1870Sstevel@tonic-gate 
1882881Smp153739 static kadm5_ret_t new_server_handle(krb5_ui_4 api_version,
1892881Smp153739 					  struct svc_req *rqstp,
1902881Smp153739 					  kadm5_server_handle_t
1912881Smp153739 					  *out_handle)
1920Sstevel@tonic-gate {
1932881Smp153739      kadm5_server_handle_t handle;
1940Sstevel@tonic-gate 	gss_name_t name;
1950Sstevel@tonic-gate 	OM_uint32 min_stat;
1960Sstevel@tonic-gate 
1972881Smp153739      if (! (handle = (kadm5_server_handle_t)
1982881Smp153739 	    malloc(sizeof(*handle))))
1992881Smp153739 	  return ENOMEM;
2000Sstevel@tonic-gate 
2012881Smp153739      *handle = *(kadm5_server_handle_t)global_server_handle;
2022881Smp153739      handle->api_version = api_version;
2030Sstevel@tonic-gate 
2042881Smp153739      if (!(name = get_clnt_name(rqstp))) {
2052881Smp153739 	  free(handle);
2062881Smp153739 	  return KADM5_FAILURE;
2072881Smp153739      }
2082881Smp153739     if (! gss_to_krb5_name(handle, name, &handle->current_caller)) {
2092881Smp153739 	  free(handle);
2100Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
2112881Smp153739 	  return KADM5_FAILURE;
2120Sstevel@tonic-gate 	}
2130Sstevel@tonic-gate 	gss_release_name(&min_stat, &name);
2140Sstevel@tonic-gate 
2152881Smp153739      *out_handle = handle;
2162881Smp153739      return 0;
2170Sstevel@tonic-gate }
2180Sstevel@tonic-gate 
2190Sstevel@tonic-gate /*
2200Sstevel@tonic-gate  * Function: free_server_handle
2210Sstevel@tonic-gate  *
2220Sstevel@tonic-gate  * Purpose: Free handle memory allocated by new_server_handle
2230Sstevel@tonic-gate  *
2240Sstevel@tonic-gate  * Arguments:
2250Sstevel@tonic-gate  * 	handle		(input/output) The handle to free
2260Sstevel@tonic-gate  */
2272881Smp153739 static void free_server_handle(kadm5_server_handle_t handle)
2280Sstevel@tonic-gate {
2292881Smp153739      krb5_free_principal(handle->context, handle->current_caller);
2302881Smp153739      free(handle);
2310Sstevel@tonic-gate }
2320Sstevel@tonic-gate 
2330Sstevel@tonic-gate /*
2340Sstevel@tonic-gate  * Function: setup_gss_names
2350Sstevel@tonic-gate  *
2360Sstevel@tonic-gate  * Purpose: Create printable representations of the client and server
2370Sstevel@tonic-gate  * names.
2380Sstevel@tonic-gate  *
2390Sstevel@tonic-gate  * Arguments:
2400Sstevel@tonic-gate  * 	rqstp		(r) the RPC request
2410Sstevel@tonic-gate  * 	client_name	(w) pointer to client_name string
2420Sstevel@tonic-gate  * 	server_name	(w) pointer to server_name string
2430Sstevel@tonic-gate  *
2440Sstevel@tonic-gate  * Effects:
2450Sstevel@tonic-gate  *
2460Sstevel@tonic-gate  * Unparses the client and server names into client_name and
2470Sstevel@tonic-gate  * server_name, both of which must be freed by the caller.  Returns 0
2480Sstevel@tonic-gate  * on success and -1 on failure. On failure client_name and server_name
2490Sstevel@tonic-gate  * will point to null.
2500Sstevel@tonic-gate  */
2512881Smp153739 /* SUNW14resync */
2522881Smp153739 int setup_gss_names(struct svc_req *rqstp,
2530Sstevel@tonic-gate     char **client_name, char **server_name)
2540Sstevel@tonic-gate {
2552881Smp153739      OM_uint32 maj_stat, min_stat;
2560Sstevel@tonic-gate 	rpc_gss_rawcred_t *raw_cred;
2570Sstevel@tonic-gate 	gss_buffer_desc name_buf;
2580Sstevel@tonic-gate 	char *tmp, *val;
2590Sstevel@tonic-gate 	size_t len;
2600Sstevel@tonic-gate 	gss_name_t name;
2610Sstevel@tonic-gate 
2620Sstevel@tonic-gate 	*client_name = NULL;
2630Sstevel@tonic-gate 
2640Sstevel@tonic-gate 	rpc_gss_getcred(rqstp, &raw_cred, NULL, NULL);
2650Sstevel@tonic-gate 
2660Sstevel@tonic-gate 	/* Return a copy of the service principal from the raw_cred */
2670Sstevel@tonic-gate 	*server_name = strdup(raw_cred->svc_principal);
2680Sstevel@tonic-gate 
2690Sstevel@tonic-gate 	if (*server_name == NULL)
2700Sstevel@tonic-gate 		return (-1);
2710Sstevel@tonic-gate 
2720Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
2730Sstevel@tonic-gate 		free(*server_name);
2740Sstevel@tonic-gate 		*server_name = NULL;
2750Sstevel@tonic-gate 		return (-1);
2760Sstevel@tonic-gate 	}
2770Sstevel@tonic-gate 	maj_stat = gss_display_name(&min_stat, name, &name_buf, NULL);
2780Sstevel@tonic-gate 	if (maj_stat != GSS_S_COMPLETE) {
2790Sstevel@tonic-gate 		free(*server_name);
2800Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
2810Sstevel@tonic-gate 		*server_name = NULL;
2820Sstevel@tonic-gate 		return (-1);
2830Sstevel@tonic-gate 	}
2840Sstevel@tonic-gate 	gss_release_name(&min_stat, &name);
2850Sstevel@tonic-gate 
2860Sstevel@tonic-gate 	/*
2870Sstevel@tonic-gate 	 * Allocate space to copy the client principal. We allocate an
2880Sstevel@tonic-gate 	 * extra byte to make the string null terminated if we need to.
2890Sstevel@tonic-gate 	 */
2900Sstevel@tonic-gate 
2910Sstevel@tonic-gate 	val = name_buf.value;
2920Sstevel@tonic-gate 	len = name_buf.length + (val[name_buf.length - 1] != '\0');
2930Sstevel@tonic-gate 
2940Sstevel@tonic-gate 	/* len is the length including the null terminating byte. */
2950Sstevel@tonic-gate 
2960Sstevel@tonic-gate 	tmp = malloc(len);
2970Sstevel@tonic-gate 	if (tmp) {
2980Sstevel@tonic-gate 		memcpy(tmp, val, len - 1);
2990Sstevel@tonic-gate 		tmp[len - 1] = '\0';
3000Sstevel@tonic-gate 	} else {
3010Sstevel@tonic-gate 		free(*server_name);
3020Sstevel@tonic-gate 		*server_name = NULL;
3030Sstevel@tonic-gate 	}
3040Sstevel@tonic-gate 
3050Sstevel@tonic-gate 	/* Were done with the GSS buffer */
3060Sstevel@tonic-gate 	(void) gss_release_buffer(&min_stat, &name_buf);
3070Sstevel@tonic-gate 
3080Sstevel@tonic-gate 	*client_name = tmp;
3090Sstevel@tonic-gate 
3100Sstevel@tonic-gate 	return (tmp ? 0 : -1);
3110Sstevel@tonic-gate }
3120Sstevel@tonic-gate 
3132881Smp153739 static gss_name_t acceptor_name(struct svc_req * rqstp)
3140Sstevel@tonic-gate {
3152881Smp153739      OM_uint32 maj_stat, min_stat;
3162881Smp153739      gss_name_t name;
3172881Smp153739      rpc_gss_rawcred_t *raw_cred;
3182881Smp153739      void *cookie;
3192881Smp153739      gss_buffer_desc name_buff;
3200Sstevel@tonic-gate 
3212881Smp153739 	rpc_gss_getcred(rqstp, &raw_cred, NULL, &cookie);
3222881Smp153739 	name_buff.value = raw_cred->svc_principal;
3232881Smp153739 	name_buff.length = strlen(raw_cred->svc_principal);
3242881Smp153739 	maj_stat = gss_import_name(&min_stat, &name_buff,
3252881Smp153739 	    (gss_OID) gss_nt_krb5_name, &name);
3262881Smp153739 	if (maj_stat != GSS_S_COMPLETE) {
3272881Smp153739 		gss_release_buffer(&min_stat, &name_buff);
3282881Smp153739 		return (NULL);
3292881Smp153739 	}
3302881Smp153739 	maj_stat = gss_display_name(&min_stat, name, &name_buff, NULL);
3312881Smp153739     if (maj_stat != GSS_S_COMPLETE) {
3322881Smp153739 		gss_release_buffer(&min_stat, &name_buff);
3332881Smp153739 	  return (NULL);
3342881Smp153739 	}
3352881Smp153739 	gss_release_buffer(&min_stat, &name_buff);
3362881Smp153739 
3372881Smp153739      return name;
3382881Smp153739 }
3392881Smp153739 
3402881Smp153739 static int cmp_gss_krb5_name(kadm5_server_handle_t handle,
3412881Smp153739 		      gss_name_t gss_name, krb5_principal princ)
3422881Smp153739 {
3432881Smp153739      krb5_principal princ2;
3442881Smp153739      int status;
3452881Smp153739 
3462881Smp153739      if (! gss_to_krb5_name(handle, gss_name, &princ2))
3472881Smp153739 	  return 0;
3482881Smp153739      status = krb5_principal_compare(handle->context, princ, princ2);
3492881Smp153739      krb5_free_principal(handle->context, princ2);
3502881Smp153739      return status;
3510Sstevel@tonic-gate }
3520Sstevel@tonic-gate 
3530Sstevel@tonic-gate 
3540Sstevel@tonic-gate /*
3550Sstevel@tonic-gate  * This routine primarily validates the username and password
3560Sstevel@tonic-gate  * of the principal to be created, if a prior acl check for
3570Sstevel@tonic-gate  * the 'u' privilege succeeds. Validation is done using
3580Sstevel@tonic-gate  * the PAM `k5migrate' service. k5migrate normally stacks
3590Sstevel@tonic-gate  * pam_unix_auth.so and pam_unix_account.so in its auth and
3600Sstevel@tonic-gate  * account stacks respectively.
3610Sstevel@tonic-gate  *
3620Sstevel@tonic-gate  * Returns 1 (true), if validation is successful,
3630Sstevel@tonic-gate  * else returns 0 (false).
3640Sstevel@tonic-gate  */
3650Sstevel@tonic-gate int verify_pam_pw(char *userdata, char *pwd) {
3660Sstevel@tonic-gate 	pam_handle_t *pamh;
3670Sstevel@tonic-gate 	int err = 0;
3680Sstevel@tonic-gate 	int result = 1;
3690Sstevel@tonic-gate 	char *user = NULL;
3700Sstevel@tonic-gate 	char *ptr = NULL;
3710Sstevel@tonic-gate 
3720Sstevel@tonic-gate 	ptr = strchr(userdata, '@');
3730Sstevel@tonic-gate 	if (ptr != NULL) {
3740Sstevel@tonic-gate 		user = (char *)malloc(ptr - userdata + 1);
3750Sstevel@tonic-gate 		(void) strlcpy(user, userdata, (ptr - userdata) + 1);
3760Sstevel@tonic-gate 	} else {
3770Sstevel@tonic-gate 		user = (char *)strdup(userdata);
3780Sstevel@tonic-gate 	}
3790Sstevel@tonic-gate 
3800Sstevel@tonic-gate 	err = pam_start("k5migrate", user, NULL, &pamh);
3810Sstevel@tonic-gate 	if (err != PAM_SUCCESS) {
3820Sstevel@tonic-gate 		syslog(LOG_ERR, "verify_pam_pw: pam_start() failed, %s\n",
3830Sstevel@tonic-gate 				pam_strerror(pamh, err));
3840Sstevel@tonic-gate 		if (user)
3850Sstevel@tonic-gate 			free(user);
3860Sstevel@tonic-gate 		return (0);
3870Sstevel@tonic-gate 	}
3880Sstevel@tonic-gate 	if (user)
3890Sstevel@tonic-gate 		free(user);
3900Sstevel@tonic-gate 
3910Sstevel@tonic-gate 	err = pam_set_item(pamh, PAM_AUTHTOK, (void *)pwd);
3920Sstevel@tonic-gate 	if (err != PAM_SUCCESS) {
3930Sstevel@tonic-gate 		syslog(LOG_ERR, "verify_pam_pw: pam_set_item() failed, %s\n",
3940Sstevel@tonic-gate 				pam_strerror(pamh, err));
3950Sstevel@tonic-gate 		(void) pam_end(pamh, err);
3960Sstevel@tonic-gate 		return (0);
3970Sstevel@tonic-gate 	}
3980Sstevel@tonic-gate 
3990Sstevel@tonic-gate 	err = pam_authenticate(pamh, PAM_SILENT);
4000Sstevel@tonic-gate 	if (err != PAM_SUCCESS) {
4010Sstevel@tonic-gate 		syslog(LOG_ERR, "verify_pam_pw: pam_authenticate() "
4020Sstevel@tonic-gate 				"failed, %s\n", pam_strerror(pamh, err));
4030Sstevel@tonic-gate 		(void) pam_end(pamh, err);
4040Sstevel@tonic-gate 		return (0);
4050Sstevel@tonic-gate 	}
4060Sstevel@tonic-gate 
4070Sstevel@tonic-gate 	err = pam_acct_mgmt(pamh, PAM_SILENT);
4080Sstevel@tonic-gate 	if (err != PAM_SUCCESS) {
4090Sstevel@tonic-gate 		syslog(LOG_ERR, "verify_pam_pw: pam_acct_mgmt() failed, %s\n",
4100Sstevel@tonic-gate 				pam_strerror(pamh, err));
4110Sstevel@tonic-gate 		(void) pam_end(pamh, err);
4120Sstevel@tonic-gate 		return (0);
4130Sstevel@tonic-gate 	}
4140Sstevel@tonic-gate 
4150Sstevel@tonic-gate 	(void) pam_end(pamh, PAM_SUCCESS);
4160Sstevel@tonic-gate 	return (result);
4170Sstevel@tonic-gate }
4180Sstevel@tonic-gate 
4192881Smp153739 static int gss_to_krb5_name(kadm5_server_handle_t handle,
4202881Smp153739 		     gss_name_t gss_name, krb5_principal *princ)
4210Sstevel@tonic-gate {
4222881Smp153739      OM_uint32 status, minor_stat;
4232881Smp153739      gss_buffer_desc gss_str;
4242881Smp153739      gss_OID gss_type;
4252881Smp153739      int success;
4260Sstevel@tonic-gate 
4272881Smp153739      status = gss_display_name(&minor_stat, gss_name, &gss_str, &gss_type);
4282881Smp153739      if ((status != GSS_S_COMPLETE) || (!g_OID_equal(gss_type, gss_nt_krb5_name)))
4292881Smp153739 	  return 0;
4302881Smp153739      success = (krb5_parse_name(handle->context, gss_str.value, princ) == 0);
4312881Smp153739      gss_release_buffer(&minor_stat, &gss_str);
4322881Smp153739      return success;
4332881Smp153739 }
4340Sstevel@tonic-gate 
4352881Smp153739 static int
4362881Smp153739 gss_name_to_string(gss_name_t gss_name, gss_buffer_desc *str)
4372881Smp153739 {
4382881Smp153739      OM_uint32 status, minor_stat;
4392881Smp153739      gss_OID gss_type;
4402881Smp153739 
4412881Smp153739      status = gss_display_name(&minor_stat, gss_name, str, &gss_type);
4422881Smp153739      if ((status != GSS_S_COMPLETE) || (gss_type != gss_nt_krb5_name))
4432881Smp153739 	  return 1;
4442881Smp153739      return 0;
4452881Smp153739 }
4460Sstevel@tonic-gate 
4473998Ssemery static int
4483998Ssemery log_unauth(
4493998Ssemery     char *op,
4503998Ssemery     char *target,
4513998Ssemery     char *client,
4523998Ssemery     char *server,
4533998Ssemery     char *addr)
4543998Ssemery {
4553998Ssemery     size_t tlen, clen, slen;
4563998Ssemery     char *tdots, *cdots, *sdots;
4573998Ssemery 
4583998Ssemery     tlen = strlen(target);
4593998Ssemery     trunc_name(&tlen, &tdots);
4603998Ssemery     clen = strlen(client);
4613998Ssemery     trunc_name(&clen, &cdots);
4623998Ssemery     slen = strlen(server);
4633998Ssemery     trunc_name(&slen, &sdots);
4643998Ssemery 
4653998Ssemery     return krb5_klog_syslog(LOG_NOTICE,
4663998Ssemery 			"Unauthorized request: %s, %.*s%s, "
4673998Ssemery 			"client=%.*s%s, service=%.*s%s, addr=%s",
4683998Ssemery 			op, tlen, target, tdots,
4693998Ssemery 			clen, client, cdots,
4703998Ssemery 			slen, server, sdots,
4713998Ssemery 			addr);
4723998Ssemery }
4733998Ssemery 
4743998Ssemery static int
4753998Ssemery log_done(
4763998Ssemery     char *op,
4773998Ssemery     char *target,
4783998Ssemery     const char *errmsg,
4793998Ssemery     char *client,
4803998Ssemery     char *server,
4813998Ssemery     char *addr)
4823998Ssemery {
4833998Ssemery     size_t tlen, clen, slen;
4843998Ssemery     char *tdots, *cdots, *sdots;
4853998Ssemery 
4863998Ssemery     tlen = strlen(target);
4873998Ssemery     trunc_name(&tlen, &tdots);
4883998Ssemery     clen = strlen(client);
4893998Ssemery     trunc_name(&clen, &cdots);
4903998Ssemery     slen = strlen(server);
4913998Ssemery     trunc_name(&slen, &sdots);
4923998Ssemery 
4933998Ssemery     return krb5_klog_syslog(LOG_NOTICE,
4943998Ssemery 			"Request: %s, %.*s%s, %s, "
4953998Ssemery 			"client=%.*s%s, service=%.*s%s, addr=%s",
4963998Ssemery 			op, tlen, target, tdots, errmsg,
4973998Ssemery 			clen, client, cdots,
4983998Ssemery 			slen, server, sdots,
4993998Ssemery 			addr);
5003998Ssemery }
5013998Ssemery 
5022881Smp153739 generic_ret *
5032881Smp153739 create_principal_1_svc(cprinc_arg *arg, struct svc_req *rqstp)
5042881Smp153739 {
5052881Smp153739     static generic_ret		ret;
5062881Smp153739     char			*prime_arg = NULL;
5072881Smp153739     char *client_name = NULL, *service_name = NULL;
5082881Smp153739     int policy_migrate = 0;
5090Sstevel@tonic-gate 
5102881Smp153739     OM_uint32			minor_stat;
5112881Smp153739     kadm5_server_handle_t	handle;
5122881Smp153739     kadm5_ret_t retval;
5132881Smp153739     restriction_t		*rp;
5142881Smp153739     gss_name_t name = NULL;
5152881Smp153739 
5162881Smp153739     xdr_free(xdr_generic_ret, (char *) &ret);
5170Sstevel@tonic-gate 
5182881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
5192881Smp153739 	 return &ret;
5202881Smp153739 
5212881Smp153739     if ((ret.code = check_handle((void *)handle)))
5220Sstevel@tonic-gate 		goto error;
5232881Smp153739     ret.api_version = handle->api_version;
5242881Smp153739 
5252881Smp153739     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
5262881Smp153739 	 ret.code = KADM5_FAILURE;
5272881Smp153739 	goto error;
5282881Smp153739     }
5292881Smp153739     if (krb5_unparse_name(handle->context, arg->rec.principal, &prime_arg)) {
5302881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
5312881Smp153739 	 goto error;
5322881Smp153739     }
5330Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
5340Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
5350Sstevel@tonic-gate 		goto error;
5360Sstevel@tonic-gate 	}
5370Sstevel@tonic-gate 
5382881Smp153739 	if (kadm5int_acl_check(handle->context, name, ACL_MIGRATE,
5390Sstevel@tonic-gate 	    arg->rec.principal, &rp) &&
5400Sstevel@tonic-gate 	    verify_pam_pw(prime_arg, arg->passwd)) {
5410Sstevel@tonic-gate 		policy_migrate = 1;
5420Sstevel@tonic-gate 	}
5430Sstevel@tonic-gate 
5442881Smp153739     if (CHANGEPW_SERVICE(rqstp)
5452881Smp153739 	|| (!kadm5int_acl_check(handle->context, name, ACL_ADD,
5460Sstevel@tonic-gate 			arg->rec.principal, &rp) &&
5470Sstevel@tonic-gate 		!(policy_migrate))
5482881Smp153739 	|| kadm5int_acl_impose_restrictions(handle->context,
5492881Smp153739 				   &arg->rec, &arg->mask, rp)) {
5502881Smp153739 	 ret.code = KADM5_AUTH_ADD;
5510Sstevel@tonic-gate 
5520Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
5530Sstevel@tonic-gate 				    "kadm5_create_principal",
5540Sstevel@tonic-gate 				    prime_arg, client_name);
5553998Ssemery 	 log_unauth("kadm5_create_principal", prime_arg,
5563998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
5572881Smp153739     } else {
5582881Smp153739 	 ret.code = kadm5_create_principal((void *)handle,
5592881Smp153739 						&arg->rec, arg->mask,
5602881Smp153739 						arg->passwd);
5610Sstevel@tonic-gate 
5620Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
5630Sstevel@tonic-gate 				"kadm5_create_principal",
5640Sstevel@tonic-gate 				prime_arg, client_name, ret.code);
5653998Ssemery 	 log_done("kadm5_create_principal", prime_arg,
5663998Ssemery 	    ((ret.code == 0) ? "success" : error_message(ret.code)),
5673998Ssemery 	    client_name, service_name, client_addr(rqstp, buf));
5680Sstevel@tonic-gate 
5690Sstevel@tonic-gate 		if (policy_migrate && (ret.code == 0)) {
5700Sstevel@tonic-gate 			arg->rec.policy = strdup("default");
5710Sstevel@tonic-gate 			if ((arg->mask & KADM5_PW_EXPIRATION)) {
5720Sstevel@tonic-gate 				arg->mask = 0;
5730Sstevel@tonic-gate 				arg->mask |= KADM5_POLICY;
5740Sstevel@tonic-gate 				arg->mask |= KADM5_PW_EXPIRATION;
5750Sstevel@tonic-gate 			} else {
5760Sstevel@tonic-gate 				arg->mask = 0;
5770Sstevel@tonic-gate 				arg->mask |= KADM5_POLICY;
5780Sstevel@tonic-gate 			}
5790Sstevel@tonic-gate 
5800Sstevel@tonic-gate 			retval = kadm5_modify_principal((void *)handle,
5810Sstevel@tonic-gate 					&arg->rec, arg->mask);
5823998Ssemery 			log_done("kadm5_modify_principal",
5830Sstevel@tonic-gate 				prime_arg, ((retval == 0) ? "success" :
5840Sstevel@tonic-gate 				error_message(retval)), client_name,
5850Sstevel@tonic-gate 				service_name, client_addr(rqstp, buf));
5860Sstevel@tonic-gate 		}
5870Sstevel@tonic-gate 	}
5880Sstevel@tonic-gate 
5890Sstevel@tonic-gate error:
5902881Smp153739     if (name)
5912881Smp153739     	gss_release_name(&minor_stat, &name);
5922881Smp153739     free_server_handle(handle);
5932881Smp153739     if (prime_arg)
5942881Smp153739     	free(prime_arg);
5952881Smp153739     if (client_name)
5962881Smp153739     	free(client_name);
5972881Smp153739     if (service_name)
5982881Smp153739     	free(service_name);
5992881Smp153739     return (&ret);
6000Sstevel@tonic-gate }
6010Sstevel@tonic-gate 
6020Sstevel@tonic-gate generic_ret *
6032881Smp153739 create_principal3_1_svc(cprinc3_arg *arg, struct svc_req *rqstp)
6040Sstevel@tonic-gate {
6050Sstevel@tonic-gate     static generic_ret		ret;
6060Sstevel@tonic-gate     char			*prime_arg = NULL;
6070Sstevel@tonic-gate     char			*client_name = NULL, *service_name = NULL;
6080Sstevel@tonic-gate     int				policy_migrate = 0;
6090Sstevel@tonic-gate 
6102881Smp153739     OM_uint32			minor_stat;
6110Sstevel@tonic-gate     kadm5_server_handle_t	handle;
6120Sstevel@tonic-gate     kadm5_ret_t			retval;
6130Sstevel@tonic-gate     restriction_t		*rp;
6140Sstevel@tonic-gate     gss_name_t			name = NULL;
6150Sstevel@tonic-gate 
6160Sstevel@tonic-gate     xdr_free(xdr_generic_ret, (char *) &ret);
6170Sstevel@tonic-gate 
6182881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
6190Sstevel@tonic-gate 	 return &ret;
6200Sstevel@tonic-gate 
6212881Smp153739     if ((ret.code = check_handle((void *)handle)))
6220Sstevel@tonic-gate 	goto error;
6230Sstevel@tonic-gate     ret.api_version = handle->api_version;
6240Sstevel@tonic-gate 
6250Sstevel@tonic-gate     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
6262881Smp153739 	 ret.code = KADM5_FAILURE;
6270Sstevel@tonic-gate 	goto error;
6280Sstevel@tonic-gate     }
6290Sstevel@tonic-gate     if (krb5_unparse_name(handle->context, arg->rec.principal, &prime_arg)) {
6302881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
6310Sstevel@tonic-gate 	goto error;
6320Sstevel@tonic-gate     }
6330Sstevel@tonic-gate     if (!(name = get_clnt_name(rqstp))) {
6340Sstevel@tonic-gate 	ret.code = KADM5_FAILURE;
6350Sstevel@tonic-gate 	goto error;
6360Sstevel@tonic-gate     }
6370Sstevel@tonic-gate 
6382881Smp153739     if (kadm5int_acl_check(handle->context, name, ACL_MIGRATE,
6390Sstevel@tonic-gate 		arg->rec.principal, &rp) &&
6400Sstevel@tonic-gate 		verify_pam_pw(prime_arg, arg->passwd)) {
6410Sstevel@tonic-gate 	policy_migrate = 1;
6420Sstevel@tonic-gate     }
6430Sstevel@tonic-gate 
6440Sstevel@tonic-gate     if (CHANGEPW_SERVICE(rqstp)
6452881Smp153739 	|| (!kadm5int_acl_check(handle->context, name, ACL_ADD,
6460Sstevel@tonic-gate 			arg->rec.principal, &rp) &&
6470Sstevel@tonic-gate 	    !(policy_migrate))
6482881Smp153739 	|| kadm5int_acl_impose_restrictions(handle->context,
6490Sstevel@tonic-gate 				   &arg->rec, &arg->mask, rp)) {
6500Sstevel@tonic-gate 	 ret.code = KADM5_AUTH_ADD;
6513998Ssemery 	 log_unauth("kadm5_create_principal", prime_arg,
6523998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
6530Sstevel@tonic-gate     } else {
6540Sstevel@tonic-gate 	 ret.code = kadm5_create_principal_3((void *)handle,
6550Sstevel@tonic-gate 					     &arg->rec, arg->mask,
6560Sstevel@tonic-gate 					     arg->n_ks_tuple,
6570Sstevel@tonic-gate 					     arg->ks_tuple,
6580Sstevel@tonic-gate 					     arg->passwd);
6593998Ssemery 	 log_done("kadm5_create_principal", prime_arg,
6603998Ssemery 		((ret.code == 0) ? "success" : error_message(ret.code)),
6613998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
6620Sstevel@tonic-gate 
6630Sstevel@tonic-gate 	 if (policy_migrate && (ret.code == 0)) {
6640Sstevel@tonic-gate 	 	arg->rec.policy = strdup("default");
6650Sstevel@tonic-gate 	 	if ((arg->mask & KADM5_PW_EXPIRATION)) {
6660Sstevel@tonic-gate 	 		arg->mask = 0;
6670Sstevel@tonic-gate 	 		arg->mask |= KADM5_POLICY;
6680Sstevel@tonic-gate 	 		arg->mask |= KADM5_PW_EXPIRATION;
6690Sstevel@tonic-gate 	 	} else {
6700Sstevel@tonic-gate 	 		arg->mask = 0;
6710Sstevel@tonic-gate 	 		arg->mask |= KADM5_POLICY;
6720Sstevel@tonic-gate 	 	}
6730Sstevel@tonic-gate 
6740Sstevel@tonic-gate 		retval = kadm5_modify_principal((void *)handle,
6750Sstevel@tonic-gate 					   &arg->rec, arg->mask);
6763998Ssemery 		log_done("kadm5_modify_principal", prime_arg,
6773998Ssemery 			((retval == 0) ? "success" : error_message(retval)),
6783998Ssemery 			client_name, service_name, client_addr(rqstp, buf));
6790Sstevel@tonic-gate 	 }
6800Sstevel@tonic-gate     }
6810Sstevel@tonic-gate 
6820Sstevel@tonic-gate error:
6830Sstevel@tonic-gate     if (name)
6842881Smp153739     	gss_release_name(&minor_stat, &name);
6850Sstevel@tonic-gate     free_server_handle(handle);
6860Sstevel@tonic-gate     if (client_name)
6872881Smp153739     	free(client_name);
6880Sstevel@tonic-gate     if (service_name)
6892881Smp153739     	free(service_name);
6900Sstevel@tonic-gate     if (prime_arg)
6912881Smp153739     	free(prime_arg);
6922881Smp153739     return &ret;
6932881Smp153739 }
6942881Smp153739 
6952881Smp153739 generic_ret *
6962881Smp153739 delete_principal_1_svc(dprinc_arg *arg, struct svc_req *rqstp)
6972881Smp153739 {
6982881Smp153739     static generic_ret		    ret;
6992881Smp153739     char			    *prime_arg = NULL;
7002881Smp153739     char *client_name = NULL, *service_name = NULL;
7012881Smp153739     OM_uint32 min_stat;
7022881Smp153739     kadm5_server_handle_t handle;
7032881Smp153739     gss_name_t name = NULL;
7042881Smp153739 
7052881Smp153739     xdr_free(xdr_generic_ret, (char *) &ret);
7062881Smp153739 
7072881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
7082881Smp153739 	 return &ret;
7092881Smp153739 
7102881Smp153739     if ((ret.code = check_handle((void *)handle)))
7112881Smp153739 		goto error;
7122881Smp153739     ret.api_version = handle->api_version;
7132881Smp153739 
7142881Smp153739     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
7152881Smp153739 	 ret.code = KADM5_FAILURE;
7162881Smp153739 		goto error;
7172881Smp153739     }
7182881Smp153739     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
7192881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
7202881Smp153739 		goto error;
7212881Smp153739     }
7222881Smp153739 	if (!(name = get_clnt_name(rqstp))) {
7232881Smp153739 		ret.code = KADM5_FAILURE;
7242881Smp153739 		goto error;
7252881Smp153739 	}
7262881Smp153739 
7272881Smp153739     if (CHANGEPW_SERVICE(rqstp)
7282881Smp153739 	|| !kadm5int_acl_check(handle->context, name, ACL_DELETE,
7292881Smp153739 		      arg->princ, NULL)) {
7302881Smp153739 	 ret.code = KADM5_AUTH_DELETE;
7312881Smp153739 
7322881Smp153739 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
7332881Smp153739 				    "kadm5_delete_principal",
7342881Smp153739 				    prime_arg, client_name);
7353998Ssemery 	 log_unauth("kadm5_delete_principal", prime_arg, client_name,
7362881Smp153739 			service_name, client_addr(rqstp, buf));
7372881Smp153739     } else {
7382881Smp153739 	 ret.code = kadm5_delete_principal((void *)handle, arg->princ);
7392881Smp153739 
7402881Smp153739 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
7412881Smp153739 				"kadm5_delete_principal",
7422881Smp153739 				prime_arg, client_name, ret.code);
7433998Ssemery 	 log_done("kadm5_delete_principal", prime_arg,
7442881Smp153739 		((ret.code == 0) ? "success" : error_message(ret.code)),
7452881Smp153739 		client_name, service_name, client_addr(rqstp, buf));
7462881Smp153739     }
7472881Smp153739 
7482881Smp153739 error:
7492881Smp153739     if (name)
7502881Smp153739     	gss_release_name(&min_stat, &name);
7512881Smp153739     if (prime_arg)
7522881Smp153739     	free(prime_arg);
7532881Smp153739     free_server_handle(handle);
7542881Smp153739     if (client_name)
7552881Smp153739     	free(client_name);
7562881Smp153739     if (service_name)
7572881Smp153739     	free(service_name);
7582881Smp153739     return &ret;
7590Sstevel@tonic-gate }
7600Sstevel@tonic-gate 
7610Sstevel@tonic-gate generic_ret *
7622881Smp153739 modify_principal_1_svc(mprinc_arg *arg, struct svc_req *rqstp)
7630Sstevel@tonic-gate {
7642881Smp153739     static generic_ret		    ret;
7652881Smp153739     char *prime_arg = NULL;
7662881Smp153739     char *client_name = NULL, *service_name = NULL;
7672881Smp153739     OM_uint32 min_stat;
7682881Smp153739     kadm5_server_handle_t handle;
7692881Smp153739     restriction_t *rp;
7702881Smp153739     gss_name_t name = NULL;
7712881Smp153739 
7722881Smp153739     xdr_free(xdr_generic_ret, (char *) &ret);
7730Sstevel@tonic-gate 
7742881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
7752881Smp153739 	 return &ret;
7760Sstevel@tonic-gate 
7772881Smp153739     if ((ret.code = check_handle((void *)handle)))
7782881Smp153739 		goto error;
7792881Smp153739    if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
7802881Smp153739 	 ret.code = KADM5_FAILURE;
7810Sstevel@tonic-gate 		goto error;
7822881Smp153739     }
7832881Smp153739     if (krb5_unparse_name(handle->context, arg->rec.principal, &prime_arg)) {
7842881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
7852881Smp153739 	 goto error;
7862881Smp153739     }
7872881Smp153739 	if (!(name = get_clnt_name(rqstp))) {
7880Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
7890Sstevel@tonic-gate 		goto error;
7900Sstevel@tonic-gate 	}
7912881Smp153739 
7922881Smp153739     if (CHANGEPW_SERVICE(rqstp)
7932881Smp153739 	|| !kadm5int_acl_check(handle->context, name, ACL_MODIFY,
7942881Smp153739 		      arg->rec.principal, &rp)
7952881Smp153739 	|| kadm5int_acl_impose_restrictions(handle->context,
7962881Smp153739 				   &arg->rec, &arg->mask, rp)) {
7972881Smp153739 	 ret.code = KADM5_AUTH_MODIFY;
7982881Smp153739 
7992881Smp153739 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
8002881Smp153739 				    "kadm5_modify_principal",
8012881Smp153739 				    prime_arg, client_name);
8023998Ssemery 	 log_unauth("kadm5_modify_principal", prime_arg, client_name,
8032881Smp153739 		    service_name, client_addr(rqstp, buf));
8042881Smp153739     } else {
8052881Smp153739 	 ret.code = kadm5_modify_principal((void *)handle, &arg->rec,
8062881Smp153739 						arg->mask);
8072881Smp153739 
8082881Smp153739 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
8092881Smp153739 				"kadm5_modify_principal",
8102881Smp153739 				prime_arg, client_name, ret.code);
8113998Ssemery 	 log_done("kadm5_modify_principal", prime_arg,
8123998Ssemery 		((ret.code == 0) ? "success" : error_message(ret.code)),
8132881Smp153739 		client_name, service_name, client_addr(rqstp, buf));
8142881Smp153739     }
8152881Smp153739 
8162881Smp153739 error:
8172881Smp153739     if (name)
8182881Smp153739     	gss_release_name(&min_stat, &name);
8192881Smp153739     free_server_handle(handle);
8202881Smp153739     if (prime_arg)
8212881Smp153739     	free(prime_arg);
8222881Smp153739     if (client_name)
8232881Smp153739     	free(client_name);
8242881Smp153739     if (service_name)
8252881Smp153739     	free(service_name);
8262881Smp153739     return &ret;
8272881Smp153739 }
8282881Smp153739 
8292881Smp153739 generic_ret *
8302881Smp153739 rename_principal_1_svc(rprinc_arg *arg, struct svc_req *rqstp)
8312881Smp153739 {
8322881Smp153739     static generic_ret		ret;
8332881Smp153739     char			*prime_arg1 = NULL, *prime_arg2 = NULL;
8342881Smp153739     char prime_arg[BUFSIZ];
8352881Smp153739     char *client_name = NULL, *service_name = NULL;
8362881Smp153739     OM_uint32 min_stat;
8372881Smp153739     kadm5_server_handle_t handle;
8382881Smp153739     restriction_t *rp;
8392881Smp153739     gss_name_t name = NULL;
840*4819Sps57422     size_t tlen1, tlen2, clen, slen;
841*4819Sps57422     char *tdots1, *tdots2, *cdots, *sdots;
8422881Smp153739 
8432881Smp153739     xdr_free(xdr_generic_ret, (char *) &ret);
8442881Smp153739 
8452881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
8462881Smp153739 	 return &ret;
8472881Smp153739 
8482881Smp153739     if ((ret.code = check_handle((void *)handle)))
8492881Smp153739 	 goto error;
8502881Smp153739     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
8512881Smp153739 	 ret.code = KADM5_FAILURE;
8522881Smp153739 	 goto error;
8532881Smp153739     }
8542881Smp153739     if (krb5_unparse_name(handle->context, arg->src, &prime_arg1) ||
8552881Smp153739         krb5_unparse_name(handle->context, arg->dest, &prime_arg2)) {
8562881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
8572881Smp153739 	 goto error;
8582881Smp153739     }
859*4819Sps57422     tlen1 = strlen(prime_arg1);
860*4819Sps57422     trunc_name(&tlen1, &tdots1);
861*4819Sps57422     tlen2 = strlen(prime_arg2);
862*4819Sps57422     trunc_name(&tlen2, &tdots2);
863*4819Sps57422     clen = strlen(client_name);
864*4819Sps57422     trunc_name(&clen, &cdots);
865*4819Sps57422     slen = strlen(service_name);
866*4819Sps57422     trunc_name(&slen, &sdots);
8672881Smp153739 
868*4819Sps57422     (void) snprintf(prime_arg, sizeof (prime_arg), "%.*s%s to %.*s*s",
869*4819Sps57422 	tlen1, prime_arg1, tdots1,
870*4819Sps57422 	tlen2, prime_arg2, tdots2);
8712881Smp153739     ret.code = KADM5_OK;
8722881Smp153739 
8730Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
8740Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
8750Sstevel@tonic-gate 		goto error;
8760Sstevel@tonic-gate 	}
8770Sstevel@tonic-gate 
8782881Smp153739     if (! CHANGEPW_SERVICE(rqstp)) {
8792881Smp153739 	 if (!kadm5int_acl_check(handle->context, name,
8802881Smp153739 			ACL_DELETE, arg->src, NULL))
8812881Smp153739 	      ret.code = KADM5_AUTH_DELETE;
8822881Smp153739 	 /* any restrictions at all on the ADD kills the RENAME */
8832881Smp153739 	 if (!kadm5int_acl_check(handle->context, name,
8842881Smp153739 			ACL_ADD, arg->dest, &rp)) {
8852881Smp153739 	      if (ret.code == KADM5_AUTH_DELETE)
8862881Smp153739 		   ret.code = KADM5_AUTH_INSUFFICIENT;
8872881Smp153739 	      else
8882881Smp153739 		   ret.code = KADM5_AUTH_ADD;
8892881Smp153739 	 }
8902881Smp153739     } else
8912881Smp153739 	 ret.code = KADM5_AUTH_INSUFFICIENT;
8922881Smp153739     if (ret.code != KADM5_OK) {
8932881Smp153739 
8942881Smp153739 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
8952881Smp153739 				    "kadm5_rename_principal",
8962881Smp153739 				    prime_arg, client_name);
897*4819Sps57422 		krb5_klog_syslog(LOG_NOTICE,
898*4819Sps57422 		    "Unauthorized request: kadm5_rename_principal, "
899*4819Sps57422 		    "%.*s%s to %.*s%s, "
900*4819Sps57422 		    "client=%.*s%s, service=%.*s%s, addr=%s",
901*4819Sps57422 		    tlen1, prime_arg1, tdots1,
902*4819Sps57422 		    tlen2, prime_arg2, tdots2,
903*4819Sps57422 		    clen, client_name, cdots,
904*4819Sps57422 		    slen, service_name, sdots,
905*4819Sps57422 		    client_addr(rqstp, buf));
9062881Smp153739     } else {
9072881Smp153739 	 ret.code = kadm5_rename_principal((void *)handle, arg->src,
9082881Smp153739 						arg->dest);
9092881Smp153739 
9102881Smp153739 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
9112881Smp153739 				"kadm5_rename_principal",
9122881Smp153739 				prime_arg, client_name, ret.code);
913*4819Sps57422 		krb5_klog_syslog(LOG_NOTICE,
914*4819Sps57422 		    "Request: kadm5_rename_principal, "
915*4819Sps57422 		    "%.*s%s to %.*s%s, %s, "
916*4819Sps57422 		    "client=%.*s%s, service=%.*s%s, addr=%s",
917*4819Sps57422 		    tlen1, prime_arg1, tdots1,
918*4819Sps57422 		    tlen2, prime_arg2, tdots2,
919*4819Sps57422 		    clen, client_name, cdots,
920*4819Sps57422 		    slen, service_name, sdots,
921*4819Sps57422 		    client_addr(rqstp, buf));
9222881Smp153739     }
9232881Smp153739 
9242881Smp153739 error:
9252881Smp153739     if (name)
9262881Smp153739     	gss_release_name(&min_stat, &name);
9272881Smp153739     free_server_handle(handle);
9282881Smp153739     if (prime_arg1)
9292881Smp153739     	free(prime_arg1);
9302881Smp153739     if (prime_arg2)
9312881Smp153739     	free(prime_arg2);
9322881Smp153739     if (client_name)
9332881Smp153739     	free(client_name);
9342881Smp153739     if (service_name)
9352881Smp153739     	free(service_name);
9362881Smp153739     return &ret;
9372881Smp153739 }
9382881Smp153739 
9392881Smp153739 gprinc_ret *
9402881Smp153739 get_principal_1_svc(gprinc_arg *arg, struct svc_req *rqstp)
9412881Smp153739 {
9422881Smp153739     static gprinc_ret		    ret;
9432881Smp153739     kadm5_principal_ent_t_v1	    e;
9442881Smp153739     char			    *prime_arg = NULL, *funcname;
9452881Smp153739     char *client_name = NULL, *service_name = NULL;
9462881Smp153739     OM_uint32			    min_stat;
9472881Smp153739     kadm5_server_handle_t	    handle;
9482881Smp153739     gss_name_t name = NULL;
9492881Smp153739 
9502881Smp153739     xdr_free(xdr_gprinc_ret, (char *) &ret);
9512881Smp153739 
9522881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
9532881Smp153739 	 return &ret;
9542881Smp153739 
9552881Smp153739     if ((ret.code = check_handle((void *)handle)))
9562881Smp153739 		goto error;
9572881Smp153739     ret.api_version = handle->api_version;
9582881Smp153739 
9592881Smp153739     funcname = handle->api_version == KADM5_API_VERSION_1 ?
9602881Smp153739 	 "kadm5_get_principal (V1)" : "kadm5_get_principal";
9612881Smp153739 
9622881Smp153739     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
9632881Smp153739 	 ret.code = KADM5_FAILURE;
9642881Smp153739 		goto error;
9652881Smp153739     }
9662881Smp153739     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
9672881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
9682881Smp153739 		goto error;
9692881Smp153739     }
9702881Smp153739 	if (!(name = get_clnt_name(rqstp))) {
9712881Smp153739 		ret.code = KADM5_FAILURE;
9722881Smp153739 		goto error;
9732881Smp153739 	}
9742881Smp153739 
9752881Smp153739     if (! cmp_gss_krb5_name(handle, name, arg->princ) &&
9762881Smp153739 	(CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
9772881Smp153739 					       name,
9782881Smp153739 					       ACL_INQUIRE,
9792881Smp153739 					       arg->princ,
9802881Smp153739 					       NULL))) {
9812881Smp153739 	 ret.code = KADM5_AUTH_GET;
9820Sstevel@tonic-gate 
9830Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
9842881Smp153739 				    funcname,
9850Sstevel@tonic-gate 				    prime_arg, client_name);
9863998Ssemery 	 log_unauth(funcname, prime_arg, client_name, service_name,
9872881Smp153739 		    client_addr(rqstp, buf));
9882881Smp153739     } else {
9892881Smp153739 	 if (handle->api_version == KADM5_API_VERSION_1) {
9902881Smp153739 	      ret.code  = kadm5_get_principal_v1((void *)handle,
9912881Smp153739 						 arg->princ, &e);
9922881Smp153739 	      if(ret.code == KADM5_OK) {
9932881Smp153739 		   memcpy(&ret.rec, e, sizeof(kadm5_principal_ent_rec_v1));
9942881Smp153739 		   free(e);
9952881Smp153739 	      }
9962881Smp153739 	 } else {
9972881Smp153739 	      ret.code  = kadm5_get_principal((void *)handle,
9982881Smp153739 					      arg->princ, &ret.rec,
9992881Smp153739 					      arg->mask);
10002881Smp153739 	 }
10012881Smp153739 
10022881Smp153739 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
10032881Smp153739 				funcname,
10042881Smp153739 				prime_arg, client_name, ret.code);
10053998Ssemery 	 log_done(funcname, prime_arg,
10062881Smp153739 		((ret.code == 0) ? "success" : error_message(ret.code)),
10072881Smp153739 		client_name, service_name, client_addr(rqstp, buf));
10082881Smp153739     }
10092881Smp153739 
10102881Smp153739 error:
10112881Smp153739 	if (name)
10122881Smp153739     	gss_release_name(&min_stat, &name);
10132881Smp153739     free_server_handle(handle);
10142881Smp153739     if (prime_arg)
10152881Smp153739     	free(prime_arg);
10162881Smp153739     if (client_name)
10172881Smp153739     	free(client_name);
10182881Smp153739     if (service_name)
10192881Smp153739     	free(service_name);
10202881Smp153739     return &ret;
10212881Smp153739 }
10222881Smp153739 
10232881Smp153739 gprincs_ret *
10242881Smp153739 get_princs_1_svc(gprincs_arg *arg, struct svc_req *rqstp)
10252881Smp153739 {
10262881Smp153739     static gprincs_ret		    ret;
10272881Smp153739     char			    *prime_arg = NULL;
10282881Smp153739     char *client_name = NULL, *service_name = NULL;
10292881Smp153739     OM_uint32			    min_stat;
10302881Smp153739     kadm5_server_handle_t handle;
10312881Smp153739     gss_name_t name = NULL;
10322881Smp153739 
10332881Smp153739     xdr_free(xdr_gprincs_ret, (char *) &ret);
10342881Smp153739 
10352881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
10362881Smp153739 	 return &ret;
10372881Smp153739 
10382881Smp153739     if ((ret.code = check_handle((void *)handle)))
10392881Smp153739 		goto error;
10402881Smp153739     ret.api_version = handle->api_version;
10412881Smp153739 
10422881Smp153739     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
10432881Smp153739 	 ret.code = KADM5_FAILURE;
10442881Smp153739 		goto error;
10452881Smp153739     }
10462881Smp153739     prime_arg = arg->exp;
10472881Smp153739     if (prime_arg == NULL)
10482881Smp153739 	 prime_arg = "*";
10492881Smp153739 
10502881Smp153739 	if (!(name = get_clnt_name(rqstp))) {
10512881Smp153739 		ret.code = KADM5_FAILURE;
10522881Smp153739 		goto error;
10532881Smp153739 	}
10542881Smp153739 
10552881Smp153739     if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
10562881Smp153739 					      name,
10572881Smp153739 					      ACL_LIST,
10582881Smp153739 					      NULL,
10592881Smp153739 					      NULL)) {
10602881Smp153739 	 ret.code = KADM5_AUTH_LIST;
10612881Smp153739 
10622881Smp153739 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
10632881Smp153739 				    "kadm5_get_principals",
10642881Smp153739 				    prime_arg, client_name);
10653998Ssemery 	 log_unauth("kadm5_get_principals", prime_arg, client_name,
10662881Smp153739 		    service_name, client_addr(rqstp, buf));
10672881Smp153739     } else {
10682881Smp153739 	 ret.code  = kadm5_get_principals((void *)handle,
10692881Smp153739 					       arg->exp, &ret.princs,
10702881Smp153739 					       &ret.count);
10710Sstevel@tonic-gate 
10720Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
10732881Smp153739 				"kadm5_get_principals",
10740Sstevel@tonic-gate 				prime_arg, client_name, ret.code);
10753998Ssemery 	 log_done("kadm5_get_principals", prime_arg,
10762881Smp153739 		((ret.code == 0) ? "success" : error_message(ret.code)),
10772881Smp153739 		client_name, service_name, client_addr(rqstp, buf));
10780Sstevel@tonic-gate 	}
10790Sstevel@tonic-gate 
10800Sstevel@tonic-gate error:
10810Sstevel@tonic-gate 	if (name)
10820Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
10830Sstevel@tonic-gate 	free_server_handle(handle);
10840Sstevel@tonic-gate 	if (client_name)
10850Sstevel@tonic-gate 		free(client_name);
10860Sstevel@tonic-gate 	if (service_name)
10870Sstevel@tonic-gate 		free(service_name);
10880Sstevel@tonic-gate 	return (&ret);
10890Sstevel@tonic-gate }
10900Sstevel@tonic-gate 
10910Sstevel@tonic-gate generic_ret *
10922881Smp153739 chpass_principal_1_svc(chpass_arg *arg, struct svc_req *rqstp)
10930Sstevel@tonic-gate {
10942881Smp153739     static generic_ret		    ret;
10952881Smp153739     char			    *prime_arg = NULL;
10962881Smp153739     char *client_name = NULL, *service_name = NULL;
10972881Smp153739     OM_uint32 min_stat;
10982881Smp153739     kadm5_server_handle_t	    handle;
10992881Smp153739     gss_name_t name = NULL;
11000Sstevel@tonic-gate 
11012881Smp153739     xdr_free(xdr_generic_ret, (char *) &ret);
11020Sstevel@tonic-gate 
11032881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
11042881Smp153739 	 return &ret;
11050Sstevel@tonic-gate 
11062881Smp153739     if ((ret.code = check_handle((void *)handle)))
11070Sstevel@tonic-gate 		goto error;
11082881Smp153739     ret.api_version = handle->api_version;
11092881Smp153739 
11102881Smp153739     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
11112881Smp153739 	 ret.code = KADM5_FAILURE;
11120Sstevel@tonic-gate 		goto error;
11132881Smp153739     }
11142881Smp153739     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
11152881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
11160Sstevel@tonic-gate 		goto error;
11170Sstevel@tonic-gate 	}
11180Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
11190Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
11200Sstevel@tonic-gate 		goto error;
11210Sstevel@tonic-gate 	}
11220Sstevel@tonic-gate 
11232881Smp153739     if (cmp_gss_krb5_name(handle, name, arg->princ)) {
11242881Smp153739 	 ret.code = chpass_principal_wrapper_3((void *)handle, arg->princ,
11252881Smp153739 					       FALSE, 0, NULL, arg->pass);
11262881Smp153739     } else if (!(CHANGEPW_SERVICE(rqstp)) &&
11272881Smp153739 	       kadm5int_acl_check(handle->context, name,
11282881Smp153739 			 ACL_CHANGEPW, arg->princ, NULL)) {
11292881Smp153739 	 ret.code = kadm5_chpass_principal((void *)handle, arg->princ,
11302881Smp153739 						arg->pass);
11312881Smp153739     } else {
11320Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
11332881Smp153739 				    "kadm5_chpass_principal",
11340Sstevel@tonic-gate 				    prime_arg, client_name);
11353998Ssemery 	 log_unauth("kadm5_chpass_principal", prime_arg, client_name,
11360Sstevel@tonic-gate 		    service_name, client_addr(rqstp, buf));
11372881Smp153739 	 ret.code = KADM5_AUTH_CHANGEPW;
11382881Smp153739     }
11390Sstevel@tonic-gate 
11402881Smp153739     if(ret.code != KADM5_AUTH_CHANGEPW) {
11410Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
11422881Smp153739 				"kadm5_chpass_principal",
11430Sstevel@tonic-gate 				prime_arg, client_name, ret.code);
11443998Ssemery 	log_done("kadm5_chpass_principal", prime_arg,
11453998Ssemery 		((ret.code == 0) ? "success" : error_message(ret.code)),
11463998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
11472881Smp153739     }
11480Sstevel@tonic-gate 
11490Sstevel@tonic-gate error:
11500Sstevel@tonic-gate 	if (name)
11510Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
11520Sstevel@tonic-gate 	free_server_handle(handle);
11530Sstevel@tonic-gate 	if (prime_arg)
11540Sstevel@tonic-gate 		free(prime_arg);
11550Sstevel@tonic-gate 	if (client_name)
11560Sstevel@tonic-gate 		free(client_name);
11570Sstevel@tonic-gate 	if (service_name)
11580Sstevel@tonic-gate 		free(service_name);
11590Sstevel@tonic-gate 	return (&ret);
11600Sstevel@tonic-gate }
11610Sstevel@tonic-gate 
11620Sstevel@tonic-gate generic_ret *
11632881Smp153739 chpass_principal3_1_svc(chpass3_arg *arg, struct svc_req *rqstp)
11640Sstevel@tonic-gate {
11650Sstevel@tonic-gate     static generic_ret		    ret;
11660Sstevel@tonic-gate     char			    *prime_arg = NULL;
11670Sstevel@tonic-gate     char       			    *client_name = NULL,
11680Sstevel@tonic-gate 				    *service_name = NULL;
11690Sstevel@tonic-gate     OM_uint32			    min_stat;
11700Sstevel@tonic-gate     kadm5_server_handle_t	    handle;
11710Sstevel@tonic-gate     gss_name_t name = NULL;
11720Sstevel@tonic-gate 
11730Sstevel@tonic-gate     xdr_free(xdr_generic_ret, (char *) &ret);
11740Sstevel@tonic-gate 
11752881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
11760Sstevel@tonic-gate 	 return &ret;
11770Sstevel@tonic-gate 
11782881Smp153739     if ((ret.code = check_handle((void *)handle)))
11790Sstevel@tonic-gate 	goto error;
11800Sstevel@tonic-gate     ret.api_version = handle->api_version;
11810Sstevel@tonic-gate 
11820Sstevel@tonic-gate     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
11832881Smp153739 	 ret.code = KADM5_FAILURE;
11840Sstevel@tonic-gate 	goto error;
11850Sstevel@tonic-gate     }
11860Sstevel@tonic-gate     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
11872881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
11880Sstevel@tonic-gate 	goto error;
11890Sstevel@tonic-gate     }
11900Sstevel@tonic-gate     if (!(name = get_clnt_name(rqstp))) {
11910Sstevel@tonic-gate 	ret.code = KADM5_FAILURE;
11920Sstevel@tonic-gate 	goto error;
11930Sstevel@tonic-gate     }
11940Sstevel@tonic-gate 
11950Sstevel@tonic-gate     if (cmp_gss_krb5_name(handle, name, arg->princ)) {
11962881Smp153739 	 ret.code = chpass_principal_wrapper_3((void *)handle, arg->princ,
11972881Smp153739 					       arg->keepold,
11982881Smp153739 					       arg->n_ks_tuple,
11992881Smp153739 					       arg->ks_tuple,
12002881Smp153739 					       arg->pass);
12010Sstevel@tonic-gate     } else if (!(CHANGEPW_SERVICE(rqstp)) &&
12022881Smp153739 	       kadm5int_acl_check(handle->context, name,
12030Sstevel@tonic-gate 			 ACL_CHANGEPW, arg->princ, NULL)) {
12040Sstevel@tonic-gate 	 ret.code = kadm5_chpass_principal_3((void *)handle, arg->princ,
12050Sstevel@tonic-gate 					     arg->keepold,
12060Sstevel@tonic-gate 					     arg->n_ks_tuple,
12070Sstevel@tonic-gate 					     arg->ks_tuple,
12080Sstevel@tonic-gate 					     arg->pass);
12090Sstevel@tonic-gate     } else {
12103998Ssemery 	 log_unauth("kadm5_chpass_principal", prime_arg,
12113998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
12120Sstevel@tonic-gate 	 ret.code = KADM5_AUTH_CHANGEPW;
12130Sstevel@tonic-gate     }
12140Sstevel@tonic-gate 
12150Sstevel@tonic-gate     if(ret.code != KADM5_AUTH_CHANGEPW) {
12163998Ssemery 	log_done("kadm5_chpass_principal", prime_arg,
12173998Ssemery 		((ret.code == 0) ? "success" : error_message(ret.code)),
12183998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
12190Sstevel@tonic-gate     }
12200Sstevel@tonic-gate 
12210Sstevel@tonic-gate error:
12220Sstevel@tonic-gate     if (name)
12230Sstevel@tonic-gate     	gss_release_name(&min_stat, &name);
12240Sstevel@tonic-gate     free_server_handle(handle);
12250Sstevel@tonic-gate     if (client_name)
12262881Smp153739     	free(client_name);
12270Sstevel@tonic-gate     if (service_name)
12282881Smp153739     	free(service_name);
12290Sstevel@tonic-gate     if (prime_arg)
12302881Smp153739     	free(prime_arg);
12310Sstevel@tonic-gate     return (&ret);
12320Sstevel@tonic-gate }
12330Sstevel@tonic-gate 
12340Sstevel@tonic-gate #ifdef SUNWOFF
12350Sstevel@tonic-gate generic_ret *
12362881Smp153739 setv4key_principal_1_svc(setv4key_arg *arg, struct svc_req *rqstp)
12370Sstevel@tonic-gate {
12380Sstevel@tonic-gate     static generic_ret		    ret;
12390Sstevel@tonic-gate     char			    *prime_arg = NULL;
12400Sstevel@tonic-gate     char 			    *client_name = NULL,
12410Sstevel@tonic-gate 				    *service_name = NULL;
12420Sstevel@tonic-gate     OM_uint32			    min_stat;
12430Sstevel@tonic-gate     kadm5_server_handle_t	    handle;
12440Sstevel@tonic-gate     gss_name_t name = NULL;
12450Sstevel@tonic-gate 
12460Sstevel@tonic-gate     xdr_free(xdr_generic_ret, (char *) &ret);
12470Sstevel@tonic-gate 
12482881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
12490Sstevel@tonic-gate 	 return &ret;
12500Sstevel@tonic-gate 
12512881Smp153739     if ((ret.code = check_handle((void *)handle)))
12520Sstevel@tonic-gate 	goto error;
12530Sstevel@tonic-gate     ret.api_version = handle->api_version;
12540Sstevel@tonic-gate 
12550Sstevel@tonic-gate     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
12562881Smp153739 	 ret.code = KADM5_FAILURE;
12570Sstevel@tonic-gate 	goto error;
12580Sstevel@tonic-gate     }
12590Sstevel@tonic-gate     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
12602881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
12610Sstevel@tonic-gate 	goto error;
12620Sstevel@tonic-gate     }
12630Sstevel@tonic-gate     if (!(name = get_clnt_name(rqstp))) {
12640Sstevel@tonic-gate 	ret.code = KADM5_FAILURE;
12650Sstevel@tonic-gate 	goto error;
12660Sstevel@tonic-gate     }
12670Sstevel@tonic-gate 
12680Sstevel@tonic-gate     if (!(CHANGEPW_SERVICE(rqstp)) &&
12692881Smp153739 	       kadm5int_acl_check(handle->context, name,
12702881Smp153739 			 ACL_SETKEY, arg->princ, NULL)) {
12710Sstevel@tonic-gate 	 ret.code = kadm5_setv4key_principal((void *)handle, arg->princ,
12720Sstevel@tonic-gate 					     arg->keyblock);
12730Sstevel@tonic-gate     } else {
12743998Ssemery 	 log_unauth("kadm5_setv4key_principal", prime_arg,
12753998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
12760Sstevel@tonic-gate 	 ret.code = KADM5_AUTH_SETKEY;
12770Sstevel@tonic-gate     }
12780Sstevel@tonic-gate 
12790Sstevel@tonic-gate     if(ret.code != KADM5_AUTH_SETKEY) {
12803998Ssemery 	log_done("kadm5_setv4key_principal", prime_arg,
12813998Ssemery 		((ret.code == 0) ? "success" : error_message(ret.code)),
12823998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
12830Sstevel@tonic-gate     }
12840Sstevel@tonic-gate 
12850Sstevel@tonic-gate error:
12860Sstevel@tonic-gate     if (name)
12870Sstevel@tonic-gate 	gss_release_name(&min_stat, &name);
12880Sstevel@tonic-gate     free_server_handle(handle);
12890Sstevel@tonic-gate     if (client_name)
12900Sstevel@tonic-gate 	free(client_name);
12910Sstevel@tonic-gate     if (service_name)
12920Sstevel@tonic-gate 	free(service_name);
12930Sstevel@tonic-gate     if (prime_arg)
12940Sstevel@tonic-gate 	free(prime_arg);
12950Sstevel@tonic-gate     return (&ret);
12960Sstevel@tonic-gate }
12970Sstevel@tonic-gate #endif
12980Sstevel@tonic-gate 
12990Sstevel@tonic-gate generic_ret *
13002881Smp153739 setkey_principal_1_svc(setkey_arg *arg, struct svc_req *rqstp)
13010Sstevel@tonic-gate {
13020Sstevel@tonic-gate     static generic_ret		    ret;
13030Sstevel@tonic-gate     char			    *prime_arg;
13040Sstevel@tonic-gate     char			    *client_name,
13050Sstevel@tonic-gate 				    *service_name;
13060Sstevel@tonic-gate     OM_uint32			    min_stat;
13070Sstevel@tonic-gate     kadm5_server_handle_t	    handle;
13080Sstevel@tonic-gate     gss_name_t name;
13090Sstevel@tonic-gate 
13100Sstevel@tonic-gate     xdr_free(xdr_generic_ret, (char *) &ret);
13110Sstevel@tonic-gate 
13122881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
13130Sstevel@tonic-gate 	 return &ret;
13140Sstevel@tonic-gate 
13152881Smp153739     if ((ret.code = check_handle((void *)handle)))
13160Sstevel@tonic-gate 	goto error;
13170Sstevel@tonic-gate     ret.api_version = handle->api_version;
13180Sstevel@tonic-gate 
13190Sstevel@tonic-gate     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
13202881Smp153739 	 ret.code = KADM5_FAILURE;
13210Sstevel@tonic-gate 	goto error;
13220Sstevel@tonic-gate     }
13230Sstevel@tonic-gate     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
13242881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
13250Sstevel@tonic-gate 	goto error;
13260Sstevel@tonic-gate     }
13270Sstevel@tonic-gate     if (!(name = get_clnt_name(rqstp))) {
13282881Smp153739 	 ret.code = KADM5_FAILURE;
13290Sstevel@tonic-gate 	goto error;
13300Sstevel@tonic-gate     }
13310Sstevel@tonic-gate 
13320Sstevel@tonic-gate     if (!(CHANGEPW_SERVICE(rqstp)) &&
13332881Smp153739 	       kadm5int_acl_check(handle->context, name, ACL_SETKEY, arg->princ, NULL)) {
13340Sstevel@tonic-gate 	 ret.code = kadm5_setkey_principal((void *)handle, arg->princ,
13350Sstevel@tonic-gate 					   arg->keyblocks, arg->n_keys);
13360Sstevel@tonic-gate     } else {
13373998Ssemery 	 log_unauth("kadm5_setkey_principal", prime_arg,
13383998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
13390Sstevel@tonic-gate 	 ret.code = KADM5_AUTH_SETKEY;
13400Sstevel@tonic-gate     }
13410Sstevel@tonic-gate 
13420Sstevel@tonic-gate     if(ret.code != KADM5_AUTH_SETKEY) {
13433998Ssemery 	log_done("kadm5_setkey_principal", prime_arg,
13443998Ssemery 		((ret.code == 0) ? "success" : error_message(ret.code)),
13453998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
13460Sstevel@tonic-gate     }
13470Sstevel@tonic-gate 
13480Sstevel@tonic-gate error:
13490Sstevel@tonic-gate     if (name)
13500Sstevel@tonic-gate 	gss_release_name(&min_stat, &name);
13510Sstevel@tonic-gate     free_server_handle(handle);
13520Sstevel@tonic-gate     if (client_name)
13532881Smp153739     	free(client_name);
13540Sstevel@tonic-gate     if (service_name)
13552881Smp153739     	free(service_name);
13560Sstevel@tonic-gate     if (prime_arg)
13572881Smp153739     	free(prime_arg);
13580Sstevel@tonic-gate     return (&ret);
13590Sstevel@tonic-gate }
13600Sstevel@tonic-gate 
13610Sstevel@tonic-gate generic_ret *
13622881Smp153739 setkey_principal3_1_svc(setkey3_arg *arg, struct svc_req *rqstp)
13630Sstevel@tonic-gate {
13640Sstevel@tonic-gate     static generic_ret		    ret;
13650Sstevel@tonic-gate     char			    *prime_arg = NULL;
13660Sstevel@tonic-gate     char			    *client_name = NULL,
13670Sstevel@tonic-gate 				    *service_name = NULL;
13680Sstevel@tonic-gate     OM_uint32			    min_stat;
13690Sstevel@tonic-gate     kadm5_server_handle_t	    handle;
13700Sstevel@tonic-gate     gss_name_t name = NULL;
13710Sstevel@tonic-gate 
13720Sstevel@tonic-gate     xdr_free(xdr_generic_ret, (char *) &ret);
13730Sstevel@tonic-gate 
13742881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
13750Sstevel@tonic-gate 	 return &ret;
13760Sstevel@tonic-gate 
13772881Smp153739     if ((ret.code = check_handle((void *)handle)))
13780Sstevel@tonic-gate 	goto error;
13790Sstevel@tonic-gate     ret.api_version = handle->api_version;
13800Sstevel@tonic-gate 
13810Sstevel@tonic-gate     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
13822881Smp153739 	 ret.code = KADM5_FAILURE;
13830Sstevel@tonic-gate 	goto error;
13840Sstevel@tonic-gate     }
13850Sstevel@tonic-gate     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
13862881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
13870Sstevel@tonic-gate 	goto error;
13880Sstevel@tonic-gate     }
13890Sstevel@tonic-gate     if (!(name = get_clnt_name(rqstp))) {
13902881Smp153739 	 ret.code = KADM5_FAILURE;
13910Sstevel@tonic-gate 	goto error;
13920Sstevel@tonic-gate     }
13930Sstevel@tonic-gate 
13940Sstevel@tonic-gate     if (!(CHANGEPW_SERVICE(rqstp)) &&
13952881Smp153739 	       kadm5int_acl_check(handle->context, name,
13962881Smp153739 			 ACL_SETKEY, arg->princ, NULL)) {
13970Sstevel@tonic-gate 	 ret.code = kadm5_setkey_principal_3((void *)handle, arg->princ,
13980Sstevel@tonic-gate 					     arg->keepold,
13990Sstevel@tonic-gate 					     arg->n_ks_tuple,
14000Sstevel@tonic-gate 					     arg->ks_tuple,
14010Sstevel@tonic-gate 					     arg->keyblocks, arg->n_keys);
14020Sstevel@tonic-gate     } else {
14033998Ssemery 	 log_unauth("kadm5_setkey_principal", prime_arg,
14043998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
14050Sstevel@tonic-gate 	 ret.code = KADM5_AUTH_SETKEY;
14060Sstevel@tonic-gate     }
14070Sstevel@tonic-gate 
14080Sstevel@tonic-gate     if(ret.code != KADM5_AUTH_SETKEY) {
14093998Ssemery 	log_done("kadm5_setkey_principal", prime_arg,
14103998Ssemery 		((ret.code == 0) ? "success" : error_message(ret.code)),
14113998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
14120Sstevel@tonic-gate     }
14130Sstevel@tonic-gate 
14140Sstevel@tonic-gate error:
14150Sstevel@tonic-gate     if (name)
14160Sstevel@tonic-gate 	gss_release_name(&min_stat, &name);
14170Sstevel@tonic-gate     free_server_handle(handle);
14180Sstevel@tonic-gate     if (client_name)
14190Sstevel@tonic-gate 	free(client_name);
14200Sstevel@tonic-gate     if (service_name)
14212881Smp153739     	free(service_name);
14220Sstevel@tonic-gate     if (prime_arg)
14232881Smp153739     	free(prime_arg);
14242881Smp153739     return &ret;
14250Sstevel@tonic-gate }
14260Sstevel@tonic-gate 
14270Sstevel@tonic-gate chrand_ret *
14282881Smp153739 chrand_principal_1_svc(chrand_arg *arg, struct svc_req *rqstp)
14290Sstevel@tonic-gate {
14302881Smp153739     static chrand_ret		ret;
14312881Smp153739     krb5_keyblock		*k;
14322881Smp153739     int				nkeys;
14332881Smp153739     char			*prime_arg = NULL, *funcname;
14342881Smp153739     char *client_name = NULL, *service_name = NULL;
14352881Smp153739     OM_uint32			min_stat;
14362881Smp153739     kadm5_server_handle_t	handle;
14372881Smp153739     gss_name_t name = NULL;
14380Sstevel@tonic-gate 
14392881Smp153739     xdr_free(xdr_chrand_ret, (char *) &ret);
14400Sstevel@tonic-gate 
14412881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
14422881Smp153739 	 return &ret;
14430Sstevel@tonic-gate 
14442881Smp153739     if ((ret.code = check_handle((void *)handle)))
14450Sstevel@tonic-gate 		goto error;
14462881Smp153739 
14472881Smp153739     ret.api_version = handle->api_version;
14480Sstevel@tonic-gate 
14492881Smp153739     funcname = handle->api_version == KADM5_API_VERSION_1 ?
14502881Smp153739 	 "kadm5_randkey_principal (V1)" : "kadm5_randkey_principal";
14510Sstevel@tonic-gate 
14522881Smp153739     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
14532881Smp153739 	 ret.code = KADM5_FAILURE;
14540Sstevel@tonic-gate 		goto error;
14552881Smp153739     }
14562881Smp153739     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
14572881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
14580Sstevel@tonic-gate 		goto error;
14592881Smp153739     }
14600Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
14610Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
14620Sstevel@tonic-gate 		goto error;
14630Sstevel@tonic-gate 	}
14640Sstevel@tonic-gate 
14652881Smp153739     if (cmp_gss_krb5_name(handle, name, arg->princ)) {
14663641Ssemery 	 ret.code = randkey_principal_wrapper((void *)handle, arg->princ, &k,
14673641Ssemery 						&nkeys);
14682881Smp153739     } else if (!(CHANGEPW_SERVICE(rqstp)) &&
14692881Smp153739 	       kadm5int_acl_check(handle->context, name,
14702881Smp153739 			 ACL_CHANGEPW, arg->princ, NULL)) {
14712881Smp153739 	 ret.code = kadm5_randkey_principal((void *)handle, arg->princ,
14722881Smp153739 					    &k, &nkeys);
14732881Smp153739     } else {
14740Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
14750Sstevel@tonic-gate 				    funcname, prime_arg, client_name);
14763998Ssemery 	 log_unauth(funcname, prime_arg,
14773998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
14782881Smp153739 	 ret.code = KADM5_AUTH_CHANGEPW;
14792881Smp153739     }
14800Sstevel@tonic-gate 
14812881Smp153739     if(ret.code == KADM5_OK) {
14822881Smp153739 	 if (handle->api_version == KADM5_API_VERSION_1) {
14832881Smp153739 	      krb5_copy_keyblock_contents(handle->context, k, &ret.key);
14842881Smp153739 	      krb5_free_keyblock(handle->context, k);
14852881Smp153739 	 } else {
14862881Smp153739 	      ret.keys = k;
14872881Smp153739 	      ret.n_keys = nkeys;
14882881Smp153739 	 }
14892881Smp153739     }
14902881Smp153739 
14912881Smp153739     if(ret.code != KADM5_AUTH_CHANGEPW) {
14920Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
14930Sstevel@tonic-gate 				funcname, prime_arg, client_name, ret.code);
14943998Ssemery 	log_done(funcname, prime_arg,
14953998Ssemery 		((ret.code == 0) ? "success" : error_message(ret.code)),
14963998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
14972881Smp153739      }
14980Sstevel@tonic-gate 
14990Sstevel@tonic-gate error:
15000Sstevel@tonic-gate 	if (name)
15010Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
15020Sstevel@tonic-gate 	free_server_handle(handle);
15030Sstevel@tonic-gate 	if (prime_arg)
15042881Smp153739     	free(prime_arg);
15052881Smp153739     if (client_name)
15062881Smp153739     	free(client_name);
15072881Smp153739     if (service_name)
15082881Smp153739     	free(service_name);
15092881Smp153739     return &ret;
15100Sstevel@tonic-gate }
15110Sstevel@tonic-gate 
15120Sstevel@tonic-gate chrand_ret *
15132881Smp153739 chrand_principal3_1_svc(chrand3_arg *arg, struct svc_req *rqstp)
15140Sstevel@tonic-gate {
15150Sstevel@tonic-gate     static chrand_ret		ret;
15160Sstevel@tonic-gate     krb5_keyblock		*k;
15170Sstevel@tonic-gate     int				nkeys;
15180Sstevel@tonic-gate     char			*prime_arg = NULL, *funcname;
15190Sstevel@tonic-gate     char			*client_name = NULL,
15200Sstevel@tonic-gate 	    			*service_name = NULL;
15210Sstevel@tonic-gate     OM_uint32			min_stat;
15220Sstevel@tonic-gate     kadm5_server_handle_t	handle;
15230Sstevel@tonic-gate     gss_name_t name = NULL;
15240Sstevel@tonic-gate 
15250Sstevel@tonic-gate     xdr_free(xdr_chrand_ret, (char *) &ret);
15260Sstevel@tonic-gate 
15272881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
15280Sstevel@tonic-gate 	 return &ret;
15290Sstevel@tonic-gate 
15302881Smp153739     if ((ret.code = check_handle((void *)handle)))
15310Sstevel@tonic-gate 	goto error;
15320Sstevel@tonic-gate     ret.api_version = handle->api_version;
15330Sstevel@tonic-gate 
15340Sstevel@tonic-gate     funcname = handle->api_version == KADM5_API_VERSION_1 ?
15350Sstevel@tonic-gate 	 "kadm5_randkey_principal (V1)" : "kadm5_randkey_principal";
15360Sstevel@tonic-gate 
15370Sstevel@tonic-gate     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
15380Sstevel@tonic-gate 	ret.code = KADM5_FAILURE;
15390Sstevel@tonic-gate 	goto error;
15400Sstevel@tonic-gate     }
15410Sstevel@tonic-gate     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
15422881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
15430Sstevel@tonic-gate 	goto error;
15440Sstevel@tonic-gate     }
15450Sstevel@tonic-gate     if (!(name = get_clnt_name(rqstp))) {
15460Sstevel@tonic-gate 	ret.code = KADM5_FAILURE;
15470Sstevel@tonic-gate 	goto error;
15480Sstevel@tonic-gate     }
15490Sstevel@tonic-gate 
15500Sstevel@tonic-gate     if (cmp_gss_krb5_name(handle, name, arg->princ)) {
15512881Smp153739 	 ret.code = randkey_principal_wrapper_3((void *)handle, arg->princ,
15522881Smp153739 						arg->keepold,
15532881Smp153739 						arg->n_ks_tuple,
15542881Smp153739 						arg->ks_tuple,
15552881Smp153739 						&k, &nkeys);
15560Sstevel@tonic-gate     } else if (!(CHANGEPW_SERVICE(rqstp)) &&
15572881Smp153739 	       kadm5int_acl_check(handle->context, name,
15580Sstevel@tonic-gate 			 ACL_CHANGEPW, arg->princ, NULL)) {
15590Sstevel@tonic-gate 	 ret.code = kadm5_randkey_principal_3((void *)handle, arg->princ,
15600Sstevel@tonic-gate 					      arg->keepold,
15610Sstevel@tonic-gate 					      arg->n_ks_tuple,
15620Sstevel@tonic-gate 					      arg->ks_tuple,
15630Sstevel@tonic-gate 					      &k, &nkeys);
15640Sstevel@tonic-gate     } else {
15653998Ssemery 	 log_unauth(funcname, prime_arg,
15663998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
15670Sstevel@tonic-gate 	 ret.code = KADM5_AUTH_CHANGEPW;
15680Sstevel@tonic-gate     }
15690Sstevel@tonic-gate 
15700Sstevel@tonic-gate     if(ret.code == KADM5_OK) {
15710Sstevel@tonic-gate 	 if (handle->api_version == KADM5_API_VERSION_1) {
15720Sstevel@tonic-gate 	      krb5_copy_keyblock_contents(handle->context, k, &ret.key);
15730Sstevel@tonic-gate 	      krb5_free_keyblock(handle->context, k);
15740Sstevel@tonic-gate 	 } else {
15750Sstevel@tonic-gate 	      ret.keys = k;
15760Sstevel@tonic-gate 	      ret.n_keys = nkeys;
15770Sstevel@tonic-gate 	 }
15780Sstevel@tonic-gate     }
15790Sstevel@tonic-gate 
15800Sstevel@tonic-gate     if(ret.code != KADM5_AUTH_CHANGEPW) {
15813998Ssemery 	log_done(funcname, prime_arg,
15823998Ssemery 		((ret.code == 0) ? "success" : error_message(ret.code)),
15833998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
15840Sstevel@tonic-gate     }
15850Sstevel@tonic-gate 
15860Sstevel@tonic-gate error:
15870Sstevel@tonic-gate     if (name)
15880Sstevel@tonic-gate 	gss_release_name(&min_stat, &name);
15890Sstevel@tonic-gate     free_server_handle(handle);
15900Sstevel@tonic-gate     if (client_name)
15910Sstevel@tonic-gate 	free(client_name);
15920Sstevel@tonic-gate     if (service_name)
15930Sstevel@tonic-gate 	free(service_name);
15940Sstevel@tonic-gate     if (prime_arg)
15950Sstevel@tonic-gate 	free(prime_arg);
15960Sstevel@tonic-gate     return (&ret);
15970Sstevel@tonic-gate }
15980Sstevel@tonic-gate 
15990Sstevel@tonic-gate generic_ret *
16002881Smp153739 create_policy_1_svc(cpol_arg *arg, struct svc_req *rqstp)
16010Sstevel@tonic-gate {
16022881Smp153739     static generic_ret		    ret;
16032881Smp153739     char			    *prime_arg = NULL;
16042881Smp153739     char *client_name = NULL, *service_name = NULL;
16052881Smp153739     OM_uint32			    min_stat;
16062881Smp153739     kadm5_server_handle_t	    handle;
16072881Smp153739     gss_name_t name = NULL;
16080Sstevel@tonic-gate 
16092881Smp153739     xdr_free(xdr_generic_ret, (char *) &ret);
16100Sstevel@tonic-gate 
16112881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
16122881Smp153739 	 return &ret;
16130Sstevel@tonic-gate 
16142881Smp153739     if ((ret.code = check_handle((void *)handle)))
16150Sstevel@tonic-gate 		goto error;
16162881Smp153739 
16172881Smp153739     ret.api_version = handle->api_version;
16180Sstevel@tonic-gate 
16192881Smp153739     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
16202881Smp153739 	 ret.code = KADM5_FAILURE;
16210Sstevel@tonic-gate 		goto error;
16222881Smp153739     }
16232881Smp153739     prime_arg = arg->rec.policy;
16240Sstevel@tonic-gate 
16250Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
16260Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
16270Sstevel@tonic-gate 		goto error;
16280Sstevel@tonic-gate 	}
16290Sstevel@tonic-gate 
16302881Smp153739     if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
16312881Smp153739 					      name,
16322881Smp153739 					      ACL_ADD, NULL, NULL)) {
16332881Smp153739 	 ret.code = KADM5_AUTH_ADD;
16340Sstevel@tonic-gate 
16350Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
16360Sstevel@tonic-gate 				    "kadm5_create_policy",
16370Sstevel@tonic-gate 				    prime_arg, client_name);
16383998Ssemery 	 log_unauth("kadm5_create_policy", prime_arg,
16393998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
16402881Smp153739 
16412881Smp153739     } else {
16422881Smp153739 	 ret.code = kadm5_create_policy((void *)handle, &arg->rec,
16432881Smp153739 					     arg->mask);
16440Sstevel@tonic-gate 
16450Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
16460Sstevel@tonic-gate 				"kadm5_create_policy",
16470Sstevel@tonic-gate 				prime_arg, client_name, ret.code);
16483998Ssemery 	 log_done("kadm5_create_policy",
16492881Smp153739 		((prime_arg == NULL) ? "(null)" : prime_arg),
16502881Smp153739 		((ret.code == 0) ? "success" : error_message(ret.code)),
16512881Smp153739 		client_name, service_name, client_addr(rqstp, buf));
16522881Smp153739     }
16530Sstevel@tonic-gate 
16540Sstevel@tonic-gate error:
16550Sstevel@tonic-gate 	if (name)
16560Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
16572881Smp153739     free_server_handle(handle);
16582881Smp153739     if (client_name)
16592881Smp153739     	free(client_name);
16602881Smp153739     if (service_name)
16612881Smp153739     	free(service_name);
16622881Smp153739     return &ret;
16630Sstevel@tonic-gate }
16640Sstevel@tonic-gate 
16650Sstevel@tonic-gate generic_ret *
16662881Smp153739 delete_policy_1_svc(dpol_arg *arg, struct svc_req *rqstp)
16670Sstevel@tonic-gate {
16682881Smp153739     static generic_ret		    ret;
16692881Smp153739     char			    *prime_arg = NULL;
16702881Smp153739     char *client_name = NULL, *service_name = NULL;
16712881Smp153739     OM_uint32			    min_stat;
16722881Smp153739     kadm5_server_handle_t	    handle;
16732881Smp153739     gss_name_t name = NULL;
16740Sstevel@tonic-gate 
16752881Smp153739     xdr_free(xdr_generic_ret, (char *) &ret);
16760Sstevel@tonic-gate 
16772881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
16782881Smp153739 	 return &ret;
16790Sstevel@tonic-gate 
16802881Smp153739     if ((ret.code = check_handle((void *)handle)))
16810Sstevel@tonic-gate 		goto error;
16822881Smp153739     ret.api_version = handle->api_version;
16830Sstevel@tonic-gate 
16842881Smp153739     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
16852881Smp153739 	 ret.code = KADM5_FAILURE;
16860Sstevel@tonic-gate 		goto error;
16872881Smp153739     }
16882881Smp153739     prime_arg = arg->name;
16892881Smp153739 
16900Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
16910Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
16920Sstevel@tonic-gate 		goto error;
16930Sstevel@tonic-gate 	}
16940Sstevel@tonic-gate 
16952881Smp153739     if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
16960Sstevel@tonic-gate 						name,
16972881Smp153739 					      ACL_DELETE, NULL, NULL)) {
16980Sstevel@tonic-gate 
16990Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
17000Sstevel@tonic-gate 				    "kadm5_delete_policy",
17010Sstevel@tonic-gate 				    prime_arg, client_name);
17023998Ssemery 	 log_unauth("kadm5_delete_policy", prime_arg,
17033998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
17042881Smp153739 	 ret.code = KADM5_AUTH_DELETE;
17052881Smp153739     } else {
17062881Smp153739 	 ret.code = kadm5_delete_policy((void *)handle, arg->name);
17070Sstevel@tonic-gate 
17080Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
17090Sstevel@tonic-gate 				"kadm5_delete_policy",
17100Sstevel@tonic-gate 				prime_arg, client_name, ret.code);
17113998Ssemery 	 log_done("kadm5_delete_policy",
17122881Smp153739 		((prime_arg == NULL) ? "(null)" : prime_arg),
17132881Smp153739 		((ret.code == 0) ? "success" : error_message(ret.code)),
17142881Smp153739 		client_name, service_name, client_addr(rqstp, buf));
17152881Smp153739     }
17162881Smp153739 
17172881Smp153739 error:
17182881Smp153739 	if (name)
17192881Smp153739 		gss_release_name(&min_stat, &name);
17202881Smp153739     free_server_handle(handle);
17212881Smp153739     if (client_name)
17222881Smp153739     free(client_name);
17232881Smp153739     if (service_name)
17242881Smp153739     free(service_name);
17252881Smp153739     return &ret;
17262881Smp153739 }
17272881Smp153739 
17282881Smp153739 generic_ret *
17292881Smp153739 modify_policy_1_svc(mpol_arg *arg, struct svc_req *rqstp)
17302881Smp153739 {
17312881Smp153739     static generic_ret		    ret;
17322881Smp153739     char			    *prime_arg = NULL;
17332881Smp153739     char *client_name = NULL, *service_name = NULL;
17342881Smp153739     OM_uint32 min_stat;
17352881Smp153739     kadm5_server_handle_t	    handle;
17362881Smp153739     gss_name_t name = NULL;
17372881Smp153739 
17382881Smp153739     xdr_free(xdr_generic_ret, (char *) &ret);
17392881Smp153739 
17402881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
17412881Smp153739 	 return &ret;
17422881Smp153739 
17432881Smp153739     if ((ret.code = check_handle((void *)handle)))
17442881Smp153739 		goto error;
17452881Smp153739     ret.api_version = handle->api_version;
17462881Smp153739 
17472881Smp153739     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
17482881Smp153739 	 ret.code = KADM5_FAILURE;
17492881Smp153739 		goto error;
17502881Smp153739     }
17512881Smp153739     prime_arg = arg->rec.policy;
17522881Smp153739 
17532881Smp153739     if (!(name = get_clnt_name(rqstp))) {
17542881Smp153739 	 ret.code = KADM5_FAILURE;
17552881Smp153739 		goto error;
17562881Smp153739     }
17572881Smp153739 
17582881Smp153739     if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
17592881Smp153739 						name,
17602881Smp153739 					      ACL_MODIFY, NULL, NULL)) {
17612881Smp153739 
17622881Smp153739 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
17632881Smp153739 				    "kadm5_modify_policy",
17642881Smp153739 				    prime_arg, client_name);
17653998Ssemery 	 log_unauth("kadm5_modify_policy", prime_arg,
17663998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
17672881Smp153739 	 ret.code = KADM5_AUTH_MODIFY;
17682881Smp153739     } else {
17692881Smp153739 	 ret.code = kadm5_modify_policy((void *)handle, &arg->rec,
17702881Smp153739 					     arg->mask);
17712881Smp153739 
17722881Smp153739 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
17732881Smp153739 				"kadm5_modify_policy",
17742881Smp153739 				prime_arg, client_name, ret.code);
17753998Ssemery 	 log_done("kadm5_modify_policy",
17762881Smp153739 		((prime_arg == NULL) ? "(null)" : prime_arg),
17772881Smp153739 		((ret.code == 0) ? "success" : error_message(ret.code)),
17782881Smp153739 		client_name, service_name, client_addr(rqstp, buf));
17792881Smp153739    }
17800Sstevel@tonic-gate 
17810Sstevel@tonic-gate error:
17820Sstevel@tonic-gate 	if (name)
17830Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
17840Sstevel@tonic-gate 	free_server_handle(handle);
17850Sstevel@tonic-gate 	if (client_name)
17860Sstevel@tonic-gate 		free(client_name);
17870Sstevel@tonic-gate 	if (service_name)
17880Sstevel@tonic-gate 		free(service_name);
17890Sstevel@tonic-gate 	return (&ret);
17900Sstevel@tonic-gate }
17910Sstevel@tonic-gate 
17922881Smp153739 gpol_ret *
17932881Smp153739 get_policy_1_svc(gpol_arg *arg, struct svc_req *rqstp)
17940Sstevel@tonic-gate {
17952881Smp153739     static gpol_ret		ret;
17962881Smp153739     kadm5_ret_t		ret2;
17972881Smp153739     char *prime_arg = NULL, *funcname;
17982881Smp153739     char *client_name = NULL, *service_name = NULL;
17992881Smp153739     OM_uint32 min_stat;
18002881Smp153739     kadm5_policy_ent_t	e;
18012881Smp153739     kadm5_principal_ent_rec	caller_ent;
18022881Smp153739     krb5_principal caller;
18032881Smp153739     kadm5_server_handle_t	handle;
18042881Smp153739   gss_name_t name = NULL;
18050Sstevel@tonic-gate 
18062881Smp153739     xdr_free(xdr_gpol_ret, (char *) &ret);
18070Sstevel@tonic-gate 
18082881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
18092881Smp153739 	 return &ret;
18100Sstevel@tonic-gate 
18112881Smp153739     if ((ret.code = check_handle((void *) handle)))
18122881Smp153739 		goto error;
18132881Smp153739 
18142881Smp153739     ret.api_version = handle->api_version;
18150Sstevel@tonic-gate 
18162881Smp153739     funcname = handle->api_version == KADM5_API_VERSION_1 ?
18172881Smp153739 	 "kadm5_get_policy (V1)" : "kadm5_get_policy";
18180Sstevel@tonic-gate 
18192881Smp153739     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
18202881Smp153739 	 ret.code = KADM5_FAILURE;
18210Sstevel@tonic-gate 		goto error;
18222881Smp153739     }
18232881Smp153739     prime_arg = arg->name;
18240Sstevel@tonic-gate 	ret.code = KADM5_AUTH_GET;
18250Sstevel@tonic-gate 
18260Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
18270Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
18280Sstevel@tonic-gate 		goto error;
18290Sstevel@tonic-gate 	}
18300Sstevel@tonic-gate 
18312881Smp153739     if (!CHANGEPW_SERVICE(rqstp) && kadm5int_acl_check(handle->context,
18320Sstevel@tonic-gate 						name,
18330Sstevel@tonic-gate 						ACL_INQUIRE, NULL, NULL))
18340Sstevel@tonic-gate 		ret.code = KADM5_OK;
18350Sstevel@tonic-gate 	else {
18360Sstevel@tonic-gate 		ret.code = kadm5_get_principal(handle->lhandle,
18370Sstevel@tonic-gate 		    handle->current_caller,
18380Sstevel@tonic-gate 		    &caller_ent,
18390Sstevel@tonic-gate 		    KADM5_PRINCIPAL_NORMAL_MASK);
18400Sstevel@tonic-gate 		if (ret.code == KADM5_OK) {
18410Sstevel@tonic-gate 			if (caller_ent.aux_attributes & KADM5_POLICY &&
18420Sstevel@tonic-gate 			    strcmp(caller_ent.policy, arg->name) == 0) {
18432881Smp153739 		   ret.code = KADM5_OK;
18442881Smp153739 	      } else ret.code = KADM5_AUTH_GET;
18452881Smp153739 	      ret2 = kadm5_free_principal_ent(handle->lhandle,
18462881Smp153739 					      &caller_ent);
18472881Smp153739 	      ret.code = ret.code ? ret.code : ret2;
18482881Smp153739 	 }
18492881Smp153739     }
18502881Smp153739 
18512881Smp153739     if (ret.code == KADM5_OK) {
18522881Smp153739 	 if (handle->api_version == KADM5_API_VERSION_1) {
18532881Smp153739 	      ret.code  = kadm5_get_policy_v1((void *)handle, arg->name, &e);
18542881Smp153739 	      if(ret.code == KADM5_OK) {
18552881Smp153739 		   memcpy(&ret.rec, e, sizeof(kadm5_policy_ent_rec));
18562881Smp153739 		   free(e);
18572881Smp153739 	      }
18582881Smp153739 	 } else {
18592881Smp153739 	      ret.code = kadm5_get_policy((void *)handle, arg->name,
18602881Smp153739 					  &ret.rec);
18612881Smp153739 	 }
18622881Smp153739 
18630Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
18640Sstevel@tonic-gate 				funcname, prime_arg, client_name, ret.code);
18653998Ssemery 	 log_done(funcname, ((prime_arg == NULL) ? "(null)" : prime_arg),
18662881Smp153739 		((ret.code == 0) ? "success" : error_message(ret.code)),
18672881Smp153739 		client_name, service_name, client_addr(rqstp, buf));
18680Sstevel@tonic-gate 	} else {
18690Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
18700Sstevel@tonic-gate 				    funcname, prime_arg, client_name);
18713998Ssemery 	 log_unauth(funcname, prime_arg, client_name,
18722881Smp153739 		service_name, client_addr(rqstp, buf));
18732881Smp153739     }
18740Sstevel@tonic-gate 
18750Sstevel@tonic-gate error:
18760Sstevel@tonic-gate 	if (name)
18770Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
18780Sstevel@tonic-gate 	free_server_handle(handle);
18790Sstevel@tonic-gate 	if (client_name)
18800Sstevel@tonic-gate 		free(client_name);
18810Sstevel@tonic-gate 	if (service_name)
18820Sstevel@tonic-gate 		free(service_name);
18830Sstevel@tonic-gate 	return (&ret);
18840Sstevel@tonic-gate 
18850Sstevel@tonic-gate }
18860Sstevel@tonic-gate 
18870Sstevel@tonic-gate gpols_ret *
18882881Smp153739 get_pols_1_svc(gpols_arg *arg, struct svc_req *rqstp)
18890Sstevel@tonic-gate {
18902881Smp153739     static gpols_ret		    ret;
18912881Smp153739     char			    *prime_arg = NULL;
18922881Smp153739     char *client_name = NULL, *service_name = NULL;
18932881Smp153739     OM_uint32 min_stat;
18942881Smp153739     kadm5_server_handle_t handle;
18952881Smp153739     gss_name_t name = NULL;
18960Sstevel@tonic-gate 
18972881Smp153739     xdr_free(xdr_gpols_ret, (char *) &ret);
18980Sstevel@tonic-gate 
18992881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
19002881Smp153739 	 return &ret;
19010Sstevel@tonic-gate 
19022881Smp153739     if ((ret.code = check_handle((void *)handle)))
19030Sstevel@tonic-gate 		goto error;
19042881Smp153739 
19052881Smp153739     ret.api_version = handle->api_version;
19060Sstevel@tonic-gate 
19072881Smp153739     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
19082881Smp153739 	 ret.code = KADM5_FAILURE;
19092881Smp153739 	goto error;
19102881Smp153739     }
19112881Smp153739     prime_arg = arg->exp;
19122881Smp153739     if (prime_arg == NULL)
19132881Smp153739 	 prime_arg = "*";
19140Sstevel@tonic-gate 
19150Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
19160Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
19170Sstevel@tonic-gate 		goto error;
19180Sstevel@tonic-gate 	}
19190Sstevel@tonic-gate 
19202881Smp153739     if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
19212881Smp153739 					      name,
19222881Smp153739 					      ACL_LIST, NULL, NULL)) {
19232881Smp153739 	 ret.code = KADM5_AUTH_LIST;
19240Sstevel@tonic-gate 
19250Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
19260Sstevel@tonic-gate 				    "kadm5_get_policies",
19270Sstevel@tonic-gate 				    prime_arg, client_name);
19283998Ssemery 	 log_unauth("kadm5_get_policies", prime_arg,
19293998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
19302881Smp153739     } else {
19312881Smp153739 	 ret.code  = kadm5_get_policies((void *)handle,
19320Sstevel@tonic-gate 		    arg->exp, &ret.pols,
19330Sstevel@tonic-gate 		    &ret.count);
19340Sstevel@tonic-gate 
19350Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
19360Sstevel@tonic-gate 				"kadm5_get_policies",
19370Sstevel@tonic-gate 				prime_arg, client_name, ret.code);
19383998Ssemery 	 log_done("kadm5_get_policies", prime_arg,
19392881Smp153739 		((ret.code == 0) ? "success" : error_message(ret.code)),
19402881Smp153739 		client_name, service_name, client_addr(rqstp, buf));
19412881Smp153739     }
19420Sstevel@tonic-gate 
19430Sstevel@tonic-gate error:
19440Sstevel@tonic-gate 	if (name)
19450Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
19460Sstevel@tonic-gate 	free_server_handle(handle);
19470Sstevel@tonic-gate 	if (client_name)
19480Sstevel@tonic-gate 		free(client_name);
19490Sstevel@tonic-gate 	if (service_name)
19500Sstevel@tonic-gate 		free(service_name);
19510Sstevel@tonic-gate 	return (&ret);
19520Sstevel@tonic-gate }
19530Sstevel@tonic-gate 
19542881Smp153739 getprivs_ret * get_privs_1_svc(krb5_ui_4 *arg, struct svc_req *rqstp)
19550Sstevel@tonic-gate {
19562881Smp153739      static getprivs_ret	    ret;
19572881Smp153739      char *client_name = NULL, *service_name = NULL;
19582881Smp153739      OM_uint32 min_stat;
19592881Smp153739      kadm5_server_handle_t handle;
19602881Smp153739      gss_name_t name = NULL;
19610Sstevel@tonic-gate 
19622881Smp153739      xdr_free(xdr_getprivs_ret, (char *) &ret);
19630Sstevel@tonic-gate 
19642881Smp153739      if ((ret.code = new_server_handle(*arg, rqstp, &handle)))
19652881Smp153739 	  return &ret;
19660Sstevel@tonic-gate 
19672881Smp153739      if ((ret.code = check_handle((void *)handle)))
19680Sstevel@tonic-gate 		goto error;
19692881Smp153739 
19702881Smp153739      ret.api_version = handle->api_version;
19710Sstevel@tonic-gate 
19722881Smp153739      if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
19732881Smp153739 	  ret.code = KADM5_FAILURE;
19742881Smp153739 	  goto error;
19752881Smp153739      }
19760Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
19770Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
19780Sstevel@tonic-gate 		goto error;
19790Sstevel@tonic-gate 	}
19800Sstevel@tonic-gate 
19810Sstevel@tonic-gate 	ret.code = __kadm5_get_priv((void *) handle, &ret.privs, name);
19820Sstevel@tonic-gate 
19830Sstevel@tonic-gate 	audit_kadmind_auth(rqstp->rq_xprt, l_port,
19840Sstevel@tonic-gate 			"kadm5_get_privs", NULL, client_name,
19850Sstevel@tonic-gate 			ret.code);
19863998Ssemery 	log_done("kadm5_get_privs", client_name,
19870Sstevel@tonic-gate 	    ((ret.code == 0) ? "success" : error_message(ret.code)),
19880Sstevel@tonic-gate 	    client_name, service_name, client_addr(rqstp, buf));
19890Sstevel@tonic-gate 
19900Sstevel@tonic-gate error:
19910Sstevel@tonic-gate 	if (name)
19920Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
19930Sstevel@tonic-gate 	free_server_handle(handle);
19940Sstevel@tonic-gate 	if (client_name)
19950Sstevel@tonic-gate 		free(client_name);
19960Sstevel@tonic-gate 	if (service_name)
19970Sstevel@tonic-gate 		free(service_name);
19980Sstevel@tonic-gate 	return (&ret);
19990Sstevel@tonic-gate }
20000Sstevel@tonic-gate 
20012881Smp153739 generic_ret *init_1_svc(krb5_ui_4 *arg, struct svc_req *rqstp)
20020Sstevel@tonic-gate {
20032881Smp153739      static generic_ret		ret;
20043998Ssemery      char *client_name, *service_name;
20053998Ssemery      kadm5_server_handle_t handle;
20063998Ssemery      size_t clen, slen;
20073998Ssemery      char *cdots, *sdots;
20080Sstevel@tonic-gate 
20092881Smp153739      xdr_free(xdr_generic_ret, (char *) &ret);
20100Sstevel@tonic-gate 
20112881Smp153739      if ((ret.code = new_server_handle(*arg, rqstp, &handle)))
20122881Smp153739 	  return &ret;
20132881Smp153739      if (! (ret.code = check_handle((void *)handle))) {
20142881Smp153739 	 ret.api_version = handle->api_version;
20152881Smp153739      }
20160Sstevel@tonic-gate 
20172881Smp153739      free_server_handle(handle);
20182881Smp153739 
20192881Smp153739      if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
20202881Smp153739 	  ret.code = KADM5_FAILURE;
20212881Smp153739 	  return &ret;
20222881Smp153739      }
20230Sstevel@tonic-gate 
20240Sstevel@tonic-gate 	audit_kadmind_auth(rqstp->rq_xprt, l_port,
20250Sstevel@tonic-gate 			(ret.api_version == KADM5_API_VERSION_1 ?
20260Sstevel@tonic-gate 			"kadm5_init (V1)" : "kadm5_init"),
20270Sstevel@tonic-gate 			NULL, client_name, ret.code);
20283998Ssemery 
20293998Ssemery 	clen = strlen(client_name);
20303998Ssemery 	trunc_name(&clen, &cdots);
20313998Ssemery 	slen = strlen(service_name);
20323998Ssemery 	trunc_name(&slen, &sdots);
20333998Ssemery 	krb5_klog_syslog(LOG_NOTICE, "Request %s, %.*s%s, %s, "
20343998Ssemery 	    "client=%.*s%s, service=%.*s%s, addr=%s, flavor=%d",
20350Sstevel@tonic-gate 	    (ret.api_version == KADM5_API_VERSION_1 ?
20363998Ssemery 	    "kadm5_init (V1)" : "kadm5_init"),
20373998Ssemery 	    clen, client_name, cdots,
20382881Smp153739 	    (ret.code == 0) ? "success" : error_message(ret.code),
20393998Ssemery 	    clen, client_name, cdots,
20403998Ssemery 	    slen, service_name, sdots,
20413998Ssemery 	    client_addr(rqstp, buf),
20423998Ssemery 	    rqstp->rq_cred.oa_flavor);
20430Sstevel@tonic-gate 	free(client_name);
20440Sstevel@tonic-gate 	free(service_name);
20450Sstevel@tonic-gate 
20460Sstevel@tonic-gate 	return (&ret);
20470Sstevel@tonic-gate }
2048