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