xref: /onnv-gate/usr/src/cmd/krb5/kadmin/server/server_stubs.c (revision 7934:6aeeafc994de)
10Sstevel@tonic-gate /*
26426Smp153739  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
30Sstevel@tonic-gate  * Use is subject to license terms.
40Sstevel@tonic-gate  */
50Sstevel@tonic-gate 
60Sstevel@tonic-gate 
70Sstevel@tonic-gate /*
80Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
90Sstevel@tonic-gate  *
100Sstevel@tonic-gate  *	Openvision retains the copyright to derivative works of
110Sstevel@tonic-gate  *	this source code.  Do *NOT* create a derivative of this
120Sstevel@tonic-gate  *	source code before consulting with your legal department.
130Sstevel@tonic-gate  *	Do *NOT* integrate *ANY* of this source code into another
140Sstevel@tonic-gate  *	product before consulting with your legal department.
150Sstevel@tonic-gate  *
160Sstevel@tonic-gate  *	For further information, read the top-level Openvision
170Sstevel@tonic-gate  *	copyright which is contained in the top-level MIT Kerberos
180Sstevel@tonic-gate  *	copyright.
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
210Sstevel@tonic-gate  *
220Sstevel@tonic-gate  */
230Sstevel@tonic-gate 
240Sstevel@tonic-gate 
250Sstevel@tonic-gate /*
260Sstevel@tonic-gate  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
270Sstevel@tonic-gate  *
280Sstevel@tonic-gate  */
290Sstevel@tonic-gate 
30*7934SMark.Phalan@Sun.COM #include <kadm5/admin.h>
310Sstevel@tonic-gate #include <gssapi/gssapi.h>
320Sstevel@tonic-gate #include <gssapi_krb5.h>   /* for gss_nt_krb5_name */
330Sstevel@tonic-gate #include <kadm5/kadm_rpc.h>
340Sstevel@tonic-gate #include <kadm5/server_internal.h>
350Sstevel@tonic-gate #include <kadm5/srv/server_acl.h>
360Sstevel@tonic-gate #include <security/pam_appl.h>
370Sstevel@tonic-gate 
380Sstevel@tonic-gate #include <syslog.h>
392881Smp153739 #include <arpa/inet.h>  /* inet_ntoa */
402881Smp153739 #include <krb5/adm_proto.h>  /* krb5_klog_syslog */
410Sstevel@tonic-gate #include <libintl.h>
42*7934SMark.Phalan@Sun.COM #include <krb5.h>
430Sstevel@tonic-gate #include "misc.h"
440Sstevel@tonic-gate 
452881Smp153739 #define LOG_UNAUTH  gettext("Unauthorized request: %s, %s, " \
460Sstevel@tonic-gate 			    "client=%s, service=%s, addr=%s")
472881Smp153739 #define	LOG_DONE   gettext("Request: %s, %s, %s, client=%s, " \
480Sstevel@tonic-gate 			    "service=%s, addr=%s")
490Sstevel@tonic-gate 
502881Smp153739 extern gss_name_t 			gss_changepw_name;
512881Smp153739 extern gss_name_t			gss_oldchangepw_name;
522881Smp153739 extern void *				global_server_handle;
530Sstevel@tonic-gate extern short l_port;
540Sstevel@tonic-gate 
550Sstevel@tonic-gate char buf[33];
560Sstevel@tonic-gate 
572881Smp153739 #define CHANGEPW_SERVICE(rqstp) \
580Sstevel@tonic-gate 	(cmp_gss_names_rel_1(acceptor_name(rqstp), gss_changepw_name) |\
592881Smp153739 	 (gss_oldchangepw_name && \
602881Smp153739 	  cmp_gss_names_rel_1(acceptor_name(rqstp), \
610Sstevel@tonic-gate 			gss_oldchangepw_name)))
620Sstevel@tonic-gate 
632881Smp153739 
642881Smp153739 static int gss_to_krb5_name(kadm5_server_handle_t handle,
652881Smp153739 		     gss_name_t gss_name, krb5_principal *princ);
662881Smp153739 
672881Smp153739 static int gss_name_to_string(gss_name_t gss_name, gss_buffer_desc *str);
682881Smp153739 
692881Smp153739 static gss_name_t acceptor_name(struct svc_req * rqstp);
702881Smp153739 
710Sstevel@tonic-gate kadm5_ret_t
720Sstevel@tonic-gate kadm5_get_priv(void *server_handle,
730Sstevel@tonic-gate     long *privs, gss_name_t clnt);
740Sstevel@tonic-gate 
750Sstevel@tonic-gate gss_name_t
760Sstevel@tonic-gate get_clnt_name(struct svc_req * rqstp)
770Sstevel@tonic-gate {
780Sstevel@tonic-gate 	OM_uint32 maj_stat, min_stat;
790Sstevel@tonic-gate 	gss_name_t name;
800Sstevel@tonic-gate 	rpc_gss_rawcred_t *raw_cred;
810Sstevel@tonic-gate 	void *cookie;
820Sstevel@tonic-gate 	gss_buffer_desc name_buff;
830Sstevel@tonic-gate 
840Sstevel@tonic-gate 	rpc_gss_getcred(rqstp, &raw_cred, NULL, &cookie);
850Sstevel@tonic-gate 	name_buff.value = raw_cred->client_principal->name;
860Sstevel@tonic-gate 	name_buff.length = raw_cred->client_principal->len;
870Sstevel@tonic-gate 	maj_stat = gss_import_name(&min_stat, &name_buff,
880Sstevel@tonic-gate 	    (gss_OID) GSS_C_NT_EXPORT_NAME, &name);
890Sstevel@tonic-gate 	if (maj_stat != GSS_S_COMPLETE) {
900Sstevel@tonic-gate 		return (NULL);
910Sstevel@tonic-gate 	}
920Sstevel@tonic-gate 	return (name);
930Sstevel@tonic-gate }
940Sstevel@tonic-gate 
950Sstevel@tonic-gate char *
960Sstevel@tonic-gate client_addr(struct svc_req * req, char *buf)
970Sstevel@tonic-gate {
980Sstevel@tonic-gate 	struct sockaddr *ca;
990Sstevel@tonic-gate 	u_char *b;
1000Sstevel@tonic-gate 	char *frontspace = " ";
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate 	/*
1030Sstevel@tonic-gate 	 * Convert the caller's IP address to a dotted string
1040Sstevel@tonic-gate 	 */
1050Sstevel@tonic-gate 	ca = (struct sockaddr *)
1060Sstevel@tonic-gate 	    svc_getrpccaller(req->rq_xprt)->buf;
1070Sstevel@tonic-gate 
1080Sstevel@tonic-gate 	if (ca->sa_family == AF_INET) {
1090Sstevel@tonic-gate 		b = (u_char *) & ((struct sockaddr_in *) ca)->sin_addr;
1100Sstevel@tonic-gate 		(void) sprintf(buf, "%s(%d.%d.%d.%d) ", frontspace,
1110Sstevel@tonic-gate 		    b[0] & 0xFF, b[1] & 0xFF, b[2] & 0xFF, b[3] & 0xFF);
1120Sstevel@tonic-gate 	} else {
1130Sstevel@tonic-gate 		/*
1140Sstevel@tonic-gate 		 * No IP address to print. If there was a host name
1150Sstevel@tonic-gate 		 * printed, then we print a space.
1160Sstevel@tonic-gate 		 */
1170Sstevel@tonic-gate 		(void) sprintf(buf, frontspace);
1180Sstevel@tonic-gate 	}
1190Sstevel@tonic-gate 
1200Sstevel@tonic-gate 	return (buf);
1210Sstevel@tonic-gate }
1220Sstevel@tonic-gate 
1232881Smp153739 static int cmp_gss_names(gss_name_t n1, gss_name_t n2)
1240Sstevel@tonic-gate {
1252881Smp153739    OM_uint32 emaj, emin;
1262881Smp153739    int equal;
1270Sstevel@tonic-gate 
1282881Smp153739    if (GSS_ERROR(emaj = gss_compare_name(&emin, n1, n2, &equal)))
1292881Smp153739       return(0);
1300Sstevel@tonic-gate 
1312881Smp153739    return(equal);
1320Sstevel@tonic-gate }
1330Sstevel@tonic-gate 
1340Sstevel@tonic-gate /* Does a comparison of the names and then releases the first entity */
1350Sstevel@tonic-gate /* For use above in CHANGEPW_SERVICE */
1362881Smp153739 static int cmp_gss_names_rel_1(gss_name_t n1, gss_name_t n2)
1370Sstevel@tonic-gate {
1380Sstevel@tonic-gate    OM_uint32 min_stat;
1390Sstevel@tonic-gate    int ret;
1402881Smp153739 
1412881Smp153739    ret = cmp_gss_names(n1, n2);
1420Sstevel@tonic-gate    if (n1) (void) gss_release_name(&min_stat, &n1);
1430Sstevel@tonic-gate    return ret;
1440Sstevel@tonic-gate }
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate /*
1470Sstevel@tonic-gate  * Function check_handle
1480Sstevel@tonic-gate  *
1490Sstevel@tonic-gate  * Purpose: Check a server handle and return a com_err code if it is
1500Sstevel@tonic-gate  * invalid or 0 if it is valid.
1510Sstevel@tonic-gate  *
1520Sstevel@tonic-gate  * Arguments:
1530Sstevel@tonic-gate  *
1540Sstevel@tonic-gate  * 	handle		The server handle.
1550Sstevel@tonic-gate  */
1560Sstevel@tonic-gate 
1572881Smp153739 static int check_handle(void *handle)
1580Sstevel@tonic-gate {
1592881Smp153739      CHECK_HANDLE(handle);
1602881Smp153739      return 0;
1610Sstevel@tonic-gate }
1620Sstevel@tonic-gate 
1630Sstevel@tonic-gate /*
1640Sstevel@tonic-gate  * Function: new_server_handle
1650Sstevel@tonic-gate  *
1660Sstevel@tonic-gate  * Purpose: Constructs a server handle suitable for passing into the
1670Sstevel@tonic-gate  * server library API functions, by folding the client's API version
1680Sstevel@tonic-gate  * and calling principal into the server handle returned by
1690Sstevel@tonic-gate  * kadm5_init.
1700Sstevel@tonic-gate  *
1710Sstevel@tonic-gate  * Arguments:
1720Sstevel@tonic-gate  * 	api_version	(input) The API version specified by the client
1730Sstevel@tonic-gate  * 	rqstp		(input) The RPC request
1740Sstevel@tonic-gate  * 	handle		(output) The returned handle
1750Sstevel@tonic-gate  *	<return value>	(output) An error code, or 0 if no error occurred
1762881Smp153739  *
1770Sstevel@tonic-gate  * Effects:
1780Sstevel@tonic-gate  * 	Returns a pointer to allocated storage containing the server
1790Sstevel@tonic-gate  * 	handle.  If an error occurs, then no allocated storage is
1800Sstevel@tonic-gate  *	returned, and the return value of the function will be a
1810Sstevel@tonic-gate  * 	non-zero com_err code.
1822881Smp153739  *
1830Sstevel@tonic-gate  *      The allocated storage for the handle should be freed with
1840Sstevel@tonic-gate  * 	free_server_handle (see below) when it is no longer needed.
1850Sstevel@tonic-gate  */
1860Sstevel@tonic-gate 
1872881Smp153739 static kadm5_ret_t new_server_handle(krb5_ui_4 api_version,
1882881Smp153739 					  struct svc_req *rqstp,
1892881Smp153739 					  kadm5_server_handle_t
1902881Smp153739 					  *out_handle)
1910Sstevel@tonic-gate {
1922881Smp153739      kadm5_server_handle_t handle;
1930Sstevel@tonic-gate 	gss_name_t name;
1940Sstevel@tonic-gate 	OM_uint32 min_stat;
1950Sstevel@tonic-gate 
1962881Smp153739      if (! (handle = (kadm5_server_handle_t)
1972881Smp153739 	    malloc(sizeof(*handle))))
1982881Smp153739 	  return ENOMEM;
1990Sstevel@tonic-gate 
2002881Smp153739      *handle = *(kadm5_server_handle_t)global_server_handle;
2012881Smp153739      handle->api_version = api_version;
2020Sstevel@tonic-gate 
2032881Smp153739      if (!(name = get_clnt_name(rqstp))) {
2042881Smp153739 	  free(handle);
2052881Smp153739 	  return KADM5_FAILURE;
2062881Smp153739      }
2072881Smp153739     if (! gss_to_krb5_name(handle, name, &handle->current_caller)) {
2082881Smp153739 	  free(handle);
2090Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
2102881Smp153739 	  return KADM5_FAILURE;
2110Sstevel@tonic-gate 	}
2120Sstevel@tonic-gate 	gss_release_name(&min_stat, &name);
2130Sstevel@tonic-gate 
2142881Smp153739      *out_handle = handle;
2152881Smp153739      return 0;
2160Sstevel@tonic-gate }
2170Sstevel@tonic-gate 
2180Sstevel@tonic-gate /*
2190Sstevel@tonic-gate  * Function: free_server_handle
2200Sstevel@tonic-gate  *
2210Sstevel@tonic-gate  * Purpose: Free handle memory allocated by new_server_handle
2220Sstevel@tonic-gate  *
2230Sstevel@tonic-gate  * Arguments:
2240Sstevel@tonic-gate  * 	handle		(input/output) The handle to free
2250Sstevel@tonic-gate  */
2262881Smp153739 static void free_server_handle(kadm5_server_handle_t handle)
2270Sstevel@tonic-gate {
2282881Smp153739      krb5_free_principal(handle->context, handle->current_caller);
2292881Smp153739      free(handle);
2300Sstevel@tonic-gate }
2310Sstevel@tonic-gate 
2320Sstevel@tonic-gate /*
2330Sstevel@tonic-gate  * Function: setup_gss_names
2340Sstevel@tonic-gate  *
2350Sstevel@tonic-gate  * Purpose: Create printable representations of the client and server
2360Sstevel@tonic-gate  * names.
2370Sstevel@tonic-gate  *
2380Sstevel@tonic-gate  * Arguments:
2390Sstevel@tonic-gate  * 	rqstp		(r) the RPC request
2400Sstevel@tonic-gate  * 	client_name	(w) pointer to client_name string
2410Sstevel@tonic-gate  * 	server_name	(w) pointer to server_name string
2420Sstevel@tonic-gate  *
2430Sstevel@tonic-gate  * Effects:
2440Sstevel@tonic-gate  *
2450Sstevel@tonic-gate  * Unparses the client and server names into client_name and
2460Sstevel@tonic-gate  * server_name, both of which must be freed by the caller.  Returns 0
2470Sstevel@tonic-gate  * on success and -1 on failure. On failure client_name and server_name
2480Sstevel@tonic-gate  * will point to null.
2490Sstevel@tonic-gate  */
2502881Smp153739 /* SUNW14resync */
2512881Smp153739 int setup_gss_names(struct svc_req *rqstp,
2520Sstevel@tonic-gate     char **client_name, char **server_name)
2530Sstevel@tonic-gate {
2542881Smp153739      OM_uint32 maj_stat, min_stat;
2550Sstevel@tonic-gate 	rpc_gss_rawcred_t *raw_cred;
2560Sstevel@tonic-gate 	gss_buffer_desc name_buf;
2570Sstevel@tonic-gate 	char *tmp, *val;
2580Sstevel@tonic-gate 	size_t len;
2590Sstevel@tonic-gate 	gss_name_t name;
2600Sstevel@tonic-gate 
2610Sstevel@tonic-gate 	*client_name = NULL;
2620Sstevel@tonic-gate 
2630Sstevel@tonic-gate 	rpc_gss_getcred(rqstp, &raw_cred, NULL, NULL);
2640Sstevel@tonic-gate 
2650Sstevel@tonic-gate 	/* Return a copy of the service principal from the raw_cred */
2660Sstevel@tonic-gate 	*server_name = strdup(raw_cred->svc_principal);
2670Sstevel@tonic-gate 
2680Sstevel@tonic-gate 	if (*server_name == NULL)
2690Sstevel@tonic-gate 		return (-1);
2700Sstevel@tonic-gate 
2710Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
2720Sstevel@tonic-gate 		free(*server_name);
2730Sstevel@tonic-gate 		*server_name = NULL;
2740Sstevel@tonic-gate 		return (-1);
2750Sstevel@tonic-gate 	}
2760Sstevel@tonic-gate 	maj_stat = gss_display_name(&min_stat, name, &name_buf, NULL);
2770Sstevel@tonic-gate 	if (maj_stat != GSS_S_COMPLETE) {
2780Sstevel@tonic-gate 		free(*server_name);
2790Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
2800Sstevel@tonic-gate 		*server_name = NULL;
2810Sstevel@tonic-gate 		return (-1);
2820Sstevel@tonic-gate 	}
2830Sstevel@tonic-gate 	gss_release_name(&min_stat, &name);
2840Sstevel@tonic-gate 
2850Sstevel@tonic-gate 	/*
2860Sstevel@tonic-gate 	 * Allocate space to copy the client principal. We allocate an
2870Sstevel@tonic-gate 	 * extra byte to make the string null terminated if we need to.
2880Sstevel@tonic-gate 	 */
2890Sstevel@tonic-gate 
2900Sstevel@tonic-gate 	val = name_buf.value;
2910Sstevel@tonic-gate 	len = name_buf.length + (val[name_buf.length - 1] != '\0');
2920Sstevel@tonic-gate 
2930Sstevel@tonic-gate 	/* len is the length including the null terminating byte. */
2940Sstevel@tonic-gate 
2950Sstevel@tonic-gate 	tmp = malloc(len);
2960Sstevel@tonic-gate 	if (tmp) {
2970Sstevel@tonic-gate 		memcpy(tmp, val, len - 1);
2980Sstevel@tonic-gate 		tmp[len - 1] = '\0';
2990Sstevel@tonic-gate 	} else {
3000Sstevel@tonic-gate 		free(*server_name);
3010Sstevel@tonic-gate 		*server_name = NULL;
3020Sstevel@tonic-gate 	}
3030Sstevel@tonic-gate 
3040Sstevel@tonic-gate 	/* Were done with the GSS buffer */
3050Sstevel@tonic-gate 	(void) gss_release_buffer(&min_stat, &name_buf);
3060Sstevel@tonic-gate 
3070Sstevel@tonic-gate 	*client_name = tmp;
3080Sstevel@tonic-gate 
3090Sstevel@tonic-gate 	return (tmp ? 0 : -1);
3100Sstevel@tonic-gate }
3110Sstevel@tonic-gate 
3122881Smp153739 static gss_name_t acceptor_name(struct svc_req * rqstp)
3130Sstevel@tonic-gate {
3142881Smp153739      OM_uint32 maj_stat, min_stat;
3152881Smp153739      gss_name_t name;
3162881Smp153739      rpc_gss_rawcred_t *raw_cred;
3172881Smp153739      void *cookie;
3182881Smp153739      gss_buffer_desc name_buff;
3190Sstevel@tonic-gate 
3202881Smp153739 	rpc_gss_getcred(rqstp, &raw_cred, NULL, &cookie);
3212881Smp153739 	name_buff.value = raw_cred->svc_principal;
3222881Smp153739 	name_buff.length = strlen(raw_cred->svc_principal);
3232881Smp153739 	maj_stat = gss_import_name(&min_stat, &name_buff,
3242881Smp153739 	    (gss_OID) gss_nt_krb5_name, &name);
3252881Smp153739 	if (maj_stat != GSS_S_COMPLETE) {
3262881Smp153739 		gss_release_buffer(&min_stat, &name_buff);
3272881Smp153739 		return (NULL);
3282881Smp153739 	}
3292881Smp153739 	maj_stat = gss_display_name(&min_stat, name, &name_buff, NULL);
3302881Smp153739     if (maj_stat != GSS_S_COMPLETE) {
3312881Smp153739 		gss_release_buffer(&min_stat, &name_buff);
3322881Smp153739 	  return (NULL);
3332881Smp153739 	}
3342881Smp153739 	gss_release_buffer(&min_stat, &name_buff);
3352881Smp153739 
3362881Smp153739      return name;
3372881Smp153739 }
3382881Smp153739 
3392881Smp153739 static int cmp_gss_krb5_name(kadm5_server_handle_t handle,
3402881Smp153739 		      gss_name_t gss_name, krb5_principal princ)
3412881Smp153739 {
3422881Smp153739      krb5_principal princ2;
3432881Smp153739      int status;
3442881Smp153739 
3452881Smp153739      if (! gss_to_krb5_name(handle, gss_name, &princ2))
3462881Smp153739 	  return 0;
3472881Smp153739      status = krb5_principal_compare(handle->context, princ, princ2);
3482881Smp153739      krb5_free_principal(handle->context, princ2);
3492881Smp153739      return status;
3500Sstevel@tonic-gate }
3510Sstevel@tonic-gate 
3520Sstevel@tonic-gate 
3530Sstevel@tonic-gate /*
3540Sstevel@tonic-gate  * This routine primarily validates the username and password
3550Sstevel@tonic-gate  * of the principal to be created, if a prior acl check for
3560Sstevel@tonic-gate  * the 'u' privilege succeeds. Validation is done using
3570Sstevel@tonic-gate  * the PAM `k5migrate' service. k5migrate normally stacks
3580Sstevel@tonic-gate  * pam_unix_auth.so and pam_unix_account.so in its auth and
3590Sstevel@tonic-gate  * account stacks respectively.
3600Sstevel@tonic-gate  *
3610Sstevel@tonic-gate  * Returns 1 (true), if validation is successful,
3620Sstevel@tonic-gate  * else returns 0 (false).
3630Sstevel@tonic-gate  */
3640Sstevel@tonic-gate int verify_pam_pw(char *userdata, char *pwd) {
3650Sstevel@tonic-gate 	pam_handle_t *pamh;
3660Sstevel@tonic-gate 	int err = 0;
3670Sstevel@tonic-gate 	int result = 1;
3680Sstevel@tonic-gate 	char *user = NULL;
3690Sstevel@tonic-gate 	char *ptr = NULL;
3700Sstevel@tonic-gate 
3710Sstevel@tonic-gate 	ptr = strchr(userdata, '@');
3720Sstevel@tonic-gate 	if (ptr != NULL) {
3730Sstevel@tonic-gate 		user = (char *)malloc(ptr - userdata + 1);
3740Sstevel@tonic-gate 		(void) strlcpy(user, userdata, (ptr - userdata) + 1);
3750Sstevel@tonic-gate 	} else {
3760Sstevel@tonic-gate 		user = (char *)strdup(userdata);
3770Sstevel@tonic-gate 	}
3780Sstevel@tonic-gate 
3790Sstevel@tonic-gate 	err = pam_start("k5migrate", user, NULL, &pamh);
3800Sstevel@tonic-gate 	if (err != PAM_SUCCESS) {
3810Sstevel@tonic-gate 		syslog(LOG_ERR, "verify_pam_pw: pam_start() failed, %s\n",
3820Sstevel@tonic-gate 				pam_strerror(pamh, err));
3830Sstevel@tonic-gate 		if (user)
3840Sstevel@tonic-gate 			free(user);
3850Sstevel@tonic-gate 		return (0);
3860Sstevel@tonic-gate 	}
3870Sstevel@tonic-gate 	if (user)
3880Sstevel@tonic-gate 		free(user);
3890Sstevel@tonic-gate 
3900Sstevel@tonic-gate 	err = pam_set_item(pamh, PAM_AUTHTOK, (void *)pwd);
3910Sstevel@tonic-gate 	if (err != PAM_SUCCESS) {
3920Sstevel@tonic-gate 		syslog(LOG_ERR, "verify_pam_pw: pam_set_item() failed, %s\n",
3930Sstevel@tonic-gate 				pam_strerror(pamh, err));
3940Sstevel@tonic-gate 		(void) pam_end(pamh, err);
3950Sstevel@tonic-gate 		return (0);
3960Sstevel@tonic-gate 	}
3970Sstevel@tonic-gate 
3980Sstevel@tonic-gate 	err = pam_authenticate(pamh, PAM_SILENT);
3990Sstevel@tonic-gate 	if (err != PAM_SUCCESS) {
4000Sstevel@tonic-gate 		syslog(LOG_ERR, "verify_pam_pw: pam_authenticate() "
4010Sstevel@tonic-gate 				"failed, %s\n", pam_strerror(pamh, err));
4020Sstevel@tonic-gate 		(void) pam_end(pamh, err);
4030Sstevel@tonic-gate 		return (0);
4040Sstevel@tonic-gate 	}
4050Sstevel@tonic-gate 
4060Sstevel@tonic-gate 	err = pam_acct_mgmt(pamh, PAM_SILENT);
4070Sstevel@tonic-gate 	if (err != PAM_SUCCESS) {
4080Sstevel@tonic-gate 		syslog(LOG_ERR, "verify_pam_pw: pam_acct_mgmt() failed, %s\n",
4090Sstevel@tonic-gate 				pam_strerror(pamh, err));
4100Sstevel@tonic-gate 		(void) pam_end(pamh, err);
4110Sstevel@tonic-gate 		return (0);
4120Sstevel@tonic-gate 	}
4130Sstevel@tonic-gate 
4140Sstevel@tonic-gate 	(void) pam_end(pamh, PAM_SUCCESS);
4150Sstevel@tonic-gate 	return (result);
4160Sstevel@tonic-gate }
4170Sstevel@tonic-gate 
4182881Smp153739 static int gss_to_krb5_name(kadm5_server_handle_t handle,
4192881Smp153739 		     gss_name_t gss_name, krb5_principal *princ)
4200Sstevel@tonic-gate {
4212881Smp153739      OM_uint32 status, minor_stat;
4222881Smp153739      gss_buffer_desc gss_str;
4232881Smp153739      gss_OID gss_type;
4242881Smp153739      int success;
4250Sstevel@tonic-gate 
4262881Smp153739      status = gss_display_name(&minor_stat, gss_name, &gss_str, &gss_type);
4272881Smp153739      if ((status != GSS_S_COMPLETE) || (!g_OID_equal(gss_type, gss_nt_krb5_name)))
4282881Smp153739 	  return 0;
4292881Smp153739      success = (krb5_parse_name(handle->context, gss_str.value, princ) == 0);
4302881Smp153739      gss_release_buffer(&minor_stat, &gss_str);
4312881Smp153739      return success;
4322881Smp153739 }
4330Sstevel@tonic-gate 
4342881Smp153739 static int
4352881Smp153739 gss_name_to_string(gss_name_t gss_name, gss_buffer_desc *str)
4362881Smp153739 {
4372881Smp153739      OM_uint32 status, minor_stat;
4382881Smp153739      gss_OID gss_type;
4392881Smp153739 
4402881Smp153739      status = gss_display_name(&minor_stat, gss_name, str, &gss_type);
4412881Smp153739      if ((status != GSS_S_COMPLETE) || (gss_type != gss_nt_krb5_name))
4422881Smp153739 	  return 1;
4432881Smp153739      return 0;
4442881Smp153739 }
4450Sstevel@tonic-gate 
4463998Ssemery static int
4473998Ssemery log_unauth(
4483998Ssemery     char *op,
4493998Ssemery     char *target,
4503998Ssemery     char *client,
4513998Ssemery     char *server,
4523998Ssemery     char *addr)
4533998Ssemery {
4543998Ssemery     size_t tlen, clen, slen;
4553998Ssemery     char *tdots, *cdots, *sdots;
4563998Ssemery 
4573998Ssemery     tlen = strlen(target);
4583998Ssemery     trunc_name(&tlen, &tdots);
4593998Ssemery     clen = strlen(client);
4603998Ssemery     trunc_name(&clen, &cdots);
4613998Ssemery     slen = strlen(server);
4623998Ssemery     trunc_name(&slen, &sdots);
4633998Ssemery 
4643998Ssemery     return krb5_klog_syslog(LOG_NOTICE,
465*7934SMark.Phalan@Sun.COM 			    "Unauthorized request: %s, %.*s%s, "
466*7934SMark.Phalan@Sun.COM 			    "client=%.*s%s, service=%.*s%s, addr=%s",
467*7934SMark.Phalan@Sun.COM 			    op, tlen, target, tdots,
468*7934SMark.Phalan@Sun.COM 			    clen, client, cdots,
469*7934SMark.Phalan@Sun.COM 			    slen, server, sdots,
470*7934SMark.Phalan@Sun.COM 			    addr);
4713998Ssemery }
4723998Ssemery 
4733998Ssemery static int
4743998Ssemery log_done(
4753998Ssemery     char *op,
4763998Ssemery     char *target,
4773998Ssemery     const char *errmsg,
4783998Ssemery     char *client,
4793998Ssemery     char *server,
4803998Ssemery     char *addr)
4813998Ssemery {
4823998Ssemery     size_t tlen, clen, slen;
4833998Ssemery     char *tdots, *cdots, *sdots;
4843998Ssemery 
4853998Ssemery     tlen = strlen(target);
4863998Ssemery     trunc_name(&tlen, &tdots);
4873998Ssemery     clen = strlen(client);
4883998Ssemery     trunc_name(&clen, &cdots);
4893998Ssemery     slen = strlen(server);
4903998Ssemery     trunc_name(&slen, &sdots);
4913998Ssemery 
4923998Ssemery     return krb5_klog_syslog(LOG_NOTICE,
493*7934SMark.Phalan@Sun.COM 			    "Request: %s, %.*s%s, %s, "
494*7934SMark.Phalan@Sun.COM 			    "client=%.*s%s, service=%.*s%s, addr=%s",
495*7934SMark.Phalan@Sun.COM 			    op, tlen, target, tdots, errmsg,
496*7934SMark.Phalan@Sun.COM 			    clen, client, cdots,
497*7934SMark.Phalan@Sun.COM 			    slen, server, sdots,
498*7934SMark.Phalan@Sun.COM 			    addr);
4993998Ssemery }
5003998Ssemery 
5012881Smp153739 generic_ret *
502*7934SMark.Phalan@Sun.COM create_principal_2_svc(cprinc_arg *arg, struct svc_req *rqstp)
5032881Smp153739 {
5042881Smp153739     static generic_ret		ret;
5052881Smp153739     char			*prime_arg = NULL;
5062881Smp153739     char *client_name = NULL, *service_name = NULL;
5072881Smp153739     int policy_migrate = 0;
5080Sstevel@tonic-gate 
5092881Smp153739     OM_uint32			minor_stat;
5102881Smp153739     kadm5_server_handle_t	handle;
5112881Smp153739     kadm5_ret_t retval;
5122881Smp153739     restriction_t		*rp;
513*7934SMark.Phalan@Sun.COM     const char			*errmsg = NULL;
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);
561*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
562*7934SMark.Phalan@Sun.COM 	 if( ret.code != 0 )
563*7934SMark.Phalan@Sun.COM 	     errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
5640Sstevel@tonic-gate 
5650Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
5660Sstevel@tonic-gate 				"kadm5_create_principal",
5670Sstevel@tonic-gate 				prime_arg, client_name, ret.code);
5683998Ssemery 	 log_done("kadm5_create_principal", prime_arg,
569*7934SMark.Phalan@Sun.COM 	    errmsg ? errmsg : "success",
5703998Ssemery 	    client_name, service_name, client_addr(rqstp, buf));
5710Sstevel@tonic-gate 
572*7934SMark.Phalan@Sun.COM 	  if (errmsg != NULL)
573*7934SMark.Phalan@Sun.COM 		krb5_free_error_message(handle ? handle->context : NULL, errmsg);
574*7934SMark.Phalan@Sun.COM 
5750Sstevel@tonic-gate 		if (policy_migrate && (ret.code == 0)) {
5760Sstevel@tonic-gate 			arg->rec.policy = strdup("default");
5770Sstevel@tonic-gate 			if ((arg->mask & KADM5_PW_EXPIRATION)) {
5780Sstevel@tonic-gate 				arg->mask = 0;
5790Sstevel@tonic-gate 				arg->mask |= KADM5_POLICY;
5800Sstevel@tonic-gate 				arg->mask |= KADM5_PW_EXPIRATION;
5810Sstevel@tonic-gate 			} else {
5820Sstevel@tonic-gate 				arg->mask = 0;
5830Sstevel@tonic-gate 				arg->mask |= KADM5_POLICY;
5840Sstevel@tonic-gate 			}
5850Sstevel@tonic-gate 
5860Sstevel@tonic-gate 			retval = kadm5_modify_principal((void *)handle,
5870Sstevel@tonic-gate 					&arg->rec, arg->mask);
5883998Ssemery 			log_done("kadm5_modify_principal",
5890Sstevel@tonic-gate 				prime_arg, ((retval == 0) ? "success" :
5900Sstevel@tonic-gate 				error_message(retval)), client_name,
5910Sstevel@tonic-gate 				service_name, client_addr(rqstp, buf));
5920Sstevel@tonic-gate 		}
5930Sstevel@tonic-gate 	}
5940Sstevel@tonic-gate 
5950Sstevel@tonic-gate error:
5962881Smp153739     if (name)
5972881Smp153739     	gss_release_name(&minor_stat, &name);
5982881Smp153739     free_server_handle(handle);
5992881Smp153739     if (prime_arg)
6002881Smp153739     	free(prime_arg);
6012881Smp153739     if (client_name)
6022881Smp153739     	free(client_name);
6032881Smp153739     if (service_name)
6042881Smp153739     	free(service_name);
6052881Smp153739     return (&ret);
6060Sstevel@tonic-gate }
6070Sstevel@tonic-gate 
6080Sstevel@tonic-gate generic_ret *
609*7934SMark.Phalan@Sun.COM create_principal3_2_svc(cprinc3_arg *arg, struct svc_req *rqstp)
6100Sstevel@tonic-gate {
6110Sstevel@tonic-gate     static generic_ret		ret;
6120Sstevel@tonic-gate     char			*prime_arg = NULL;
6130Sstevel@tonic-gate     char			*client_name = NULL, *service_name = NULL;
6140Sstevel@tonic-gate     int				policy_migrate = 0;
6150Sstevel@tonic-gate 
6162881Smp153739     OM_uint32			minor_stat;
6170Sstevel@tonic-gate     kadm5_server_handle_t	handle;
6180Sstevel@tonic-gate     kadm5_ret_t			retval;
6190Sstevel@tonic-gate     restriction_t		*rp;
620*7934SMark.Phalan@Sun.COM     const char                        *errmsg = NULL;
6210Sstevel@tonic-gate     gss_name_t			name = NULL;
6220Sstevel@tonic-gate 
6230Sstevel@tonic-gate     xdr_free(xdr_generic_ret, (char *) &ret);
6240Sstevel@tonic-gate 
6252881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
6260Sstevel@tonic-gate 	 return &ret;
6270Sstevel@tonic-gate 
6282881Smp153739     if ((ret.code = check_handle((void *)handle)))
6290Sstevel@tonic-gate 	goto error;
6300Sstevel@tonic-gate     ret.api_version = handle->api_version;
6310Sstevel@tonic-gate 
6320Sstevel@tonic-gate     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
6332881Smp153739 	 ret.code = KADM5_FAILURE;
6340Sstevel@tonic-gate 	goto error;
6350Sstevel@tonic-gate     }
6360Sstevel@tonic-gate     if (krb5_unparse_name(handle->context, arg->rec.principal, &prime_arg)) {
6372881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
6380Sstevel@tonic-gate 	goto error;
6390Sstevel@tonic-gate     }
6400Sstevel@tonic-gate     if (!(name = get_clnt_name(rqstp))) {
6410Sstevel@tonic-gate 	ret.code = KADM5_FAILURE;
6420Sstevel@tonic-gate 	goto error;
6430Sstevel@tonic-gate     }
6440Sstevel@tonic-gate 
6452881Smp153739     if (kadm5int_acl_check(handle->context, name, ACL_MIGRATE,
6460Sstevel@tonic-gate 		arg->rec.principal, &rp) &&
6470Sstevel@tonic-gate 		verify_pam_pw(prime_arg, arg->passwd)) {
6480Sstevel@tonic-gate 	policy_migrate = 1;
6490Sstevel@tonic-gate     }
6500Sstevel@tonic-gate 
6510Sstevel@tonic-gate     if (CHANGEPW_SERVICE(rqstp)
6522881Smp153739 	|| (!kadm5int_acl_check(handle->context, name, ACL_ADD,
6530Sstevel@tonic-gate 			arg->rec.principal, &rp) &&
6540Sstevel@tonic-gate 	    !(policy_migrate))
6552881Smp153739 	|| kadm5int_acl_impose_restrictions(handle->context,
6560Sstevel@tonic-gate 				   &arg->rec, &arg->mask, rp)) {
6570Sstevel@tonic-gate 	 ret.code = KADM5_AUTH_ADD;
6583998Ssemery 	 log_unauth("kadm5_create_principal", prime_arg,
659*7934SMark.Phalan@Sun.COM 		    client_name, service_name, client_addr(rqstp, buf));
6600Sstevel@tonic-gate     } else {
6610Sstevel@tonic-gate 	 ret.code = kadm5_create_principal_3((void *)handle,
6620Sstevel@tonic-gate 					     &arg->rec, arg->mask,
6630Sstevel@tonic-gate 					     arg->n_ks_tuple,
6640Sstevel@tonic-gate 					     arg->ks_tuple,
6650Sstevel@tonic-gate 					     arg->passwd);
666*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
667*7934SMark.Phalan@Sun.COM 	 if( ret.code != 0 )
668*7934SMark.Phalan@Sun.COM 	     errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
669*7934SMark.Phalan@Sun.COM 
6703998Ssemery 	 log_done("kadm5_create_principal", prime_arg,
671*7934SMark.Phalan@Sun.COM 		  errmsg ? errmsg : "success",
672*7934SMark.Phalan@Sun.COM 		  client_name, service_name, client_addr(rqstp, buf));
673*7934SMark.Phalan@Sun.COM 
674*7934SMark.Phalan@Sun.COM 	  if (errmsg != NULL)
675*7934SMark.Phalan@Sun.COM 		krb5_free_error_message(handle ? handle->context : NULL, errmsg);
6760Sstevel@tonic-gate 
6770Sstevel@tonic-gate 	 if (policy_migrate && (ret.code == 0)) {
6780Sstevel@tonic-gate 	 	arg->rec.policy = strdup("default");
6790Sstevel@tonic-gate 	 	if ((arg->mask & KADM5_PW_EXPIRATION)) {
6800Sstevel@tonic-gate 	 		arg->mask = 0;
6810Sstevel@tonic-gate 	 		arg->mask |= KADM5_POLICY;
6820Sstevel@tonic-gate 	 		arg->mask |= KADM5_PW_EXPIRATION;
6830Sstevel@tonic-gate 	 	} else {
6840Sstevel@tonic-gate 	 		arg->mask = 0;
6850Sstevel@tonic-gate 	 		arg->mask |= KADM5_POLICY;
6860Sstevel@tonic-gate 	 	}
6870Sstevel@tonic-gate 
6880Sstevel@tonic-gate 		retval = kadm5_modify_principal((void *)handle,
6890Sstevel@tonic-gate 					   &arg->rec, arg->mask);
6903998Ssemery 		log_done("kadm5_modify_principal", prime_arg,
6913998Ssemery 			((retval == 0) ? "success" : error_message(retval)),
6923998Ssemery 			client_name, service_name, client_addr(rqstp, buf));
6930Sstevel@tonic-gate 	 }
6940Sstevel@tonic-gate     }
6950Sstevel@tonic-gate 
6960Sstevel@tonic-gate error:
6970Sstevel@tonic-gate     if (name)
6982881Smp153739     	gss_release_name(&minor_stat, &name);
6990Sstevel@tonic-gate     free_server_handle(handle);
7000Sstevel@tonic-gate     if (client_name)
7012881Smp153739     	free(client_name);
7020Sstevel@tonic-gate     if (service_name)
7032881Smp153739     	free(service_name);
7040Sstevel@tonic-gate     if (prime_arg)
7052881Smp153739     	free(prime_arg);
7062881Smp153739     return &ret;
7072881Smp153739 }
7082881Smp153739 
7092881Smp153739 generic_ret *
710*7934SMark.Phalan@Sun.COM delete_principal_2_svc(dprinc_arg *arg, struct svc_req *rqstp)
7112881Smp153739 {
7122881Smp153739     static generic_ret		    ret;
7132881Smp153739     char			    *prime_arg = NULL;
7142881Smp153739     char *client_name = NULL, *service_name = NULL;
715*7934SMark.Phalan@Sun.COM     OM_uint32			    min_stat;
716*7934SMark.Phalan@Sun.COM     kadm5_server_handle_t	    handle;
717*7934SMark.Phalan@Sun.COM     const char                            *errmsg = NULL;
718*7934SMark.Phalan@Sun.COM 
7192881Smp153739     gss_name_t name = NULL;
7202881Smp153739 
721*7934SMark.Phalan@Sun.COM 
7222881Smp153739     xdr_free(xdr_generic_ret, (char *) &ret);
7232881Smp153739 
7242881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
7252881Smp153739 	 return &ret;
7262881Smp153739 
7272881Smp153739     if ((ret.code = check_handle((void *)handle)))
7282881Smp153739 		goto error;
7292881Smp153739     ret.api_version = handle->api_version;
7302881Smp153739 
7312881Smp153739     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
7322881Smp153739 	 ret.code = KADM5_FAILURE;
7332881Smp153739 		goto error;
7342881Smp153739     }
7352881Smp153739     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
7362881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
7372881Smp153739 		goto error;
7382881Smp153739     }
7392881Smp153739 	if (!(name = get_clnt_name(rqstp))) {
7402881Smp153739 		ret.code = KADM5_FAILURE;
7412881Smp153739 		goto error;
7422881Smp153739 	}
7432881Smp153739 
7442881Smp153739     if (CHANGEPW_SERVICE(rqstp)
7452881Smp153739 	|| !kadm5int_acl_check(handle->context, name, ACL_DELETE,
7462881Smp153739 		      arg->princ, NULL)) {
7472881Smp153739 	 ret.code = KADM5_AUTH_DELETE;
7482881Smp153739 
7492881Smp153739 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
7502881Smp153739 				    "kadm5_delete_principal",
7512881Smp153739 				    prime_arg, client_name);
7523998Ssemery 	 log_unauth("kadm5_delete_principal", prime_arg, client_name,
7532881Smp153739 			service_name, client_addr(rqstp, buf));
7542881Smp153739     } else {
7552881Smp153739 	 ret.code = kadm5_delete_principal((void *)handle, arg->princ);
756*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
757*7934SMark.Phalan@Sun.COM 	 if( ret.code != 0 )
758*7934SMark.Phalan@Sun.COM 	     errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
7592881Smp153739 
7602881Smp153739 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
7612881Smp153739 				"kadm5_delete_principal",
7622881Smp153739 				prime_arg, client_name, ret.code);
763*7934SMark.Phalan@Sun.COM 	 log_done("kadm5_delete_principal", prime_arg,
764*7934SMark.Phalan@Sun.COM 		  errmsg ? errmsg : "success",
765*7934SMark.Phalan@Sun.COM 		  client_name, service_name, client_addr(rqstp, buf));
766*7934SMark.Phalan@Sun.COM 
767*7934SMark.Phalan@Sun.COM 	  if (errmsg != NULL)
768*7934SMark.Phalan@Sun.COM 		krb5_free_error_message(handle ? handle->context : NULL, errmsg);
769*7934SMark.Phalan@Sun.COM 
7702881Smp153739     }
7712881Smp153739 
7722881Smp153739 error:
7732881Smp153739     if (name)
7742881Smp153739     	gss_release_name(&min_stat, &name);
7752881Smp153739     if (prime_arg)
7762881Smp153739     	free(prime_arg);
7772881Smp153739     free_server_handle(handle);
7782881Smp153739     if (client_name)
7792881Smp153739     	free(client_name);
7802881Smp153739     if (service_name)
7812881Smp153739     	free(service_name);
7822881Smp153739     return &ret;
7830Sstevel@tonic-gate }
7840Sstevel@tonic-gate 
7850Sstevel@tonic-gate generic_ret *
786*7934SMark.Phalan@Sun.COM modify_principal_2_svc(mprinc_arg *arg, struct svc_req *rqstp)
7870Sstevel@tonic-gate {
7882881Smp153739     static generic_ret		    ret;
7892881Smp153739     char *prime_arg = NULL;
7902881Smp153739     char *client_name = NULL, *service_name = NULL;
7912881Smp153739     OM_uint32 min_stat;
7922881Smp153739     kadm5_server_handle_t handle;
7932881Smp153739     restriction_t *rp;
7942881Smp153739     gss_name_t name = NULL;
795*7934SMark.Phalan@Sun.COM     const char                            *errmsg = NULL;
7962881Smp153739 
7972881Smp153739     xdr_free(xdr_generic_ret, (char *) &ret);
7980Sstevel@tonic-gate 
7992881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
8002881Smp153739 	 return &ret;
8010Sstevel@tonic-gate 
8022881Smp153739     if ((ret.code = check_handle((void *)handle)))
8032881Smp153739 		goto error;
8042881Smp153739    if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
8052881Smp153739 	 ret.code = KADM5_FAILURE;
8060Sstevel@tonic-gate 		goto error;
8072881Smp153739     }
8082881Smp153739     if (krb5_unparse_name(handle->context, arg->rec.principal, &prime_arg)) {
8092881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
8102881Smp153739 	 goto error;
8112881Smp153739     }
8122881Smp153739 	if (!(name = get_clnt_name(rqstp))) {
8130Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
8140Sstevel@tonic-gate 		goto error;
8150Sstevel@tonic-gate 	}
8162881Smp153739 
8172881Smp153739     if (CHANGEPW_SERVICE(rqstp)
8182881Smp153739 	|| !kadm5int_acl_check(handle->context, name, ACL_MODIFY,
8192881Smp153739 		      arg->rec.principal, &rp)
8202881Smp153739 	|| kadm5int_acl_impose_restrictions(handle->context,
8212881Smp153739 				   &arg->rec, &arg->mask, rp)) {
8222881Smp153739 	 ret.code = KADM5_AUTH_MODIFY;
8232881Smp153739 
8242881Smp153739 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
8252881Smp153739 				    "kadm5_modify_principal",
8262881Smp153739 				    prime_arg, client_name);
8273998Ssemery 	 log_unauth("kadm5_modify_principal", prime_arg, client_name,
8282881Smp153739 		    service_name, client_addr(rqstp, buf));
8292881Smp153739     } else {
8302881Smp153739 	 ret.code = kadm5_modify_principal((void *)handle, &arg->rec,
8312881Smp153739 						arg->mask);
832*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
833*7934SMark.Phalan@Sun.COM 	 if( ret.code != 0 )
834*7934SMark.Phalan@Sun.COM 	     errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
8352881Smp153739 
8362881Smp153739 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
8372881Smp153739 				"kadm5_modify_principal",
8382881Smp153739 				prime_arg, client_name, ret.code);
8393998Ssemery 	 log_done("kadm5_modify_principal", prime_arg,
840*7934SMark.Phalan@Sun.COM 		  errmsg ? errmsg : "success",
841*7934SMark.Phalan@Sun.COM 		  client_name, service_name, client_addr(rqstp, buf));
842*7934SMark.Phalan@Sun.COM 
843*7934SMark.Phalan@Sun.COM 	  if (errmsg != NULL)
844*7934SMark.Phalan@Sun.COM 		krb5_free_error_message(handle ? handle->context : NULL, errmsg);
8452881Smp153739     }
8462881Smp153739 
8472881Smp153739 error:
8482881Smp153739     if (name)
8492881Smp153739     	gss_release_name(&min_stat, &name);
8502881Smp153739     free_server_handle(handle);
8512881Smp153739     if (prime_arg)
8522881Smp153739     	free(prime_arg);
8532881Smp153739     if (client_name)
8542881Smp153739     	free(client_name);
8552881Smp153739     if (service_name)
8562881Smp153739     	free(service_name);
8572881Smp153739     return &ret;
8582881Smp153739 }
8592881Smp153739 
8602881Smp153739 generic_ret *
861*7934SMark.Phalan@Sun.COM rename_principal_2_svc(rprinc_arg *arg, struct svc_req *rqstp)
8622881Smp153739 {
8632881Smp153739     static generic_ret		ret;
8642881Smp153739     char			*prime_arg1 = NULL, *prime_arg2 = NULL;
8652881Smp153739     char prime_arg[BUFSIZ];
8662881Smp153739     char *client_name = NULL, *service_name = NULL;
8672881Smp153739     OM_uint32 min_stat;
8682881Smp153739     kadm5_server_handle_t handle;
8692881Smp153739     restriction_t *rp;
870*7934SMark.Phalan@Sun.COM     const char                        *errmsg = NULL;
8712881Smp153739     gss_name_t name = NULL;
8724819Sps57422     size_t tlen1, tlen2, clen, slen;
8734819Sps57422     char *tdots1, *tdots2, *cdots, *sdots;
8742881Smp153739 
8752881Smp153739     xdr_free(xdr_generic_ret, (char *) &ret);
8762881Smp153739 
8772881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
8782881Smp153739 	 return &ret;
8792881Smp153739 
8802881Smp153739     if ((ret.code = check_handle((void *)handle)))
8812881Smp153739 	 goto error;
8822881Smp153739     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
8832881Smp153739 	 ret.code = KADM5_FAILURE;
8842881Smp153739 	 goto error;
8852881Smp153739     }
8862881Smp153739     if (krb5_unparse_name(handle->context, arg->src, &prime_arg1) ||
8872881Smp153739         krb5_unparse_name(handle->context, arg->dest, &prime_arg2)) {
8882881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
8892881Smp153739 	 goto error;
8902881Smp153739     }
8914819Sps57422     tlen1 = strlen(prime_arg1);
8924819Sps57422     trunc_name(&tlen1, &tdots1);
8934819Sps57422     tlen2 = strlen(prime_arg2);
8944819Sps57422     trunc_name(&tlen2, &tdots2);
8954819Sps57422     clen = strlen(client_name);
8964819Sps57422     trunc_name(&clen, &cdots);
8974819Sps57422     slen = strlen(service_name);
8984819Sps57422     trunc_name(&slen, &sdots);
8992881Smp153739 
9004819Sps57422     (void) snprintf(prime_arg, sizeof (prime_arg), "%.*s%s to %.*s*s",
9014819Sps57422 	tlen1, prime_arg1, tdots1,
9024819Sps57422 	tlen2, prime_arg2, tdots2);
9032881Smp153739     ret.code = KADM5_OK;
9042881Smp153739 
9050Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
9060Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
9070Sstevel@tonic-gate 		goto error;
9080Sstevel@tonic-gate 	}
9090Sstevel@tonic-gate 
9102881Smp153739     if (! CHANGEPW_SERVICE(rqstp)) {
9112881Smp153739 	 if (!kadm5int_acl_check(handle->context, name,
9122881Smp153739 			ACL_DELETE, arg->src, NULL))
9132881Smp153739 	      ret.code = KADM5_AUTH_DELETE;
9142881Smp153739 	 /* any restrictions at all on the ADD kills the RENAME */
9152881Smp153739 	 if (!kadm5int_acl_check(handle->context, name,
9162881Smp153739 			ACL_ADD, arg->dest, &rp)) {
9172881Smp153739 	      if (ret.code == KADM5_AUTH_DELETE)
9182881Smp153739 		   ret.code = KADM5_AUTH_INSUFFICIENT;
9192881Smp153739 	      else
9202881Smp153739 		   ret.code = KADM5_AUTH_ADD;
9212881Smp153739 	 }
9222881Smp153739     } else
9232881Smp153739 	 ret.code = KADM5_AUTH_INSUFFICIENT;
9242881Smp153739     if (ret.code != KADM5_OK) {
9252881Smp153739 
9262881Smp153739 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
9272881Smp153739 				    "kadm5_rename_principal",
9282881Smp153739 				    prime_arg, client_name);
9294819Sps57422 		krb5_klog_syslog(LOG_NOTICE,
9304819Sps57422 		    "Unauthorized request: kadm5_rename_principal, "
9314819Sps57422 		    "%.*s%s to %.*s%s, "
9324819Sps57422 		    "client=%.*s%s, service=%.*s%s, addr=%s",
9334819Sps57422 		    tlen1, prime_arg1, tdots1,
9344819Sps57422 		    tlen2, prime_arg2, tdots2,
9354819Sps57422 		    clen, client_name, cdots,
9364819Sps57422 		    slen, service_name, sdots,
9374819Sps57422 		    client_addr(rqstp, buf));
9382881Smp153739     } else {
9392881Smp153739 	 ret.code = kadm5_rename_principal((void *)handle, arg->src,
9402881Smp153739 						arg->dest);
941*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
942*7934SMark.Phalan@Sun.COM 	 if( ret.code != 0 )
943*7934SMark.Phalan@Sun.COM 	     errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
9442881Smp153739 
9452881Smp153739 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
9462881Smp153739 				"kadm5_rename_principal",
9472881Smp153739 				prime_arg, client_name, ret.code);
948*7934SMark.Phalan@Sun.COM 	 krb5_klog_syslog(LOG_NOTICE,
949*7934SMark.Phalan@Sun.COM 			  "Request: kadm5_rename_principal, "
950*7934SMark.Phalan@Sun.COM 			  "%.*s%s to %.*s%s, %s, "
951*7934SMark.Phalan@Sun.COM 			  "client=%.*s%s, service=%.*s%s, addr=%s",
952*7934SMark.Phalan@Sun.COM 			  tlen1, prime_arg1, tdots1,
953*7934SMark.Phalan@Sun.COM 			  tlen2, prime_arg2, tdots2,
954*7934SMark.Phalan@Sun.COM 			  errmsg ? errmsg : "success",
955*7934SMark.Phalan@Sun.COM 			  clen, client_name, cdots,
956*7934SMark.Phalan@Sun.COM 			  slen, service_name, sdots,
957*7934SMark.Phalan@Sun.COM 			  client_addr(rqstp, buf));
958*7934SMark.Phalan@Sun.COM 
959*7934SMark.Phalan@Sun.COM 	  if (errmsg != NULL)
960*7934SMark.Phalan@Sun.COM 		krb5_free_error_message(handle ? handle->context : NULL, errmsg);
9612881Smp153739     }
9622881Smp153739 
9632881Smp153739 error:
9642881Smp153739     if (name)
9652881Smp153739     	gss_release_name(&min_stat, &name);
9662881Smp153739     free_server_handle(handle);
9672881Smp153739     if (prime_arg1)
9682881Smp153739     	free(prime_arg1);
9692881Smp153739     if (prime_arg2)
9702881Smp153739     	free(prime_arg2);
9712881Smp153739     if (client_name)
9722881Smp153739     	free(client_name);
9732881Smp153739     if (service_name)
9742881Smp153739     	free(service_name);
9752881Smp153739     return &ret;
9762881Smp153739 }
9772881Smp153739 
9782881Smp153739 gprinc_ret *
979*7934SMark.Phalan@Sun.COM get_principal_2_svc(gprinc_arg *arg, struct svc_req *rqstp)
9802881Smp153739 {
9812881Smp153739     static gprinc_ret		    ret;
9822881Smp153739     kadm5_principal_ent_t_v1	    e;
9832881Smp153739     char			    *prime_arg = NULL, *funcname;
9842881Smp153739     char *client_name = NULL, *service_name = NULL;
9852881Smp153739     OM_uint32			    min_stat;
9862881Smp153739     kadm5_server_handle_t	    handle;
987*7934SMark.Phalan@Sun.COM     const char                            *errmsg = NULL;
9882881Smp153739     gss_name_t name = NULL;
9892881Smp153739 
9902881Smp153739     xdr_free(xdr_gprinc_ret, (char *) &ret);
9912881Smp153739 
9922881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
9932881Smp153739 	 return &ret;
9942881Smp153739 
9952881Smp153739     if ((ret.code = check_handle((void *)handle)))
9962881Smp153739 		goto error;
9972881Smp153739     ret.api_version = handle->api_version;
9982881Smp153739 
9992881Smp153739     funcname = handle->api_version == KADM5_API_VERSION_1 ?
10002881Smp153739 	 "kadm5_get_principal (V1)" : "kadm5_get_principal";
10012881Smp153739 
10022881Smp153739     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
10032881Smp153739 	 ret.code = KADM5_FAILURE;
10042881Smp153739 		goto error;
10052881Smp153739     }
10062881Smp153739     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
10072881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
10082881Smp153739 		goto error;
10092881Smp153739     }
10102881Smp153739 	if (!(name = get_clnt_name(rqstp))) {
10112881Smp153739 		ret.code = KADM5_FAILURE;
10122881Smp153739 		goto error;
10132881Smp153739 	}
10142881Smp153739 
10152881Smp153739     if (! cmp_gss_krb5_name(handle, name, arg->princ) &&
10162881Smp153739 	(CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
10172881Smp153739 					       name,
10182881Smp153739 					       ACL_INQUIRE,
10192881Smp153739 					       arg->princ,
10202881Smp153739 					       NULL))) {
10212881Smp153739 	 ret.code = KADM5_AUTH_GET;
10220Sstevel@tonic-gate 
10230Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
10242881Smp153739 				    funcname,
10250Sstevel@tonic-gate 				    prime_arg, client_name);
10263998Ssemery 	 log_unauth(funcname, prime_arg, client_name, service_name,
10272881Smp153739 		    client_addr(rqstp, buf));
10282881Smp153739     } else {
10292881Smp153739 	 if (handle->api_version == KADM5_API_VERSION_1) {
10302881Smp153739 	      ret.code  = kadm5_get_principal_v1((void *)handle,
10312881Smp153739 						 arg->princ, &e);
10322881Smp153739 	      if(ret.code == KADM5_OK) {
10332881Smp153739 		   memcpy(&ret.rec, e, sizeof(kadm5_principal_ent_rec_v1));
10342881Smp153739 		   free(e);
10352881Smp153739 	      }
10362881Smp153739 	 } else {
10372881Smp153739 	      ret.code  = kadm5_get_principal((void *)handle,
10382881Smp153739 					      arg->princ, &ret.rec,
10392881Smp153739 					      arg->mask);
10402881Smp153739 	 }
10412881Smp153739 
1042*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
1043*7934SMark.Phalan@Sun.COM 	 if( ret.code != 0 )
1044*7934SMark.Phalan@Sun.COM 	     errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
1045*7934SMark.Phalan@Sun.COM 
10462881Smp153739 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
10472881Smp153739 				funcname,
10482881Smp153739 				prime_arg, client_name, ret.code);
1049*7934SMark.Phalan@Sun.COM 	 log_done(funcname, prime_arg, errmsg ? errmsg : "success",
1050*7934SMark.Phalan@Sun.COM 		  client_name, service_name, client_addr(rqstp, buf));
1051*7934SMark.Phalan@Sun.COM 
1052*7934SMark.Phalan@Sun.COM 	  if (errmsg != NULL)
1053*7934SMark.Phalan@Sun.COM 		krb5_free_error_message(handle ? handle->context : NULL, errmsg);
10542881Smp153739     }
10552881Smp153739 
10562881Smp153739 error:
10572881Smp153739 	if (name)
10582881Smp153739     	gss_release_name(&min_stat, &name);
10592881Smp153739     free_server_handle(handle);
10602881Smp153739     if (prime_arg)
10612881Smp153739     	free(prime_arg);
10622881Smp153739     if (client_name)
10632881Smp153739     	free(client_name);
10642881Smp153739     if (service_name)
10652881Smp153739     	free(service_name);
10662881Smp153739     return &ret;
10672881Smp153739 }
10682881Smp153739 
10692881Smp153739 gprincs_ret *
1070*7934SMark.Phalan@Sun.COM get_princs_2_svc(gprincs_arg *arg, struct svc_req *rqstp)
10712881Smp153739 {
10722881Smp153739     static gprincs_ret		    ret;
10732881Smp153739     char			    *prime_arg = NULL;
10742881Smp153739     char *client_name = NULL, *service_name = NULL;
10752881Smp153739     OM_uint32			    min_stat;
10762881Smp153739     kadm5_server_handle_t handle;
10772881Smp153739     gss_name_t name = NULL;
1078*7934SMark.Phalan@Sun.COM     const char                            *errmsg = NULL;
10792881Smp153739 
10802881Smp153739     xdr_free(xdr_gprincs_ret, (char *) &ret);
10812881Smp153739 
10822881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
10832881Smp153739 	 return &ret;
10842881Smp153739 
10852881Smp153739     if ((ret.code = check_handle((void *)handle)))
10862881Smp153739 		goto error;
10872881Smp153739     ret.api_version = handle->api_version;
10882881Smp153739 
10892881Smp153739     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
10902881Smp153739 	 ret.code = KADM5_FAILURE;
10912881Smp153739 		goto error;
10922881Smp153739     }
10932881Smp153739     prime_arg = arg->exp;
10942881Smp153739     if (prime_arg == NULL)
10952881Smp153739 	 prime_arg = "*";
10962881Smp153739 
10972881Smp153739 	if (!(name = get_clnt_name(rqstp))) {
10982881Smp153739 		ret.code = KADM5_FAILURE;
10992881Smp153739 		goto error;
11002881Smp153739 	}
11012881Smp153739 
11022881Smp153739     if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
11032881Smp153739 					      name,
11042881Smp153739 					      ACL_LIST,
11052881Smp153739 					      NULL,
11062881Smp153739 					      NULL)) {
11072881Smp153739 	 ret.code = KADM5_AUTH_LIST;
11082881Smp153739 
11092881Smp153739 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
11102881Smp153739 				    "kadm5_get_principals",
11112881Smp153739 				    prime_arg, client_name);
11123998Ssemery 	 log_unauth("kadm5_get_principals", prime_arg, client_name,
11132881Smp153739 		    service_name, client_addr(rqstp, buf));
11142881Smp153739     } else {
11152881Smp153739 	 ret.code  = kadm5_get_principals((void *)handle,
11162881Smp153739 					       arg->exp, &ret.princs,
11172881Smp153739 					       &ret.count);
1118*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
1119*7934SMark.Phalan@Sun.COM 	 if( ret.code != 0 )
1120*7934SMark.Phalan@Sun.COM 	     errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
11210Sstevel@tonic-gate 
11220Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
11232881Smp153739 				"kadm5_get_principals",
11240Sstevel@tonic-gate 				prime_arg, client_name, ret.code);
1125*7934SMark.Phalan@Sun.COM 	 log_done("kadm5_get_principals", prime_arg,
1126*7934SMark.Phalan@Sun.COM 		  errmsg ? errmsg : "success",
1127*7934SMark.Phalan@Sun.COM 		  client_name, service_name, client_addr(rqstp, buf));
1128*7934SMark.Phalan@Sun.COM 
1129*7934SMark.Phalan@Sun.COM 	  if (errmsg != NULL)
1130*7934SMark.Phalan@Sun.COM 		krb5_free_error_message(handle ? handle->context : NULL, errmsg);
11310Sstevel@tonic-gate 	}
11320Sstevel@tonic-gate 
11330Sstevel@tonic-gate error:
11340Sstevel@tonic-gate 	if (name)
11350Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
11360Sstevel@tonic-gate 	free_server_handle(handle);
11370Sstevel@tonic-gate 	if (client_name)
11380Sstevel@tonic-gate 		free(client_name);
11390Sstevel@tonic-gate 	if (service_name)
11400Sstevel@tonic-gate 		free(service_name);
11410Sstevel@tonic-gate 	return (&ret);
11420Sstevel@tonic-gate }
11430Sstevel@tonic-gate 
11440Sstevel@tonic-gate generic_ret *
1145*7934SMark.Phalan@Sun.COM chpass_principal_2_svc(chpass_arg *arg, struct svc_req *rqstp)
11460Sstevel@tonic-gate {
11472881Smp153739     static generic_ret		    ret;
11482881Smp153739     char			    *prime_arg = NULL;
11492881Smp153739     char *client_name = NULL, *service_name = NULL;
11502881Smp153739     OM_uint32 min_stat;
11512881Smp153739     kadm5_server_handle_t	    handle;
1152*7934SMark.Phalan@Sun.COM     const char                            *errmsg = NULL;
11532881Smp153739     gss_name_t name = NULL;
11540Sstevel@tonic-gate 
11552881Smp153739     xdr_free(xdr_generic_ret, (char *) &ret);
11560Sstevel@tonic-gate 
11572881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
11582881Smp153739 	 return &ret;
11590Sstevel@tonic-gate 
11602881Smp153739     if ((ret.code = check_handle((void *)handle)))
11610Sstevel@tonic-gate 		goto error;
11622881Smp153739     ret.api_version = handle->api_version;
11632881Smp153739 
11642881Smp153739     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
11652881Smp153739 	 ret.code = KADM5_FAILURE;
11660Sstevel@tonic-gate 		goto error;
11672881Smp153739     }
11682881Smp153739     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
11692881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
11700Sstevel@tonic-gate 		goto error;
11710Sstevel@tonic-gate 	}
11720Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
11730Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
11740Sstevel@tonic-gate 		goto error;
11750Sstevel@tonic-gate 	}
11760Sstevel@tonic-gate 
11772881Smp153739     if (cmp_gss_krb5_name(handle, name, arg->princ)) {
11782881Smp153739 	 ret.code = chpass_principal_wrapper_3((void *)handle, arg->princ,
11792881Smp153739 					       FALSE, 0, NULL, arg->pass);
11802881Smp153739     } else if (!(CHANGEPW_SERVICE(rqstp)) &&
11812881Smp153739 	       kadm5int_acl_check(handle->context, name,
11822881Smp153739 			 ACL_CHANGEPW, arg->princ, NULL)) {
11832881Smp153739 	 ret.code = kadm5_chpass_principal((void *)handle, arg->princ,
11842881Smp153739 						arg->pass);
11852881Smp153739     } else {
11860Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
11872881Smp153739 				    "kadm5_chpass_principal",
11880Sstevel@tonic-gate 				    prime_arg, client_name);
11893998Ssemery 	 log_unauth("kadm5_chpass_principal", prime_arg, client_name,
11900Sstevel@tonic-gate 		    service_name, client_addr(rqstp, buf));
11912881Smp153739 	 ret.code = KADM5_AUTH_CHANGEPW;
11922881Smp153739     }
11930Sstevel@tonic-gate 
11942881Smp153739     if(ret.code != KADM5_AUTH_CHANGEPW) {
1195*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
1196*7934SMark.Phalan@Sun.COM 	 if( ret.code != 0 )
1197*7934SMark.Phalan@Sun.COM 	     errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
1198*7934SMark.Phalan@Sun.COM 
11990Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
12002881Smp153739 				"kadm5_chpass_principal",
12010Sstevel@tonic-gate 				prime_arg, client_name, ret.code);
12023998Ssemery 	log_done("kadm5_chpass_principal", prime_arg,
1203*7934SMark.Phalan@Sun.COM 		 errmsg ? errmsg : "success",
1204*7934SMark.Phalan@Sun.COM 		 client_name, service_name, client_addr(rqstp, buf));
1205*7934SMark.Phalan@Sun.COM 
1206*7934SMark.Phalan@Sun.COM 	  if (errmsg != NULL)
1207*7934SMark.Phalan@Sun.COM 		krb5_free_error_message(handle ? handle->context : NULL, errmsg);
12082881Smp153739     }
12090Sstevel@tonic-gate 
12100Sstevel@tonic-gate error:
12110Sstevel@tonic-gate 	if (name)
12120Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
12130Sstevel@tonic-gate 	free_server_handle(handle);
12140Sstevel@tonic-gate 	if (prime_arg)
12150Sstevel@tonic-gate 		free(prime_arg);
12160Sstevel@tonic-gate 	if (client_name)
12170Sstevel@tonic-gate 		free(client_name);
12180Sstevel@tonic-gate 	if (service_name)
12190Sstevel@tonic-gate 		free(service_name);
12200Sstevel@tonic-gate 	return (&ret);
12210Sstevel@tonic-gate }
12220Sstevel@tonic-gate 
12230Sstevel@tonic-gate generic_ret *
1224*7934SMark.Phalan@Sun.COM chpass_principal3_2_svc(chpass3_arg *arg, struct svc_req *rqstp)
12250Sstevel@tonic-gate {
12260Sstevel@tonic-gate     static generic_ret		    ret;
12270Sstevel@tonic-gate     char			    *prime_arg = NULL;
12280Sstevel@tonic-gate     char       			    *client_name = NULL,
12290Sstevel@tonic-gate 				    *service_name = NULL;
12300Sstevel@tonic-gate     OM_uint32			    min_stat;
12310Sstevel@tonic-gate     kadm5_server_handle_t	    handle;
1232*7934SMark.Phalan@Sun.COM     const char                            *errmsg = NULL;
12330Sstevel@tonic-gate     gss_name_t name = NULL;
12340Sstevel@tonic-gate 
12350Sstevel@tonic-gate     xdr_free(xdr_generic_ret, (char *) &ret);
12360Sstevel@tonic-gate 
12372881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
12380Sstevel@tonic-gate 	 return &ret;
12390Sstevel@tonic-gate 
12402881Smp153739     if ((ret.code = check_handle((void *)handle)))
12410Sstevel@tonic-gate 	goto error;
12420Sstevel@tonic-gate     ret.api_version = handle->api_version;
12430Sstevel@tonic-gate 
12440Sstevel@tonic-gate     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
12452881Smp153739 	 ret.code = KADM5_FAILURE;
12460Sstevel@tonic-gate 	goto error;
12470Sstevel@tonic-gate     }
12480Sstevel@tonic-gate     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
12492881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
12500Sstevel@tonic-gate 	goto error;
12510Sstevel@tonic-gate     }
12520Sstevel@tonic-gate     if (!(name = get_clnt_name(rqstp))) {
12530Sstevel@tonic-gate 	ret.code = KADM5_FAILURE;
12540Sstevel@tonic-gate 	goto error;
12550Sstevel@tonic-gate     }
12560Sstevel@tonic-gate 
12570Sstevel@tonic-gate     if (cmp_gss_krb5_name(handle, name, arg->princ)) {
12582881Smp153739 	 ret.code = chpass_principal_wrapper_3((void *)handle, arg->princ,
12592881Smp153739 					       arg->keepold,
12602881Smp153739 					       arg->n_ks_tuple,
12612881Smp153739 					       arg->ks_tuple,
12622881Smp153739 					       arg->pass);
12630Sstevel@tonic-gate     } else if (!(CHANGEPW_SERVICE(rqstp)) &&
12642881Smp153739 	       kadm5int_acl_check(handle->context, name,
12650Sstevel@tonic-gate 			 ACL_CHANGEPW, arg->princ, NULL)) {
12660Sstevel@tonic-gate 	 ret.code = kadm5_chpass_principal_3((void *)handle, arg->princ,
12670Sstevel@tonic-gate 					     arg->keepold,
12680Sstevel@tonic-gate 					     arg->n_ks_tuple,
12690Sstevel@tonic-gate 					     arg->ks_tuple,
12700Sstevel@tonic-gate 					     arg->pass);
12710Sstevel@tonic-gate     } else {
12723998Ssemery 	 log_unauth("kadm5_chpass_principal", prime_arg,
12733998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
12740Sstevel@tonic-gate 	 ret.code = KADM5_AUTH_CHANGEPW;
12750Sstevel@tonic-gate     }
12760Sstevel@tonic-gate 
12770Sstevel@tonic-gate     if(ret.code != KADM5_AUTH_CHANGEPW) {
1278*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
1279*7934SMark.Phalan@Sun.COM 	if( ret.code != 0 )
1280*7934SMark.Phalan@Sun.COM 	     errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
1281*7934SMark.Phalan@Sun.COM 
12823998Ssemery 	log_done("kadm5_chpass_principal", prime_arg,
1283*7934SMark.Phalan@Sun.COM 		errmsg ? errmsg : "success",
12843998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
1285*7934SMark.Phalan@Sun.COM 
1286*7934SMark.Phalan@Sun.COM 	  if (errmsg != NULL)
1287*7934SMark.Phalan@Sun.COM 		krb5_free_error_message(handle ? handle->context : NULL, errmsg);
12880Sstevel@tonic-gate     }
12890Sstevel@tonic-gate 
12900Sstevel@tonic-gate error:
12910Sstevel@tonic-gate     if (name)
12920Sstevel@tonic-gate     	gss_release_name(&min_stat, &name);
12930Sstevel@tonic-gate     free_server_handle(handle);
12940Sstevel@tonic-gate     if (client_name)
12952881Smp153739     	free(client_name);
12960Sstevel@tonic-gate     if (service_name)
12972881Smp153739     	free(service_name);
12980Sstevel@tonic-gate     if (prime_arg)
12992881Smp153739     	free(prime_arg);
13000Sstevel@tonic-gate     return (&ret);
13010Sstevel@tonic-gate }
13020Sstevel@tonic-gate 
13030Sstevel@tonic-gate #ifdef SUNWOFF
13040Sstevel@tonic-gate generic_ret *
1305*7934SMark.Phalan@Sun.COM setv4key_principal_2_svc(setv4key_arg *arg, struct svc_req *rqstp)
13060Sstevel@tonic-gate {
13070Sstevel@tonic-gate     static generic_ret		    ret;
13080Sstevel@tonic-gate     char			    *prime_arg = NULL;
13090Sstevel@tonic-gate     char 			    *client_name = NULL,
13100Sstevel@tonic-gate 				    *service_name = NULL;
13110Sstevel@tonic-gate     OM_uint32			    min_stat;
13120Sstevel@tonic-gate     kadm5_server_handle_t	    handle;
1313*7934SMark.Phalan@Sun.COM     const char                            *errmsg = NULL;
13140Sstevel@tonic-gate     gss_name_t name = NULL;
13150Sstevel@tonic-gate 
13160Sstevel@tonic-gate     xdr_free(xdr_generic_ret, (char *) &ret);
13170Sstevel@tonic-gate 
13182881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
13190Sstevel@tonic-gate 	 return &ret;
13200Sstevel@tonic-gate 
13212881Smp153739     if ((ret.code = check_handle((void *)handle)))
13220Sstevel@tonic-gate 	goto error;
13230Sstevel@tonic-gate     ret.api_version = handle->api_version;
13240Sstevel@tonic-gate 
13250Sstevel@tonic-gate     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
13262881Smp153739 	 ret.code = KADM5_FAILURE;
13270Sstevel@tonic-gate 	goto error;
13280Sstevel@tonic-gate     }
13290Sstevel@tonic-gate     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
13302881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
13310Sstevel@tonic-gate 	goto error;
13320Sstevel@tonic-gate     }
13330Sstevel@tonic-gate     if (!(name = get_clnt_name(rqstp))) {
13340Sstevel@tonic-gate 	ret.code = KADM5_FAILURE;
13350Sstevel@tonic-gate 	goto error;
13360Sstevel@tonic-gate     }
13370Sstevel@tonic-gate 
13380Sstevel@tonic-gate     if (!(CHANGEPW_SERVICE(rqstp)) &&
13392881Smp153739 	       kadm5int_acl_check(handle->context, name,
13402881Smp153739 			 ACL_SETKEY, arg->princ, NULL)) {
13410Sstevel@tonic-gate 	 ret.code = kadm5_setv4key_principal((void *)handle, arg->princ,
13420Sstevel@tonic-gate 					     arg->keyblock);
13430Sstevel@tonic-gate     } else {
13443998Ssemery 	 log_unauth("kadm5_setv4key_principal", prime_arg,
13453998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
13460Sstevel@tonic-gate 	 ret.code = KADM5_AUTH_SETKEY;
13470Sstevel@tonic-gate     }
13480Sstevel@tonic-gate 
13490Sstevel@tonic-gate     if(ret.code != KADM5_AUTH_SETKEY) {
1350*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
1351*7934SMark.Phalan@Sun.COM 	if( ret.code != 0 )
1352*7934SMark.Phalan@Sun.COM 	     errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
1353*7934SMark.Phalan@Sun.COM 
13543998Ssemery 	log_done("kadm5_setv4key_principal", prime_arg,
1355*7934SMark.Phalan@Sun.COM 		 errmsg ? errmsg : "success",
1356*7934SMark.Phalan@Sun.COM 		 client_name, service_name, client_addr(rqstp, buf));
1357*7934SMark.Phalan@Sun.COM 
1358*7934SMark.Phalan@Sun.COM 	  if (errmsg != NULL)
1359*7934SMark.Phalan@Sun.COM 		krb5_free_error_message(handle ? handle->context : NULL, errmsg);
13600Sstevel@tonic-gate     }
13610Sstevel@tonic-gate 
13620Sstevel@tonic-gate error:
13630Sstevel@tonic-gate     if (name)
13640Sstevel@tonic-gate 	gss_release_name(&min_stat, &name);
13650Sstevel@tonic-gate     free_server_handle(handle);
13660Sstevel@tonic-gate     if (client_name)
13670Sstevel@tonic-gate 	free(client_name);
13680Sstevel@tonic-gate     if (service_name)
13690Sstevel@tonic-gate 	free(service_name);
13700Sstevel@tonic-gate     if (prime_arg)
13710Sstevel@tonic-gate 	free(prime_arg);
13720Sstevel@tonic-gate     return (&ret);
13730Sstevel@tonic-gate }
13740Sstevel@tonic-gate #endif
13750Sstevel@tonic-gate 
13760Sstevel@tonic-gate generic_ret *
1377*7934SMark.Phalan@Sun.COM setkey_principal_2_svc(setkey_arg *arg, struct svc_req *rqstp)
13780Sstevel@tonic-gate {
13790Sstevel@tonic-gate     static generic_ret		    ret;
13800Sstevel@tonic-gate     char			    *prime_arg;
13810Sstevel@tonic-gate     char			    *client_name,
13820Sstevel@tonic-gate 				    *service_name;
13830Sstevel@tonic-gate     OM_uint32			    min_stat;
13840Sstevel@tonic-gate     kadm5_server_handle_t	    handle;
1385*7934SMark.Phalan@Sun.COM     const char                            *errmsg = NULL;
13860Sstevel@tonic-gate     gss_name_t name;
13870Sstevel@tonic-gate 
13880Sstevel@tonic-gate     xdr_free(xdr_generic_ret, (char *) &ret);
13890Sstevel@tonic-gate 
13902881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
13910Sstevel@tonic-gate 	 return &ret;
13920Sstevel@tonic-gate 
13932881Smp153739     if ((ret.code = check_handle((void *)handle)))
13940Sstevel@tonic-gate 	goto error;
13950Sstevel@tonic-gate     ret.api_version = handle->api_version;
13960Sstevel@tonic-gate 
13970Sstevel@tonic-gate     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
13982881Smp153739 	 ret.code = KADM5_FAILURE;
13990Sstevel@tonic-gate 	goto error;
14000Sstevel@tonic-gate     }
14010Sstevel@tonic-gate     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
14022881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
14030Sstevel@tonic-gate 	goto error;
14040Sstevel@tonic-gate     }
14050Sstevel@tonic-gate     if (!(name = get_clnt_name(rqstp))) {
14062881Smp153739 	 ret.code = KADM5_FAILURE;
14070Sstevel@tonic-gate 	goto error;
14080Sstevel@tonic-gate     }
14090Sstevel@tonic-gate 
14100Sstevel@tonic-gate     if (!(CHANGEPW_SERVICE(rqstp)) &&
14112881Smp153739 	       kadm5int_acl_check(handle->context, name, ACL_SETKEY, arg->princ, NULL)) {
14120Sstevel@tonic-gate 	 ret.code = kadm5_setkey_principal((void *)handle, arg->princ,
14130Sstevel@tonic-gate 					   arg->keyblocks, arg->n_keys);
14140Sstevel@tonic-gate     } else {
14153998Ssemery 	 log_unauth("kadm5_setkey_principal", prime_arg,
14163998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
14170Sstevel@tonic-gate 	 ret.code = KADM5_AUTH_SETKEY;
14180Sstevel@tonic-gate     }
14190Sstevel@tonic-gate 
14200Sstevel@tonic-gate     if(ret.code != KADM5_AUTH_SETKEY) {
1421*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
1422*7934SMark.Phalan@Sun.COM 	if( ret.code != 0 )
1423*7934SMark.Phalan@Sun.COM 	    errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
1424*7934SMark.Phalan@Sun.COM 
14253998Ssemery 	log_done("kadm5_setkey_principal", prime_arg,
1426*7934SMark.Phalan@Sun.COM 		 errmsg ? errmsg : "success",
1427*7934SMark.Phalan@Sun.COM 		 client_name, service_name, client_addr(rqstp, buf));
1428*7934SMark.Phalan@Sun.COM 
1429*7934SMark.Phalan@Sun.COM 	  if (errmsg != NULL)
1430*7934SMark.Phalan@Sun.COM 		krb5_free_error_message(handle ? handle->context : NULL, errmsg);
14310Sstevel@tonic-gate     }
14320Sstevel@tonic-gate 
14330Sstevel@tonic-gate error:
14340Sstevel@tonic-gate     if (name)
14350Sstevel@tonic-gate 	gss_release_name(&min_stat, &name);
14360Sstevel@tonic-gate     free_server_handle(handle);
14370Sstevel@tonic-gate     if (client_name)
14382881Smp153739     	free(client_name);
14390Sstevel@tonic-gate     if (service_name)
14402881Smp153739     	free(service_name);
14410Sstevel@tonic-gate     if (prime_arg)
14422881Smp153739     	free(prime_arg);
14430Sstevel@tonic-gate     return (&ret);
14440Sstevel@tonic-gate }
14450Sstevel@tonic-gate 
14460Sstevel@tonic-gate generic_ret *
1447*7934SMark.Phalan@Sun.COM setkey_principal3_2_svc(setkey3_arg *arg, struct svc_req *rqstp)
14480Sstevel@tonic-gate {
14490Sstevel@tonic-gate     static generic_ret		    ret;
14500Sstevel@tonic-gate     char			    *prime_arg = NULL;
14510Sstevel@tonic-gate     char			    *client_name = NULL,
14520Sstevel@tonic-gate 				    *service_name = NULL;
14530Sstevel@tonic-gate     OM_uint32			    min_stat;
14540Sstevel@tonic-gate     kadm5_server_handle_t	    handle;
1455*7934SMark.Phalan@Sun.COM     const char                            *errmsg = NULL;
14560Sstevel@tonic-gate     gss_name_t name = NULL;
14570Sstevel@tonic-gate 
14580Sstevel@tonic-gate     xdr_free(xdr_generic_ret, (char *) &ret);
14590Sstevel@tonic-gate 
14602881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
14610Sstevel@tonic-gate 	 return &ret;
14620Sstevel@tonic-gate 
14632881Smp153739     if ((ret.code = check_handle((void *)handle)))
14640Sstevel@tonic-gate 	goto error;
14650Sstevel@tonic-gate     ret.api_version = handle->api_version;
14660Sstevel@tonic-gate 
14670Sstevel@tonic-gate     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
14682881Smp153739 	 ret.code = KADM5_FAILURE;
14690Sstevel@tonic-gate 	goto error;
14700Sstevel@tonic-gate     }
14710Sstevel@tonic-gate     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
14722881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
14730Sstevel@tonic-gate 	goto error;
14740Sstevel@tonic-gate     }
14750Sstevel@tonic-gate     if (!(name = get_clnt_name(rqstp))) {
14762881Smp153739 	 ret.code = KADM5_FAILURE;
14770Sstevel@tonic-gate 	goto error;
14780Sstevel@tonic-gate     }
14790Sstevel@tonic-gate 
14800Sstevel@tonic-gate     if (!(CHANGEPW_SERVICE(rqstp)) &&
14812881Smp153739 	       kadm5int_acl_check(handle->context, name,
14822881Smp153739 			 ACL_SETKEY, arg->princ, NULL)) {
14830Sstevel@tonic-gate 	 ret.code = kadm5_setkey_principal_3((void *)handle, arg->princ,
14840Sstevel@tonic-gate 					     arg->keepold,
14850Sstevel@tonic-gate 					     arg->n_ks_tuple,
14860Sstevel@tonic-gate 					     arg->ks_tuple,
14870Sstevel@tonic-gate 					     arg->keyblocks, arg->n_keys);
14880Sstevel@tonic-gate     } else {
14893998Ssemery 	 log_unauth("kadm5_setkey_principal", prime_arg,
14903998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
14910Sstevel@tonic-gate 	 ret.code = KADM5_AUTH_SETKEY;
14920Sstevel@tonic-gate     }
14930Sstevel@tonic-gate 
14940Sstevel@tonic-gate     if(ret.code != KADM5_AUTH_SETKEY) {
1495*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
1496*7934SMark.Phalan@Sun.COM 	if( ret.code != 0 )
1497*7934SMark.Phalan@Sun.COM 	    errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
1498*7934SMark.Phalan@Sun.COM 
14993998Ssemery 	log_done("kadm5_setkey_principal", prime_arg,
1500*7934SMark.Phalan@Sun.COM 		 errmsg ? errmsg : "success",
1501*7934SMark.Phalan@Sun.COM 		 client_name, service_name, client_addr(rqstp, buf));
1502*7934SMark.Phalan@Sun.COM 
1503*7934SMark.Phalan@Sun.COM 	  if (errmsg != NULL)
1504*7934SMark.Phalan@Sun.COM 		krb5_free_error_message(handle ? handle->context : NULL, errmsg);
15050Sstevel@tonic-gate     }
15060Sstevel@tonic-gate 
15070Sstevel@tonic-gate error:
15080Sstevel@tonic-gate     if (name)
15090Sstevel@tonic-gate 	gss_release_name(&min_stat, &name);
15100Sstevel@tonic-gate     free_server_handle(handle);
15110Sstevel@tonic-gate     if (client_name)
15120Sstevel@tonic-gate 	free(client_name);
15130Sstevel@tonic-gate     if (service_name)
15142881Smp153739     	free(service_name);
15150Sstevel@tonic-gate     if (prime_arg)
15162881Smp153739     	free(prime_arg);
15172881Smp153739     return &ret;
15180Sstevel@tonic-gate }
15190Sstevel@tonic-gate 
15200Sstevel@tonic-gate chrand_ret *
1521*7934SMark.Phalan@Sun.COM chrand_principal_2_svc(chrand_arg *arg, struct svc_req *rqstp)
15220Sstevel@tonic-gate {
15232881Smp153739     static chrand_ret		ret;
15242881Smp153739     krb5_keyblock		*k;
15252881Smp153739     int				nkeys;
15262881Smp153739     char			*prime_arg = NULL, *funcname;
15272881Smp153739     char *client_name = NULL, *service_name = NULL;
15282881Smp153739     OM_uint32			min_stat;
15292881Smp153739     kadm5_server_handle_t	handle;
1530*7934SMark.Phalan@Sun.COM     const char                        *errmsg = NULL;
15312881Smp153739     gss_name_t name = NULL;
15320Sstevel@tonic-gate 
15332881Smp153739     xdr_free(xdr_chrand_ret, (char *) &ret);
15340Sstevel@tonic-gate 
15352881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
15362881Smp153739 	 return &ret;
15370Sstevel@tonic-gate 
15382881Smp153739     if ((ret.code = check_handle((void *)handle)))
15390Sstevel@tonic-gate 		goto error;
15402881Smp153739 
15412881Smp153739     ret.api_version = handle->api_version;
15420Sstevel@tonic-gate 
15432881Smp153739     funcname = handle->api_version == KADM5_API_VERSION_1 ?
15442881Smp153739 	 "kadm5_randkey_principal (V1)" : "kadm5_randkey_principal";
15450Sstevel@tonic-gate 
15462881Smp153739     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
15472881Smp153739 	 ret.code = KADM5_FAILURE;
15480Sstevel@tonic-gate 		goto error;
15492881Smp153739     }
15502881Smp153739     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
15512881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
15520Sstevel@tonic-gate 		goto error;
15532881Smp153739     }
15540Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
15550Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
15560Sstevel@tonic-gate 		goto error;
15570Sstevel@tonic-gate 	}
15580Sstevel@tonic-gate 
15592881Smp153739     if (cmp_gss_krb5_name(handle, name, arg->princ)) {
15603641Ssemery 	 ret.code = randkey_principal_wrapper((void *)handle, arg->princ, &k,
15613641Ssemery 						&nkeys);
15622881Smp153739     } else if (!(CHANGEPW_SERVICE(rqstp)) &&
15632881Smp153739 	       kadm5int_acl_check(handle->context, name,
15642881Smp153739 			 ACL_CHANGEPW, arg->princ, NULL)) {
15652881Smp153739 	 ret.code = kadm5_randkey_principal((void *)handle, arg->princ,
15662881Smp153739 					    &k, &nkeys);
15672881Smp153739     } else {
15680Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
15690Sstevel@tonic-gate 				    funcname, prime_arg, client_name);
15703998Ssemery 	 log_unauth(funcname, prime_arg,
15713998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
15722881Smp153739 	 ret.code = KADM5_AUTH_CHANGEPW;
15732881Smp153739     }
15740Sstevel@tonic-gate 
15752881Smp153739     if(ret.code == KADM5_OK) {
15762881Smp153739 	 if (handle->api_version == KADM5_API_VERSION_1) {
15772881Smp153739 	      krb5_copy_keyblock_contents(handle->context, k, &ret.key);
15782881Smp153739 	      krb5_free_keyblock(handle->context, k);
15792881Smp153739 	 } else {
15802881Smp153739 	      ret.keys = k;
15812881Smp153739 	      ret.n_keys = nkeys;
15822881Smp153739 	 }
15832881Smp153739     }
15842881Smp153739 
15852881Smp153739     if(ret.code != KADM5_AUTH_CHANGEPW) {
1586*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
1587*7934SMark.Phalan@Sun.COM 	if( ret.code != 0 )
1588*7934SMark.Phalan@Sun.COM 	    errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
1589*7934SMark.Phalan@Sun.COM 
15900Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
15910Sstevel@tonic-gate 				funcname, prime_arg, client_name, ret.code);
1592*7934SMark.Phalan@Sun.COM 	log_done(funcname, prime_arg, errmsg ? errmsg : "success",
1593*7934SMark.Phalan@Sun.COM 		 client_name, service_name, client_addr(rqstp, buf));
1594*7934SMark.Phalan@Sun.COM 
1595*7934SMark.Phalan@Sun.COM 	  if (errmsg != NULL)
1596*7934SMark.Phalan@Sun.COM 		krb5_free_error_message(handle ? handle->context : NULL, errmsg);
1597*7934SMark.Phalan@Sun.COM     }
15980Sstevel@tonic-gate 
15990Sstevel@tonic-gate error:
16000Sstevel@tonic-gate 	if (name)
16010Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
16020Sstevel@tonic-gate 	free_server_handle(handle);
16030Sstevel@tonic-gate 	if (prime_arg)
16042881Smp153739     	free(prime_arg);
16052881Smp153739     if (client_name)
16062881Smp153739     	free(client_name);
16072881Smp153739     if (service_name)
16082881Smp153739     	free(service_name);
16092881Smp153739     return &ret;
16100Sstevel@tonic-gate }
16110Sstevel@tonic-gate 
16120Sstevel@tonic-gate chrand_ret *
1613*7934SMark.Phalan@Sun.COM chrand_principal3_2_svc(chrand3_arg *arg, struct svc_req *rqstp)
16140Sstevel@tonic-gate {
16150Sstevel@tonic-gate     static chrand_ret		ret;
16160Sstevel@tonic-gate     krb5_keyblock		*k;
16170Sstevel@tonic-gate     int				nkeys;
16180Sstevel@tonic-gate     char			*prime_arg = NULL, *funcname;
16190Sstevel@tonic-gate     char			*client_name = NULL,
16200Sstevel@tonic-gate 	    			*service_name = NULL;
16210Sstevel@tonic-gate     OM_uint32			min_stat;
16220Sstevel@tonic-gate     kadm5_server_handle_t	handle;
1623*7934SMark.Phalan@Sun.COM     const char                        *errmsg = NULL;
16240Sstevel@tonic-gate     gss_name_t name = NULL;
16250Sstevel@tonic-gate 
16260Sstevel@tonic-gate     xdr_free(xdr_chrand_ret, (char *) &ret);
16270Sstevel@tonic-gate 
16282881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
16290Sstevel@tonic-gate 	 return &ret;
16300Sstevel@tonic-gate 
16312881Smp153739     if ((ret.code = check_handle((void *)handle)))
16320Sstevel@tonic-gate 	goto error;
16330Sstevel@tonic-gate     ret.api_version = handle->api_version;
16340Sstevel@tonic-gate 
16350Sstevel@tonic-gate     funcname = handle->api_version == KADM5_API_VERSION_1 ?
16360Sstevel@tonic-gate 	 "kadm5_randkey_principal (V1)" : "kadm5_randkey_principal";
16370Sstevel@tonic-gate 
16380Sstevel@tonic-gate     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
16390Sstevel@tonic-gate 	ret.code = KADM5_FAILURE;
16400Sstevel@tonic-gate 	goto error;
16410Sstevel@tonic-gate     }
16420Sstevel@tonic-gate     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
16432881Smp153739 	 ret.code = KADM5_BAD_PRINCIPAL;
16440Sstevel@tonic-gate 	goto error;
16450Sstevel@tonic-gate     }
16460Sstevel@tonic-gate     if (!(name = get_clnt_name(rqstp))) {
16470Sstevel@tonic-gate 	ret.code = KADM5_FAILURE;
16480Sstevel@tonic-gate 	goto error;
16490Sstevel@tonic-gate     }
16500Sstevel@tonic-gate 
16510Sstevel@tonic-gate     if (cmp_gss_krb5_name(handle, name, arg->princ)) {
16522881Smp153739 	 ret.code = randkey_principal_wrapper_3((void *)handle, arg->princ,
16532881Smp153739 						arg->keepold,
16542881Smp153739 						arg->n_ks_tuple,
16552881Smp153739 						arg->ks_tuple,
16562881Smp153739 						&k, &nkeys);
16570Sstevel@tonic-gate     } else if (!(CHANGEPW_SERVICE(rqstp)) &&
16582881Smp153739 	       kadm5int_acl_check(handle->context, name,
16590Sstevel@tonic-gate 			 ACL_CHANGEPW, arg->princ, NULL)) {
16600Sstevel@tonic-gate 	 ret.code = kadm5_randkey_principal_3((void *)handle, arg->princ,
16610Sstevel@tonic-gate 					      arg->keepold,
16620Sstevel@tonic-gate 					      arg->n_ks_tuple,
16630Sstevel@tonic-gate 					      arg->ks_tuple,
16640Sstevel@tonic-gate 					      &k, &nkeys);
16650Sstevel@tonic-gate     } else {
16663998Ssemery 	 log_unauth(funcname, prime_arg,
16673998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
16680Sstevel@tonic-gate 	 ret.code = KADM5_AUTH_CHANGEPW;
16690Sstevel@tonic-gate     }
16700Sstevel@tonic-gate 
16710Sstevel@tonic-gate     if(ret.code == KADM5_OK) {
16720Sstevel@tonic-gate 	 if (handle->api_version == KADM5_API_VERSION_1) {
16730Sstevel@tonic-gate 	      krb5_copy_keyblock_contents(handle->context, k, &ret.key);
16740Sstevel@tonic-gate 	      krb5_free_keyblock(handle->context, k);
16750Sstevel@tonic-gate 	 } else {
16760Sstevel@tonic-gate 	      ret.keys = k;
16770Sstevel@tonic-gate 	      ret.n_keys = nkeys;
16780Sstevel@tonic-gate 	 }
16790Sstevel@tonic-gate     }
16800Sstevel@tonic-gate 
16810Sstevel@tonic-gate     if(ret.code != KADM5_AUTH_CHANGEPW) {
1682*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
1683*7934SMark.Phalan@Sun.COM 	if( ret.code != 0 )
1684*7934SMark.Phalan@Sun.COM 	    errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
1685*7934SMark.Phalan@Sun.COM 
1686*7934SMark.Phalan@Sun.COM 	log_done(funcname, prime_arg, errmsg ? errmsg : "success",
1687*7934SMark.Phalan@Sun.COM 		 client_name, service_name, client_addr(rqstp, buf));
1688*7934SMark.Phalan@Sun.COM 
1689*7934SMark.Phalan@Sun.COM 	if (errmsg != NULL)
1690*7934SMark.Phalan@Sun.COM 		krb5_free_error_message(handle ? handle->context : NULL, errmsg);
16910Sstevel@tonic-gate     }
16920Sstevel@tonic-gate 
16930Sstevel@tonic-gate error:
16940Sstevel@tonic-gate     if (name)
16950Sstevel@tonic-gate 	gss_release_name(&min_stat, &name);
16960Sstevel@tonic-gate     free_server_handle(handle);
16970Sstevel@tonic-gate     if (client_name)
16980Sstevel@tonic-gate 	free(client_name);
16990Sstevel@tonic-gate     if (service_name)
17000Sstevel@tonic-gate 	free(service_name);
17010Sstevel@tonic-gate     if (prime_arg)
17020Sstevel@tonic-gate 	free(prime_arg);
17030Sstevel@tonic-gate     return (&ret);
17040Sstevel@tonic-gate }
17050Sstevel@tonic-gate 
17060Sstevel@tonic-gate generic_ret *
1707*7934SMark.Phalan@Sun.COM create_policy_2_svc(cpol_arg *arg, struct svc_req *rqstp)
17080Sstevel@tonic-gate {
17092881Smp153739     static generic_ret		    ret;
17102881Smp153739     char			    *prime_arg = NULL;
17112881Smp153739     char *client_name = NULL, *service_name = NULL;
17122881Smp153739     OM_uint32			    min_stat;
17132881Smp153739     kadm5_server_handle_t	    handle;
1714*7934SMark.Phalan@Sun.COM     const char                            *errmsg = NULL;
17152881Smp153739     gss_name_t name = NULL;
17160Sstevel@tonic-gate 
17172881Smp153739     xdr_free(xdr_generic_ret, (char *) &ret);
17180Sstevel@tonic-gate 
17192881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
17202881Smp153739 	 return &ret;
17210Sstevel@tonic-gate 
17222881Smp153739     if ((ret.code = check_handle((void *)handle)))
17230Sstevel@tonic-gate 		goto error;
17242881Smp153739 
17252881Smp153739     ret.api_version = handle->api_version;
17260Sstevel@tonic-gate 
17272881Smp153739     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
17282881Smp153739 	 ret.code = KADM5_FAILURE;
17290Sstevel@tonic-gate 		goto error;
17302881Smp153739     }
17312881Smp153739     prime_arg = arg->rec.policy;
17320Sstevel@tonic-gate 
17330Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
17340Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
17350Sstevel@tonic-gate 		goto error;
17360Sstevel@tonic-gate 	}
17370Sstevel@tonic-gate 
17382881Smp153739     if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
17392881Smp153739 					      name,
17402881Smp153739 					      ACL_ADD, NULL, NULL)) {
17412881Smp153739 	 ret.code = KADM5_AUTH_ADD;
17420Sstevel@tonic-gate 
17430Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
17440Sstevel@tonic-gate 				    "kadm5_create_policy",
17450Sstevel@tonic-gate 				    prime_arg, client_name);
17463998Ssemery 	 log_unauth("kadm5_create_policy", prime_arg,
1747*7934SMark.Phalan@Sun.COM 		 client_name, service_name, client_addr(rqstp, buf));
1748*7934SMark.Phalan@Sun.COM 
17492881Smp153739     } else {
17502881Smp153739 	 ret.code = kadm5_create_policy((void *)handle, &arg->rec,
17512881Smp153739 					     arg->mask);
1752*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
1753*7934SMark.Phalan@Sun.COM 	 if( ret.code != 0 )
1754*7934SMark.Phalan@Sun.COM 	     errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
17550Sstevel@tonic-gate 
17560Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
17570Sstevel@tonic-gate 				"kadm5_create_policy",
17580Sstevel@tonic-gate 				prime_arg, client_name, ret.code);
17593998Ssemery 	 log_done("kadm5_create_policy",
1760*7934SMark.Phalan@Sun.COM 		  ((prime_arg == NULL) ? "(null)" : prime_arg),
1761*7934SMark.Phalan@Sun.COM 		  errmsg ? errmsg : "success",
1762*7934SMark.Phalan@Sun.COM 		  client_name, service_name, client_addr(rqstp, buf));
1763*7934SMark.Phalan@Sun.COM 
1764*7934SMark.Phalan@Sun.COM 	  if (errmsg != NULL)
1765*7934SMark.Phalan@Sun.COM 		krb5_free_error_message(handle ? handle->context : NULL, errmsg);
17662881Smp153739     }
17670Sstevel@tonic-gate 
17680Sstevel@tonic-gate error:
17690Sstevel@tonic-gate 	if (name)
17700Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
17712881Smp153739     free_server_handle(handle);
17722881Smp153739     if (client_name)
17732881Smp153739     	free(client_name);
17742881Smp153739     if (service_name)
17752881Smp153739     	free(service_name);
17762881Smp153739     return &ret;
17770Sstevel@tonic-gate }
17780Sstevel@tonic-gate 
17790Sstevel@tonic-gate generic_ret *
1780*7934SMark.Phalan@Sun.COM delete_policy_2_svc(dpol_arg *arg, struct svc_req *rqstp)
17810Sstevel@tonic-gate {
17822881Smp153739     static generic_ret		    ret;
17832881Smp153739     char			    *prime_arg = NULL;
17842881Smp153739     char *client_name = NULL, *service_name = NULL;
17852881Smp153739     OM_uint32			    min_stat;
17862881Smp153739     kadm5_server_handle_t	    handle;
1787*7934SMark.Phalan@Sun.COM     const char                            *errmsg = NULL;
17882881Smp153739     gss_name_t name = NULL;
17890Sstevel@tonic-gate 
17902881Smp153739     xdr_free(xdr_generic_ret, (char *) &ret);
17910Sstevel@tonic-gate 
17922881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
17932881Smp153739 	 return &ret;
17940Sstevel@tonic-gate 
17952881Smp153739     if ((ret.code = check_handle((void *)handle)))
17960Sstevel@tonic-gate 		goto error;
17972881Smp153739     ret.api_version = handle->api_version;
17980Sstevel@tonic-gate 
17992881Smp153739     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
18002881Smp153739 	 ret.code = KADM5_FAILURE;
18010Sstevel@tonic-gate 		goto error;
18022881Smp153739     }
18032881Smp153739     prime_arg = arg->name;
18042881Smp153739 
18050Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
18060Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
18070Sstevel@tonic-gate 		goto error;
18080Sstevel@tonic-gate 	}
18090Sstevel@tonic-gate 
18102881Smp153739     if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
18110Sstevel@tonic-gate 						name,
18122881Smp153739 					      ACL_DELETE, NULL, NULL)) {
18130Sstevel@tonic-gate 
18140Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
18150Sstevel@tonic-gate 				    "kadm5_delete_policy",
18160Sstevel@tonic-gate 				    prime_arg, client_name);
18173998Ssemery 	 log_unauth("kadm5_delete_policy", prime_arg,
18183998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
18192881Smp153739 	 ret.code = KADM5_AUTH_DELETE;
18202881Smp153739     } else {
18212881Smp153739 	 ret.code = kadm5_delete_policy((void *)handle, arg->name);
1822*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
1823*7934SMark.Phalan@Sun.COM 	 if( ret.code != 0 )
1824*7934SMark.Phalan@Sun.COM 	     errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
18250Sstevel@tonic-gate 
18260Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
18270Sstevel@tonic-gate 				"kadm5_delete_policy",
18280Sstevel@tonic-gate 				prime_arg, client_name, ret.code);
18293998Ssemery 	 log_done("kadm5_delete_policy",
1830*7934SMark.Phalan@Sun.COM 		  ((prime_arg == NULL) ? "(null)" : prime_arg),
1831*7934SMark.Phalan@Sun.COM 		 errmsg ? errmsg : "success",
1832*7934SMark.Phalan@Sun.COM 		  client_name, service_name, client_addr(rqstp, buf));
1833*7934SMark.Phalan@Sun.COM 
1834*7934SMark.Phalan@Sun.COM 	 if (errmsg != NULL)
1835*7934SMark.Phalan@Sun.COM 		krb5_free_error_message(handle ? handle->context : NULL, errmsg);
18362881Smp153739     }
18372881Smp153739 
18382881Smp153739 error:
18392881Smp153739 	if (name)
18402881Smp153739 		gss_release_name(&min_stat, &name);
18412881Smp153739     free_server_handle(handle);
18422881Smp153739     if (client_name)
18432881Smp153739     free(client_name);
18442881Smp153739     if (service_name)
18452881Smp153739     free(service_name);
18462881Smp153739     return &ret;
18472881Smp153739 }
18482881Smp153739 
18492881Smp153739 generic_ret *
1850*7934SMark.Phalan@Sun.COM modify_policy_2_svc(mpol_arg *arg, struct svc_req *rqstp)
18512881Smp153739 {
18522881Smp153739     static generic_ret		    ret;
18532881Smp153739     char			    *prime_arg = NULL;
18542881Smp153739     char *client_name = NULL, *service_name = NULL;
18552881Smp153739     OM_uint32 min_stat;
18562881Smp153739     kadm5_server_handle_t	    handle;
1857*7934SMark.Phalan@Sun.COM     const char                            *errmsg = NULL;
18582881Smp153739     gss_name_t name = NULL;
18592881Smp153739 
18602881Smp153739     xdr_free(xdr_generic_ret, (char *) &ret);
18612881Smp153739 
18622881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
18632881Smp153739 	 return &ret;
18642881Smp153739 
18652881Smp153739     if ((ret.code = check_handle((void *)handle)))
18662881Smp153739 		goto error;
18672881Smp153739     ret.api_version = handle->api_version;
18682881Smp153739 
18692881Smp153739     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
18702881Smp153739 	 ret.code = KADM5_FAILURE;
18712881Smp153739 		goto error;
18722881Smp153739     }
18732881Smp153739     prime_arg = arg->rec.policy;
18742881Smp153739 
18752881Smp153739     if (!(name = get_clnt_name(rqstp))) {
18762881Smp153739 	 ret.code = KADM5_FAILURE;
18772881Smp153739 		goto error;
18782881Smp153739     }
18792881Smp153739 
18802881Smp153739     if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
18812881Smp153739 						name,
18822881Smp153739 					      ACL_MODIFY, NULL, NULL)) {
18832881Smp153739 
18842881Smp153739 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
18852881Smp153739 				    "kadm5_modify_policy",
18862881Smp153739 				    prime_arg, client_name);
18873998Ssemery 	 log_unauth("kadm5_modify_policy", prime_arg,
18883998Ssemery 		client_name, service_name, client_addr(rqstp, buf));
18892881Smp153739 	 ret.code = KADM5_AUTH_MODIFY;
18902881Smp153739     } else {
18912881Smp153739 	 ret.code = kadm5_modify_policy((void *)handle, &arg->rec,
18922881Smp153739 					     arg->mask);
1893*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
1894*7934SMark.Phalan@Sun.COM 	 if( ret.code != 0 )
1895*7934SMark.Phalan@Sun.COM 	     errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
18962881Smp153739 
18972881Smp153739 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
18982881Smp153739 				"kadm5_modify_policy",
18992881Smp153739 				prime_arg, client_name, ret.code);
19003998Ssemery 	 log_done("kadm5_modify_policy",
1901*7934SMark.Phalan@Sun.COM 		  ((prime_arg == NULL) ? "(null)" : prime_arg),
1902*7934SMark.Phalan@Sun.COM 		  errmsg ? errmsg : "success",
1903*7934SMark.Phalan@Sun.COM 		  client_name, service_name, client_addr(rqstp, buf));
1904*7934SMark.Phalan@Sun.COM 
1905*7934SMark.Phalan@Sun.COM 	  if (errmsg != NULL)
1906*7934SMark.Phalan@Sun.COM 		krb5_free_error_message(handle ? handle->context : NULL, errmsg);
1907*7934SMark.Phalan@Sun.COM     }
19080Sstevel@tonic-gate 
19090Sstevel@tonic-gate error:
19100Sstevel@tonic-gate 	if (name)
19110Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
19120Sstevel@tonic-gate 	free_server_handle(handle);
19130Sstevel@tonic-gate 	if (client_name)
19140Sstevel@tonic-gate 		free(client_name);
19150Sstevel@tonic-gate 	if (service_name)
19160Sstevel@tonic-gate 		free(service_name);
19170Sstevel@tonic-gate 	return (&ret);
19180Sstevel@tonic-gate }
19190Sstevel@tonic-gate 
19202881Smp153739 gpol_ret *
1921*7934SMark.Phalan@Sun.COM get_policy_2_svc(gpol_arg *arg, struct svc_req *rqstp)
19220Sstevel@tonic-gate {
19232881Smp153739     static gpol_ret		ret;
19242881Smp153739     kadm5_ret_t		ret2;
19252881Smp153739     char *prime_arg = NULL, *funcname;
19262881Smp153739     char *client_name = NULL, *service_name = NULL;
19272881Smp153739     OM_uint32 min_stat;
19282881Smp153739     kadm5_policy_ent_t	e;
19292881Smp153739     kadm5_principal_ent_rec	caller_ent;
19302881Smp153739     krb5_principal caller;
19312881Smp153739     kadm5_server_handle_t	handle;
1932*7934SMark.Phalan@Sun.COM     const char                        *errmsg = NULL;
19332881Smp153739   gss_name_t name = NULL;
19340Sstevel@tonic-gate 
19352881Smp153739     xdr_free(xdr_gpol_ret, (char *) &ret);
19360Sstevel@tonic-gate 
19372881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
19382881Smp153739 	 return &ret;
19390Sstevel@tonic-gate 
19402881Smp153739     if ((ret.code = check_handle((void *) handle)))
19412881Smp153739 		goto error;
19422881Smp153739 
19432881Smp153739     ret.api_version = handle->api_version;
19440Sstevel@tonic-gate 
19452881Smp153739     funcname = handle->api_version == KADM5_API_VERSION_1 ?
19462881Smp153739 	 "kadm5_get_policy (V1)" : "kadm5_get_policy";
19470Sstevel@tonic-gate 
19482881Smp153739     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
19492881Smp153739 	 ret.code = KADM5_FAILURE;
19500Sstevel@tonic-gate 		goto error;
19512881Smp153739     }
19522881Smp153739     prime_arg = arg->name;
19530Sstevel@tonic-gate 	ret.code = KADM5_AUTH_GET;
19540Sstevel@tonic-gate 
19550Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
19560Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
19570Sstevel@tonic-gate 		goto error;
19580Sstevel@tonic-gate 	}
19590Sstevel@tonic-gate 
19602881Smp153739     if (!CHANGEPW_SERVICE(rqstp) && kadm5int_acl_check(handle->context,
19610Sstevel@tonic-gate 						name,
19620Sstevel@tonic-gate 						ACL_INQUIRE, NULL, NULL))
19630Sstevel@tonic-gate 		ret.code = KADM5_OK;
19640Sstevel@tonic-gate 	else {
19650Sstevel@tonic-gate 		ret.code = kadm5_get_principal(handle->lhandle,
19660Sstevel@tonic-gate 		    handle->current_caller,
19670Sstevel@tonic-gate 		    &caller_ent,
19680Sstevel@tonic-gate 		    KADM5_PRINCIPAL_NORMAL_MASK);
19690Sstevel@tonic-gate 		if (ret.code == KADM5_OK) {
19700Sstevel@tonic-gate 			if (caller_ent.aux_attributes & KADM5_POLICY &&
19710Sstevel@tonic-gate 			    strcmp(caller_ent.policy, arg->name) == 0) {
19722881Smp153739 		   ret.code = KADM5_OK;
19732881Smp153739 	      } else ret.code = KADM5_AUTH_GET;
19742881Smp153739 	      ret2 = kadm5_free_principal_ent(handle->lhandle,
19752881Smp153739 					      &caller_ent);
19762881Smp153739 	      ret.code = ret.code ? ret.code : ret2;
19772881Smp153739 	 }
19782881Smp153739     }
19792881Smp153739 
19802881Smp153739     if (ret.code == KADM5_OK) {
19812881Smp153739 	 if (handle->api_version == KADM5_API_VERSION_1) {
19822881Smp153739 	      ret.code  = kadm5_get_policy_v1((void *)handle, arg->name, &e);
19832881Smp153739 	      if(ret.code == KADM5_OK) {
19842881Smp153739 		   memcpy(&ret.rec, e, sizeof(kadm5_policy_ent_rec));
19852881Smp153739 		   free(e);
19862881Smp153739 	      }
19872881Smp153739 	 } else {
19882881Smp153739 	      ret.code = kadm5_get_policy((void *)handle, arg->name,
19892881Smp153739 					  &ret.rec);
19902881Smp153739 	 }
19912881Smp153739 
1992*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
1993*7934SMark.Phalan@Sun.COM 	 if( ret.code != 0 )
1994*7934SMark.Phalan@Sun.COM 	     errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
1995*7934SMark.Phalan@Sun.COM 
19960Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
19970Sstevel@tonic-gate 				funcname, prime_arg, client_name, ret.code);
1998*7934SMark.Phalan@Sun.COM 	 log_done(funcname,
1999*7934SMark.Phalan@Sun.COM 		  ((prime_arg == NULL) ? "(null)" : prime_arg),
2000*7934SMark.Phalan@Sun.COM 		  errmsg ? errmsg : "success",
2001*7934SMark.Phalan@Sun.COM 		  client_name, service_name, client_addr(rqstp, buf));
2002*7934SMark.Phalan@Sun.COM 
2003*7934SMark.Phalan@Sun.COM 	 if (errmsg != NULL)
2004*7934SMark.Phalan@Sun.COM 		krb5_free_error_message(handle ? handle->context : NULL, errmsg);
2005*7934SMark.Phalan@Sun.COM 
2006*7934SMark.Phalan@Sun.COM     } else {
20070Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
20080Sstevel@tonic-gate 				    funcname, prime_arg, client_name);
2009*7934SMark.Phalan@Sun.COM 	 log_unauth(funcname, prime_arg,
2010*7934SMark.Phalan@Sun.COM 		    client_name, service_name, client_addr(rqstp, buf));
20112881Smp153739     }
20120Sstevel@tonic-gate 
20130Sstevel@tonic-gate error:
20140Sstevel@tonic-gate 	if (name)
20150Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
20160Sstevel@tonic-gate 	free_server_handle(handle);
20170Sstevel@tonic-gate 	if (client_name)
20180Sstevel@tonic-gate 		free(client_name);
20190Sstevel@tonic-gate 	if (service_name)
20200Sstevel@tonic-gate 		free(service_name);
20210Sstevel@tonic-gate 	return (&ret);
20220Sstevel@tonic-gate 
20230Sstevel@tonic-gate }
20240Sstevel@tonic-gate 
20250Sstevel@tonic-gate gpols_ret *
2026*7934SMark.Phalan@Sun.COM get_pols_2_svc(gpols_arg *arg, struct svc_req *rqstp)
20270Sstevel@tonic-gate {
20282881Smp153739     static gpols_ret		    ret;
20292881Smp153739     char			    *prime_arg = NULL;
20302881Smp153739     char *client_name = NULL, *service_name = NULL;
20312881Smp153739     OM_uint32 min_stat;
20322881Smp153739     kadm5_server_handle_t handle;
2033*7934SMark.Phalan@Sun.COM     const char                            *errmsg = NULL;
20342881Smp153739     gss_name_t name = NULL;
20350Sstevel@tonic-gate 
20362881Smp153739     xdr_free(xdr_gpols_ret, (char *) &ret);
20370Sstevel@tonic-gate 
20382881Smp153739     if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
20392881Smp153739 	 return &ret;
20400Sstevel@tonic-gate 
20412881Smp153739     if ((ret.code = check_handle((void *)handle)))
20420Sstevel@tonic-gate 		goto error;
20432881Smp153739 
20442881Smp153739     ret.api_version = handle->api_version;
20450Sstevel@tonic-gate 
20462881Smp153739     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
20472881Smp153739 	 ret.code = KADM5_FAILURE;
20482881Smp153739 	goto error;
20492881Smp153739     }
20502881Smp153739     prime_arg = arg->exp;
20512881Smp153739     if (prime_arg == NULL)
20522881Smp153739 	 prime_arg = "*";
20530Sstevel@tonic-gate 
20540Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
20550Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
20560Sstevel@tonic-gate 		goto error;
20570Sstevel@tonic-gate 	}
20580Sstevel@tonic-gate 
20592881Smp153739     if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
20602881Smp153739 					      name,
20612881Smp153739 					      ACL_LIST, NULL, NULL)) {
20622881Smp153739 	 ret.code = KADM5_AUTH_LIST;
20630Sstevel@tonic-gate 
20640Sstevel@tonic-gate 		audit_kadmind_unauth(rqstp->rq_xprt, l_port,
20650Sstevel@tonic-gate 				    "kadm5_get_policies",
20660Sstevel@tonic-gate 				    prime_arg, client_name);
20673998Ssemery 	 log_unauth("kadm5_get_policies", prime_arg,
2068*7934SMark.Phalan@Sun.COM 		    client_name, service_name, client_addr(rqstp, buf));
20692881Smp153739     } else {
20702881Smp153739 	 ret.code  = kadm5_get_policies((void *)handle,
2071*7934SMark.Phalan@Sun.COM 					       arg->exp, &ret.pols,
2072*7934SMark.Phalan@Sun.COM 					       &ret.count);
2073*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
2074*7934SMark.Phalan@Sun.COM 	 if( ret.code != 0 )
2075*7934SMark.Phalan@Sun.COM 	     errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
20760Sstevel@tonic-gate 
20770Sstevel@tonic-gate 		audit_kadmind_auth(rqstp->rq_xprt, l_port,
20780Sstevel@tonic-gate 				"kadm5_get_policies",
20790Sstevel@tonic-gate 				prime_arg, client_name, ret.code);
2080*7934SMark.Phalan@Sun.COM 	 log_done("kadm5_get_policies", prime_arg,
2081*7934SMark.Phalan@Sun.COM 		  errmsg ? errmsg : "success",
2082*7934SMark.Phalan@Sun.COM 		  client_name, service_name, client_addr(rqstp, buf));
2083*7934SMark.Phalan@Sun.COM 
2084*7934SMark.Phalan@Sun.COM 	  if (errmsg != NULL)
2085*7934SMark.Phalan@Sun.COM 		krb5_free_error_message(handle ? handle->context : NULL, errmsg);
20862881Smp153739     }
20870Sstevel@tonic-gate 
20880Sstevel@tonic-gate error:
20890Sstevel@tonic-gate 	if (name)
20900Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
20910Sstevel@tonic-gate 	free_server_handle(handle);
20920Sstevel@tonic-gate 	if (client_name)
20930Sstevel@tonic-gate 		free(client_name);
20940Sstevel@tonic-gate 	if (service_name)
20950Sstevel@tonic-gate 		free(service_name);
20960Sstevel@tonic-gate 	return (&ret);
20970Sstevel@tonic-gate }
20980Sstevel@tonic-gate 
2099*7934SMark.Phalan@Sun.COM getprivs_ret * get_privs_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp)
21000Sstevel@tonic-gate {
21012881Smp153739      static getprivs_ret	    ret;
21022881Smp153739      char *client_name = NULL, *service_name = NULL;
21032881Smp153739      OM_uint32 min_stat;
21042881Smp153739      kadm5_server_handle_t handle;
2105*7934SMark.Phalan@Sun.COM      const char                           *errmsg = NULL;
21062881Smp153739      gss_name_t name = NULL;
21070Sstevel@tonic-gate 
21082881Smp153739      xdr_free(xdr_getprivs_ret, (char *) &ret);
21090Sstevel@tonic-gate 
21102881Smp153739      if ((ret.code = new_server_handle(*arg, rqstp, &handle)))
21112881Smp153739 	  return &ret;
21120Sstevel@tonic-gate 
21132881Smp153739      if ((ret.code = check_handle((void *)handle)))
21140Sstevel@tonic-gate 		goto error;
21152881Smp153739 
21162881Smp153739      ret.api_version = handle->api_version;
21170Sstevel@tonic-gate 
21182881Smp153739      if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
21192881Smp153739 	  ret.code = KADM5_FAILURE;
21202881Smp153739 	  goto error;
21212881Smp153739      }
21220Sstevel@tonic-gate 	if (!(name = get_clnt_name(rqstp))) {
21230Sstevel@tonic-gate 		ret.code = KADM5_FAILURE;
21240Sstevel@tonic-gate 		goto error;
21250Sstevel@tonic-gate 	}
21260Sstevel@tonic-gate 
21270Sstevel@tonic-gate 	ret.code = __kadm5_get_priv((void *) handle, &ret.privs, name);
2128*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
2129*7934SMark.Phalan@Sun.COM      if( ret.code != 0 )
2130*7934SMark.Phalan@Sun.COM 	 errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
21310Sstevel@tonic-gate 
21320Sstevel@tonic-gate 	audit_kadmind_auth(rqstp->rq_xprt, l_port,
21330Sstevel@tonic-gate 			"kadm5_get_privs", NULL, client_name,
21340Sstevel@tonic-gate 			ret.code);
21353998Ssemery 	log_done("kadm5_get_privs", client_name,
2136*7934SMark.Phalan@Sun.COM 	    errmsg ? errmsg : "success",
21370Sstevel@tonic-gate 	    client_name, service_name, client_addr(rqstp, buf));
2138*7934SMark.Phalan@Sun.COM 
2139*7934SMark.Phalan@Sun.COM 	if (errmsg != NULL)
2140*7934SMark.Phalan@Sun.COM 		krb5_free_error_message(handle ? handle->context : NULL, errmsg);
21410Sstevel@tonic-gate 
21420Sstevel@tonic-gate error:
21430Sstevel@tonic-gate 	if (name)
21440Sstevel@tonic-gate 		gss_release_name(&min_stat, &name);
21450Sstevel@tonic-gate 	free_server_handle(handle);
21460Sstevel@tonic-gate 	if (client_name)
21470Sstevel@tonic-gate 		free(client_name);
21480Sstevel@tonic-gate 	if (service_name)
21490Sstevel@tonic-gate 		free(service_name);
21500Sstevel@tonic-gate 	return (&ret);
21510Sstevel@tonic-gate }
21520Sstevel@tonic-gate 
2153*7934SMark.Phalan@Sun.COM generic_ret *init_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp)
21540Sstevel@tonic-gate {
21552881Smp153739      static generic_ret		ret;
21563998Ssemery      char *client_name, *service_name;
21573998Ssemery      kadm5_server_handle_t handle;
2158*7934SMark.Phalan@Sun.COM      const char                       *errmsg = NULL;
21593998Ssemery      size_t clen, slen;
21603998Ssemery      char *cdots, *sdots;
21610Sstevel@tonic-gate 
21622881Smp153739      xdr_free(xdr_generic_ret, (char *) &ret);
21630Sstevel@tonic-gate 
21642881Smp153739      if ((ret.code = new_server_handle(*arg, rqstp, &handle)))
21652881Smp153739 	  return &ret;
21662881Smp153739      if (! (ret.code = check_handle((void *)handle))) {
21672881Smp153739 	 ret.api_version = handle->api_version;
21682881Smp153739      }
21690Sstevel@tonic-gate 
21702881Smp153739      free_server_handle(handle);
21712881Smp153739 
21722881Smp153739      if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
21732881Smp153739 	  ret.code = KADM5_FAILURE;
21742881Smp153739 	  return &ret;
21752881Smp153739      }
21760Sstevel@tonic-gate 
2177*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
2178*7934SMark.Phalan@Sun.COM      if (ret.code != 0)
2179*7934SMark.Phalan@Sun.COM 	 errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
2180*7934SMark.Phalan@Sun.COM 
21810Sstevel@tonic-gate 	audit_kadmind_auth(rqstp->rq_xprt, l_port,
21820Sstevel@tonic-gate 			(ret.api_version == KADM5_API_VERSION_1 ?
21830Sstevel@tonic-gate 			"kadm5_init (V1)" : "kadm5_init"),
21840Sstevel@tonic-gate 			NULL, client_name, ret.code);
21853998Ssemery 
2186*7934SMark.Phalan@Sun.COM      clen = strlen(client_name);
2187*7934SMark.Phalan@Sun.COM      trunc_name(&clen, &cdots);
2188*7934SMark.Phalan@Sun.COM      slen = strlen(service_name);
2189*7934SMark.Phalan@Sun.COM      trunc_name(&slen, &sdots);
2190*7934SMark.Phalan@Sun.COM      krb5_klog_syslog(LOG_NOTICE, "Request: %s, %.*s%s, %s, "
2191*7934SMark.Phalan@Sun.COM 		      "client=%.*s%s, service=%.*s%s, addr=%s, flavor=%d",
2192*7934SMark.Phalan@Sun.COM 		      (ret.api_version == KADM5_API_VERSION_1 ?
2193*7934SMark.Phalan@Sun.COM 		       "kadm5_init (V1)" : "kadm5_init"),
2194*7934SMark.Phalan@Sun.COM 		      clen, client_name, cdots,
2195*7934SMark.Phalan@Sun.COM 		      errmsg ? errmsg : "success",
2196*7934SMark.Phalan@Sun.COM 		      clen, client_name, cdots,
2197*7934SMark.Phalan@Sun.COM 		      slen, service_name, sdots,
2198*7934SMark.Phalan@Sun.COM 		      client_addr(rqstp, buf),
2199*7934SMark.Phalan@Sun.COM 		      rqstp->rq_cred.oa_flavor);
2200*7934SMark.Phalan@Sun.COM 	if (errmsg != NULL)
2201*7934SMark.Phalan@Sun.COM 		krb5_free_error_message(handle ? handle->context : NULL, errmsg);
22020Sstevel@tonic-gate 	free(client_name);
22030Sstevel@tonic-gate 	free(service_name);
22040Sstevel@tonic-gate 
22050Sstevel@tonic-gate 	return (&ret);
22060Sstevel@tonic-gate }
2207