xref: /titanic_50/usr/src/cmd/krb5/kadmin/server/ovsec_kadmd.c (revision 4e2a441b1242a0b1975a0a8f01c33106e9f28e86)
17c478bd9Sstevel@tonic-gate /*
2d15b0992SMark Phalan  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate 
77c478bd9Sstevel@tonic-gate /*
87c478bd9Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
97c478bd9Sstevel@tonic-gate  *
107c478bd9Sstevel@tonic-gate  *	Openvision retains the copyright to derivative works of
117c478bd9Sstevel@tonic-gate  *	this source code.	Do *NOT* create a derivative of this
127c478bd9Sstevel@tonic-gate  *	source code before consulting with your legal department.
137c478bd9Sstevel@tonic-gate  *	Do *NOT* integrate *ANY* of this source code into another
147c478bd9Sstevel@tonic-gate  *	product before consulting with your legal department.
157c478bd9Sstevel@tonic-gate  *
167c478bd9Sstevel@tonic-gate  *	For further information, read the top-level Openvision
177c478bd9Sstevel@tonic-gate  *	copyright which is contained in the top-level MIT Kerberos
187c478bd9Sstevel@tonic-gate  *	copyright.
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
217c478bd9Sstevel@tonic-gate  *
227c478bd9Sstevel@tonic-gate  */
237c478bd9Sstevel@tonic-gate 
247c478bd9Sstevel@tonic-gate /*
257c478bd9Sstevel@tonic-gate  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
26159d09a2SMark Phalan  *
277c478bd9Sstevel@tonic-gate  */
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate /*
3056a424ccSmp153739  * Copyright (C) 1998 by the FundsXpress, INC.
3156a424ccSmp153739  *
3256a424ccSmp153739  * All rights reserved.
3356a424ccSmp153739  *
3456a424ccSmp153739  * Export of this software from the United States of America may require
3556a424ccSmp153739  * a specific license from the United States Government.  It is the
3656a424ccSmp153739  * responsibility of any person or organization contemplating export to
3756a424ccSmp153739  * obtain such a license before exporting.
3856a424ccSmp153739  *
3956a424ccSmp153739  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
4056a424ccSmp153739  * distribute this software and its documentation for any purpose and
4156a424ccSmp153739  * without fee is hereby granted, provided that the above copyright
4256a424ccSmp153739  * notice appear in all copies and that both that copyright notice and
4356a424ccSmp153739  * this permission notice appear in supporting documentation, and that
4456a424ccSmp153739  * the name of FundsXpress. not be used in advertising or publicity pertaining
4556a424ccSmp153739  * to distribution of the software without specific, written prior
4656a424ccSmp153739  * permission.  FundsXpress makes no representations about the suitability of
4756a424ccSmp153739  * this software for any purpose.  It is provided "as is" without express
4856a424ccSmp153739  * or implied warranty.
4956a424ccSmp153739  *
5056a424ccSmp153739  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
5156a424ccSmp153739  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
5256a424ccSmp153739  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
5356a424ccSmp153739  */
5456a424ccSmp153739 
5556a424ccSmp153739 
5656a424ccSmp153739 /*
577c478bd9Sstevel@tonic-gate  * SUNWresync121 XXX
587c478bd9Sstevel@tonic-gate  * Beware future resyncers, this file is much diff from MIT (1.0...)
597c478bd9Sstevel@tonic-gate  */
607c478bd9Sstevel@tonic-gate 
617c478bd9Sstevel@tonic-gate #include    <stdio.h>
62004388ebScasper #include    <stdio_ext.h>
637c478bd9Sstevel@tonic-gate #include    <signal.h>
647c478bd9Sstevel@tonic-gate #include    <syslog.h>
657c478bd9Sstevel@tonic-gate #include    <sys/types.h>
6656a424ccSmp153739 #ifdef _AIX
6756a424ccSmp153739 #include    <sys/select.h>
6856a424ccSmp153739 #endif
697c478bd9Sstevel@tonic-gate #include    <sys/time.h>
707c478bd9Sstevel@tonic-gate #include    <sys/socket.h>
717c478bd9Sstevel@tonic-gate #include    <unistd.h>
727c478bd9Sstevel@tonic-gate #include    <netinet/in.h>
737c478bd9Sstevel@tonic-gate #include    <arpa/inet.h>  /* inet_ntoa */
747c478bd9Sstevel@tonic-gate #include    <gssapi/gssapi.h>
75159d09a2SMark Phalan #include    "gssapiP_krb5.h" /* for kg_get_context */
767c478bd9Sstevel@tonic-gate #include    <rpc/rpc.h>
777c478bd9Sstevel@tonic-gate #include    <kadm5/admin.h>
787c478bd9Sstevel@tonic-gate #include    <kadm5/kadm_rpc.h>
797c478bd9Sstevel@tonic-gate #include    <server_acl.h>
807c478bd9Sstevel@tonic-gate #include    <krb5/adm_proto.h>
81159d09a2SMark Phalan #include    "kdb_kt.h"	/* for krb5_ktkdb_set_context */
827c478bd9Sstevel@tonic-gate #include    <string.h>
8356a424ccSmp153739 #include    <kadm5/server_internal.h>
847c478bd9Sstevel@tonic-gate #include    <gssapi_krb5.h>
857c478bd9Sstevel@tonic-gate #include    <libintl.h>
867c478bd9Sstevel@tonic-gate #include    <locale.h>
877c478bd9Sstevel@tonic-gate #include    <sys/resource.h>
887c478bd9Sstevel@tonic-gate #include    <kdb/kdb_log.h>
8954925bf6Swillf #include    <kdb_kt.h>
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate #include <rpc/rpcsec_gss.h>
9256a424ccSmp153739 #include    "misc.h"
937c478bd9Sstevel@tonic-gate 
94159d09a2SMark Phalan #ifdef PURIFY
95159d09a2SMark Phalan #include    "purify.h"
96159d09a2SMark Phalan 
97159d09a2SMark Phalan int	signal_pure_report = 0;
98159d09a2SMark Phalan int	signal_pure_clear = 0;
99159d09a2SMark Phalan void	request_pure_report(int);
100159d09a2SMark Phalan void	request_pure_clear(int);
101159d09a2SMark Phalan #endif /* PURIFY */
102159d09a2SMark Phalan 
103159d09a2SMark Phalan 
1047c478bd9Sstevel@tonic-gate #ifndef	FD_SETSIZE
1057c478bd9Sstevel@tonic-gate #define	FD_SETSIZE	256
1067c478bd9Sstevel@tonic-gate #endif
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate #ifndef MAX
1097c478bd9Sstevel@tonic-gate #define	MAX(a, b)	(((a) > (b)) ? (a) : (b))
1107c478bd9Sstevel@tonic-gate #endif
1117c478bd9Sstevel@tonic-gate 
11256a424ccSmp153739 #if defined(NEED_DAEMON_PROTO)
11356a424ccSmp153739 extern int daemon(int, int);
11456a424ccSmp153739 #endif
11556a424ccSmp153739 
1167c478bd9Sstevel@tonic-gate static int	signal_request_exit = 0;
1177c478bd9Sstevel@tonic-gate kadm5_config_params chgpw_params;
1187c478bd9Sstevel@tonic-gate void    setup_signal_handlers(iprop_role iproprole);
119159d09a2SMark Phalan void	request_exit(int);
1207c478bd9Sstevel@tonic-gate void	sig_pipe(int);
121159d09a2SMark Phalan void	kadm_svc_run(void);
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate #ifdef POSIX_SIGNALS
1247c478bd9Sstevel@tonic-gate static struct sigaction s_action;
1257c478bd9Sstevel@tonic-gate #endif /* POSIX_SIGNALS */
1267c478bd9Sstevel@tonic-gate 
12756a424ccSmp153739 
1287c478bd9Sstevel@tonic-gate #define	TIMEOUT	15
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate typedef struct _auth_gssapi_name {
1317c478bd9Sstevel@tonic-gate 	char *name;
1327c478bd9Sstevel@tonic-gate 	gss_OID type;
1337c478bd9Sstevel@tonic-gate } auth_gssapi_name;
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate gss_name_t gss_changepw_name = NULL, gss_oldchangepw_name = NULL;
1367c478bd9Sstevel@tonic-gate void *global_server_handle;
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate /*
1397c478bd9Sstevel@tonic-gate  * This is a kludge, but the server needs these constants to be
1407c478bd9Sstevel@tonic-gate  * compatible with old clients.  They are defined in <kadm5/admin.h>,
1417c478bd9Sstevel@tonic-gate  * but only if USE_KADM5_API_VERSION == 1.
1427c478bd9Sstevel@tonic-gate  */
1437c478bd9Sstevel@tonic-gate #define OVSEC_KADM_ADMIN_SERVICE_P	"ovsec_adm@admin"
1447c478bd9Sstevel@tonic-gate #define OVSEC_KADM_CHANGEPW_SERVICE_P	"ovsec_adm@changepw"
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate extern void krb5_iprop_prog_1();
1487c478bd9Sstevel@tonic-gate extern kadm5_ret_t kiprop_get_adm_host_srv_name(
1497c478bd9Sstevel@tonic-gate 	krb5_context,
1507c478bd9Sstevel@tonic-gate 	const char *,
1517c478bd9Sstevel@tonic-gate 	char **);
1527c478bd9Sstevel@tonic-gate 
153159d09a2SMark Phalan static int schpw;
1547c478bd9Sstevel@tonic-gate 
15556a424ccSmp153739 
1567c478bd9Sstevel@tonic-gate in_port_t l_port = 0;	/* global local port num, for BSM audits */
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate int nofork = 0; /* global; don't fork (debug mode) */
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate /*
1627c478bd9Sstevel@tonic-gate  * Function: usage
1637c478bd9Sstevel@tonic-gate  *
1647c478bd9Sstevel@tonic-gate  * Purpose: print out the server usage message
1657c478bd9Sstevel@tonic-gate  *
1667c478bd9Sstevel@tonic-gate  * Arguments:
1677c478bd9Sstevel@tonic-gate  * Requires:
1687c478bd9Sstevel@tonic-gate  * Effects:
1697c478bd9Sstevel@tonic-gate  * Modifies:
1707c478bd9Sstevel@tonic-gate  */
1717c478bd9Sstevel@tonic-gate 
usage()17256a424ccSmp153739 static void usage()
1737c478bd9Sstevel@tonic-gate {
17454925bf6Swillf      fprintf(stderr, gettext("Usage: kadmind [-x db_args]* [-r realm] [-m] [-d] "
1757c478bd9Sstevel@tonic-gate          "[-p port-number]\n"));
1767c478bd9Sstevel@tonic-gate      exit(1);
1777c478bd9Sstevel@tonic-gate }
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate /*
1807c478bd9Sstevel@tonic-gate  * Function: display_status
1817c478bd9Sstevel@tonic-gate  *
1827c478bd9Sstevel@tonic-gate  * Purpose: displays GSS-API messages
1837c478bd9Sstevel@tonic-gate  *
1847c478bd9Sstevel@tonic-gate  * Arguments:
1857c478bd9Sstevel@tonic-gate  *
1867c478bd9Sstevel@tonic-gate  * 	msg		a string to be displayed with the message
1877c478bd9Sstevel@tonic-gate  * 	maj_stat	the GSS-API major status code
1887c478bd9Sstevel@tonic-gate  * 	min_stat	the GSS-API minor status code
1897c478bd9Sstevel@tonic-gate  *
1907c478bd9Sstevel@tonic-gate  * Effects:
1917c478bd9Sstevel@tonic-gate  *
1927c478bd9Sstevel@tonic-gate  * The GSS-API messages associated with maj_stat and min_stat are
1937c478bd9Sstevel@tonic-gate  * displayed on stderr, each preceeded by "GSS-API error <msg>: " and
1947c478bd9Sstevel@tonic-gate  * followed by a newline.
1957c478bd9Sstevel@tonic-gate  */
19656a424ccSmp153739 static void display_status_1(char *, OM_uint32, int);
1977c478bd9Sstevel@tonic-gate 
display_status(msg,maj_stat,min_stat)19856a424ccSmp153739 static void display_status(msg, maj_stat, min_stat)
1997c478bd9Sstevel@tonic-gate      char *msg;
2007c478bd9Sstevel@tonic-gate      OM_uint32 maj_stat;
2017c478bd9Sstevel@tonic-gate      OM_uint32 min_stat;
2027c478bd9Sstevel@tonic-gate {
2037c478bd9Sstevel@tonic-gate      display_status_1(msg, maj_stat, GSS_C_GSS_CODE);
2047c478bd9Sstevel@tonic-gate      display_status_1(msg, min_stat, GSS_C_MECH_CODE);
2057c478bd9Sstevel@tonic-gate }
2067c478bd9Sstevel@tonic-gate 
display_status_1(m,code,type)2077c478bd9Sstevel@tonic-gate static void display_status_1(m, code, type)
2087c478bd9Sstevel@tonic-gate      char *m;
2097c478bd9Sstevel@tonic-gate      OM_uint32 code;
2107c478bd9Sstevel@tonic-gate      int type;
2117c478bd9Sstevel@tonic-gate {
2127c478bd9Sstevel@tonic-gate 	OM_uint32 maj_stat, min_stat;
2137c478bd9Sstevel@tonic-gate 	gss_buffer_desc msg;
2147c478bd9Sstevel@tonic-gate 	OM_uint32 msg_ctx;
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate 	msg_ctx = 0;
2177c478bd9Sstevel@tonic-gate 	while (1) {
2187c478bd9Sstevel@tonic-gate 		maj_stat = gss_display_status(&min_stat, code,
2197c478bd9Sstevel@tonic-gate 					      type, GSS_C_NULL_OID,
2207c478bd9Sstevel@tonic-gate 					      &msg_ctx, &msg);
2217c478bd9Sstevel@tonic-gate 		fprintf(stderr, "GSS-API error %s: %s\n", m,
2227c478bd9Sstevel@tonic-gate 			(char *)msg.value);
2237c478bd9Sstevel@tonic-gate 		(void) gss_release_buffer(&min_stat, &msg);
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate 		if (!msg_ctx)
2267c478bd9Sstevel@tonic-gate 			break;
2277c478bd9Sstevel@tonic-gate 	}
2287c478bd9Sstevel@tonic-gate }
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate /*
2327c478bd9Sstevel@tonic-gate  * Solaris Kerberos: the following prototypes are needed because these are
2337c478bd9Sstevel@tonic-gate  * private interfaces that do not have prototypes in any .h
2347c478bd9Sstevel@tonic-gate  */
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate extern struct hostent   *res_getipnodebyaddr(const void *, size_t, int, int *);
2377c478bd9Sstevel@tonic-gate extern void             res_freehostent(struct hostent *);
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate static void
freedomnames(char ** npp)2407c478bd9Sstevel@tonic-gate freedomnames(char **npp)
2417c478bd9Sstevel@tonic-gate {
2427c478bd9Sstevel@tonic-gate 	char **tpp;
2437c478bd9Sstevel@tonic-gate 
2447c478bd9Sstevel@tonic-gate 	if (npp) {
2457c478bd9Sstevel@tonic-gate 		tpp = npp;
2467c478bd9Sstevel@tonic-gate 		while (*tpp++) {
2477c478bd9Sstevel@tonic-gate 			free(*(tpp-1));
2487c478bd9Sstevel@tonic-gate 		}
2497c478bd9Sstevel@tonic-gate 		free(npp);
2507c478bd9Sstevel@tonic-gate 	}
2517c478bd9Sstevel@tonic-gate }
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate /*
2547c478bd9Sstevel@tonic-gate  * Construct a list of uniq FQDNs of all the net interfaces (except
2557c478bd9Sstevel@tonic-gate  * krb5.conf master dups) and return it in arg 'dnames'.
2567c478bd9Sstevel@tonic-gate  *
2577c478bd9Sstevel@tonic-gate  * On successful return (0), caller must call freedomnames()
2587c478bd9Sstevel@tonic-gate  * to free memory.
2597c478bd9Sstevel@tonic-gate  */
2607c478bd9Sstevel@tonic-gate static int
getdomnames(krb5_context ctx,char * realm,char *** dnames)2617c478bd9Sstevel@tonic-gate getdomnames(krb5_context ctx, char *realm, char ***dnames)
2627c478bd9Sstevel@tonic-gate {
2637c478bd9Sstevel@tonic-gate 	krb5_address **addresses = NULL;
2647c478bd9Sstevel@tonic-gate 	krb5_address *a = NULL;
2657c478bd9Sstevel@tonic-gate 	struct hostent *hp = NULL;
2667c478bd9Sstevel@tonic-gate 	int ret, i, result=0, error;
2677c478bd9Sstevel@tonic-gate 	char **npp = NULL, **tpp=NULL;
2687c478bd9Sstevel@tonic-gate 	int dup=0, n = 0;
2697c478bd9Sstevel@tonic-gate 	char *cfhost = NULL; /* krb5 conf file master hostname */
2707c478bd9Sstevel@tonic-gate 
2717c478bd9Sstevel@tonic-gate 	if (ret = kadm5_get_master(ctx, realm, &cfhost)) {
2727c478bd9Sstevel@tonic-gate 		return (ret);
2737c478bd9Sstevel@tonic-gate 	}
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate 	ret = krb5_os_localaddr(ctx, &addresses);
2767c478bd9Sstevel@tonic-gate 	if (ret != 0) {
2777c478bd9Sstevel@tonic-gate 		if (nofork)
2787c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
2797c478bd9Sstevel@tonic-gate 				    "kadmind: get localaddrs failed: %s",
2807c478bd9Sstevel@tonic-gate 				    error_message(ret));
2817c478bd9Sstevel@tonic-gate 		result = ret;
2827c478bd9Sstevel@tonic-gate 		goto err;
2837c478bd9Sstevel@tonic-gate 	}
2847c478bd9Sstevel@tonic-gate 
2857c478bd9Sstevel@tonic-gate 
2867c478bd9Sstevel@tonic-gate 	for (i=0; addresses[i]; i++) {
2877c478bd9Sstevel@tonic-gate 		a = addresses[i];
2887c478bd9Sstevel@tonic-gate 		hp = res_getipnodebyaddr(a->contents, a->length,
2897c478bd9Sstevel@tonic-gate 					a->addrtype == ADDRTYPE_INET
2907c478bd9Sstevel@tonic-gate 					? AF_INET : AF_INET6,
2917c478bd9Sstevel@tonic-gate 					&error);
2927c478bd9Sstevel@tonic-gate 		if (hp != NULL) {
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate 			/* skip master host in krb5.conf */
2957c478bd9Sstevel@tonic-gate 			if (strcasecmp(cfhost, hp->h_name) == 0) {
2967c478bd9Sstevel@tonic-gate 				res_freehostent(hp);
2977c478bd9Sstevel@tonic-gate 				hp = NULL;
2987c478bd9Sstevel@tonic-gate 				continue;
2997c478bd9Sstevel@tonic-gate 			}
3007c478bd9Sstevel@tonic-gate 
3017c478bd9Sstevel@tonic-gate 			dup = 0;
3027c478bd9Sstevel@tonic-gate 			tpp = npp;
3037c478bd9Sstevel@tonic-gate 			/* skip if hostname already exists in list */
3047c478bd9Sstevel@tonic-gate 			while (tpp && *tpp++) {
3057c478bd9Sstevel@tonic-gate 				if (strcasecmp(*(tpp-1), hp->h_name) == 0) {
3067c478bd9Sstevel@tonic-gate 					dup++;
3077c478bd9Sstevel@tonic-gate 					break;
3087c478bd9Sstevel@tonic-gate 				}
3097c478bd9Sstevel@tonic-gate 			}
3107c478bd9Sstevel@tonic-gate 
3117c478bd9Sstevel@tonic-gate 			if (dup) {
3127c478bd9Sstevel@tonic-gate 				res_freehostent(hp);
3137c478bd9Sstevel@tonic-gate 				hp = NULL;
3147c478bd9Sstevel@tonic-gate 				continue;
3157c478bd9Sstevel@tonic-gate 			}
3167c478bd9Sstevel@tonic-gate 
3177c478bd9Sstevel@tonic-gate 			npp = realloc(npp, sizeof(char *) * (n + 2));
3187c478bd9Sstevel@tonic-gate 			if (!npp) {
3197c478bd9Sstevel@tonic-gate 				result = ENOMEM;
3207c478bd9Sstevel@tonic-gate 				goto err;
3217c478bd9Sstevel@tonic-gate 			}
3227c478bd9Sstevel@tonic-gate 			npp[n] = strdup(hp->h_name);
3237c478bd9Sstevel@tonic-gate 			if (!npp[n]) {
3247c478bd9Sstevel@tonic-gate 				result = ENOMEM;
3257c478bd9Sstevel@tonic-gate 				goto err;
3267c478bd9Sstevel@tonic-gate 			}
3277c478bd9Sstevel@tonic-gate 			npp[n+1] = NULL;
3287c478bd9Sstevel@tonic-gate 			n++;
3297c478bd9Sstevel@tonic-gate 
3307c478bd9Sstevel@tonic-gate 			res_freehostent(hp);
3317c478bd9Sstevel@tonic-gate 			hp = NULL;
3327c478bd9Sstevel@tonic-gate 			result = 0;
3337c478bd9Sstevel@tonic-gate 		}
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate 	}
3367c478bd9Sstevel@tonic-gate 
3377c478bd9Sstevel@tonic-gate #ifdef DEBUG
3387c478bd9Sstevel@tonic-gate 	printf("getdomnames: n=%d, i=%d, npp=%p\n", n, i, npp);
3397c478bd9Sstevel@tonic-gate 	tpp = npp;
3407c478bd9Sstevel@tonic-gate 	while (tpp && *tpp++) {
3417c478bd9Sstevel@tonic-gate 		printf("tpp=%s\n", *(tpp-1));
3427c478bd9Sstevel@tonic-gate 	}
3437c478bd9Sstevel@tonic-gate #endif
3447c478bd9Sstevel@tonic-gate 
3457c478bd9Sstevel@tonic-gate 	goto out;
3467c478bd9Sstevel@tonic-gate 
3477c478bd9Sstevel@tonic-gate err:
3487c478bd9Sstevel@tonic-gate 	if (npp) {
3497c478bd9Sstevel@tonic-gate 		freedomnames(npp);
3507c478bd9Sstevel@tonic-gate 		npp = NULL;
3517c478bd9Sstevel@tonic-gate 	}
3527c478bd9Sstevel@tonic-gate 
3537c478bd9Sstevel@tonic-gate 	if (hp) {
3547c478bd9Sstevel@tonic-gate 		res_freehostent(hp);
3557c478bd9Sstevel@tonic-gate 		hp = NULL;
3567c478bd9Sstevel@tonic-gate 	}
3577c478bd9Sstevel@tonic-gate 
3587c478bd9Sstevel@tonic-gate out:
3597c478bd9Sstevel@tonic-gate 	if (cfhost) {
3607c478bd9Sstevel@tonic-gate 		free (cfhost);
3617c478bd9Sstevel@tonic-gate 		cfhost = NULL;
3627c478bd9Sstevel@tonic-gate 	}
3637c478bd9Sstevel@tonic-gate 	if (addresses) {
3647c478bd9Sstevel@tonic-gate 		krb5_free_addresses(ctx, addresses);
3657c478bd9Sstevel@tonic-gate 		addresses = NULL;
3667c478bd9Sstevel@tonic-gate 	}
3677c478bd9Sstevel@tonic-gate 
3687c478bd9Sstevel@tonic-gate 	if (result == 0)
3697c478bd9Sstevel@tonic-gate 		*dnames = npp;
3707c478bd9Sstevel@tonic-gate 
3717c478bd9Sstevel@tonic-gate 	return (result);
3727c478bd9Sstevel@tonic-gate }
3737c478bd9Sstevel@tonic-gate 
3747c478bd9Sstevel@tonic-gate /*
3757c478bd9Sstevel@tonic-gate  * Set the rpcsec_gss svc names for all net interfaces.
3767c478bd9Sstevel@tonic-gate  */
3777c478bd9Sstevel@tonic-gate static void
set_svc_domnames(char * svcname,char ** dnames,u_int program,u_int version)3787c478bd9Sstevel@tonic-gate set_svc_domnames(char *svcname, char **dnames,
3797c478bd9Sstevel@tonic-gate 		u_int program, u_int version)
3807c478bd9Sstevel@tonic-gate {
3817c478bd9Sstevel@tonic-gate 	bool_t ret;
3827c478bd9Sstevel@tonic-gate 	char **tpp = dnames;
3837c478bd9Sstevel@tonic-gate 
3847c478bd9Sstevel@tonic-gate 	if (!tpp)
3857c478bd9Sstevel@tonic-gate 		return;
3867c478bd9Sstevel@tonic-gate 
3877c478bd9Sstevel@tonic-gate 	while (*tpp++) {
3887c478bd9Sstevel@tonic-gate 		/* MAX_NAME_LEN from rpc/rpcsec_gss.h */
3897c478bd9Sstevel@tonic-gate 		char name[MAXHOSTNAMELEN+MAX_NAME_LEN+2] = {0};
3907c478bd9Sstevel@tonic-gate 		(void) snprintf(name, sizeof(name), "%s@%s",
3917c478bd9Sstevel@tonic-gate 				svcname, *(tpp-1));
3927c478bd9Sstevel@tonic-gate 		ret = rpc_gss_set_svc_name(name,
3937c478bd9Sstevel@tonic-gate 					"kerberos_v5", 0,
3947c478bd9Sstevel@tonic-gate 					program, version);
3957c478bd9Sstevel@tonic-gate 		if (nofork && ret)
3967c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
3977c478bd9Sstevel@tonic-gate 				    "rpc_gss_set_svc_name success: %s\n",
3987c478bd9Sstevel@tonic-gate 				    name);
3997c478bd9Sstevel@tonic-gate 	}
4007c478bd9Sstevel@tonic-gate }
4017c478bd9Sstevel@tonic-gate 
402159d09a2SMark Phalan /* XXX yuck.  the signal handlers need this */
403159d09a2SMark Phalan static krb5_context context;
4047c478bd9Sstevel@tonic-gate 
405159d09a2SMark Phalan static krb5_context hctx;
4067c478bd9Sstevel@tonic-gate 
main(int argc,char * argv[])407159d09a2SMark Phalan int main(int argc, char *argv[])
4087c478bd9Sstevel@tonic-gate {
409159d09a2SMark Phalan      register	SVCXPRT *transp;
4107c478bd9Sstevel@tonic-gate      extern	char *optarg;
4117c478bd9Sstevel@tonic-gate      extern	int optind, opterr;
4127c478bd9Sstevel@tonic-gate      int ret, rlen, oldnames = 0;
4137c478bd9Sstevel@tonic-gate      OM_uint32 OMret, major_status, minor_status;
4147c478bd9Sstevel@tonic-gate      char *whoami;
4157c478bd9Sstevel@tonic-gate      FILE *acl_file;
4167c478bd9Sstevel@tonic-gate      gss_buffer_desc in_buf;
4177c478bd9Sstevel@tonic-gate      struct servent *srv;
4187c478bd9Sstevel@tonic-gate      struct sockaddr_in addr;
4197c478bd9Sstevel@tonic-gate      struct sockaddr_in *sin;
4207c478bd9Sstevel@tonic-gate      int s;
421159d09a2SMark Phalan      auth_gssapi_name names[6];
422159d09a2SMark Phalan      gss_buffer_desc gssbuf;
423159d09a2SMark Phalan      gss_OID nt_krb5_name_oid;
4247c478bd9Sstevel@tonic-gate      int optchar;
4257c478bd9Sstevel@tonic-gate      struct netconfig *nconf;
4267c478bd9Sstevel@tonic-gate      void *handlep;
4277c478bd9Sstevel@tonic-gate      int fd;
4287c478bd9Sstevel@tonic-gate      struct t_info tinfo;
4297c478bd9Sstevel@tonic-gate      struct t_bind tbindstr, *tres;
4307c478bd9Sstevel@tonic-gate 
4317c478bd9Sstevel@tonic-gate      struct t_optmgmt req, resp;
4327c478bd9Sstevel@tonic-gate      struct opthdr *opt;
4337c478bd9Sstevel@tonic-gate      char reqbuf[128];
4347c478bd9Sstevel@tonic-gate      struct rlimit rl;
4357c478bd9Sstevel@tonic-gate 
4367c478bd9Sstevel@tonic-gate      char *kiprop_name = NULL; /* IProp svc name */
4377c478bd9Sstevel@tonic-gate      kdb_log_context *log_ctx;
4387c478bd9Sstevel@tonic-gate      kadm5_server_handle_t handle;
4397c478bd9Sstevel@tonic-gate      krb5_context ctx;
4407c478bd9Sstevel@tonic-gate 
4417c478bd9Sstevel@tonic-gate      kadm5_config_params params;
44254925bf6Swillf      char **db_args      = NULL;
44354925bf6Swillf      int    db_args_size = 0;
444159d09a2SMark Phalan      const char *errmsg;
4457c478bd9Sstevel@tonic-gate      char **dnames = NULL;
4467c478bd9Sstevel@tonic-gate      int retdn;
44754925bf6Swillf      int iprop_supported;
4487c478bd9Sstevel@tonic-gate 
4497c64d375Smp153739      /* Solaris Kerberos: Stores additional error messages */
4507c64d375Smp153739      char *emsg = NULL;
4517c64d375Smp153739 
4527c64d375Smp153739      /* Solaris Kerberos: Indicates whether loalhost is master or not */
4537c64d375Smp153739      krb5_boolean is_master;
4547c64d375Smp153739 
4557c64d375Smp153739      /* Solaris Kerberos: Used for checking acl file */
4567c64d375Smp153739      gss_name_t name;
4577c64d375Smp153739 
4587c478bd9Sstevel@tonic-gate      /* This is OID value the Krb5_Name NameType */
4597c478bd9Sstevel@tonic-gate      gssbuf.value = "{1 2 840 113554 1 2 2 1}";
4607c478bd9Sstevel@tonic-gate      gssbuf.length = strlen(gssbuf.value);
461159d09a2SMark Phalan      major_status = gss_str_to_oid(&minor_status, &gssbuf, &nt_krb5_name_oid);
4627c478bd9Sstevel@tonic-gate      if (major_status != GSS_S_COMPLETE) {
4637c478bd9Sstevel@tonic-gate 	     fprintf(stderr,
4647c478bd9Sstevel@tonic-gate 	         gettext("Couldn't create KRB5 Name NameType OID\n"));
4657c478bd9Sstevel@tonic-gate 	     display_status("str_to_oid", major_status, minor_status);
4667c478bd9Sstevel@tonic-gate 	     exit(1);
4677c478bd9Sstevel@tonic-gate      }
4687c478bd9Sstevel@tonic-gate 
469159d09a2SMark Phalan      names[0].name = names[1].name = names[2].name = names[3].name = NULL;
470159d09a2SMark Phalan      names[4].name  = names[5].name =NULL;
471159d09a2SMark Phalan      names[0].type = names[1].type = names[2].type = names[3].type =
4727c478bd9Sstevel@tonic-gate 	    (gss_OID) nt_krb5_name_oid;
473159d09a2SMark Phalan      names[4].type = names[5].type = (gss_OID) nt_krb5_name_oid;
4747c478bd9Sstevel@tonic-gate 
475159d09a2SMark Phalan #ifdef PURIFY
476159d09a2SMark Phalan      purify_start_batch();
477159d09a2SMark Phalan #endif /* PURIFY */
4787c478bd9Sstevel@tonic-gate      whoami = (strrchr(argv[0], '/') ? strrchr(argv[0], '/')+1 : argv[0]);
4797c478bd9Sstevel@tonic-gate 
4807c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
4817c478bd9Sstevel@tonic-gate 
4827c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)  /* Should be defined by cc -D */
4837c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN	"SYS_TEST"	/* Use this only if it weren't */
4847c478bd9Sstevel@tonic-gate #endif
4857c478bd9Sstevel@tonic-gate 
4867c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
4877c478bd9Sstevel@tonic-gate 
4887c478bd9Sstevel@tonic-gate      nofork = 0;
4897c478bd9Sstevel@tonic-gate 
4907c478bd9Sstevel@tonic-gate      memset((char *) &params, 0, sizeof(params));
4917c478bd9Sstevel@tonic-gate 
49254925bf6Swillf 	while ((optchar = getopt(argc, argv, "r:mdp:x:")) != EOF) {
4937c478bd9Sstevel@tonic-gate 		switch (optchar) {
4947c478bd9Sstevel@tonic-gate 		case 'r':
4957c478bd9Sstevel@tonic-gate 			if (!optarg)
4967c478bd9Sstevel@tonic-gate 				usage();
4977c478bd9Sstevel@tonic-gate 			params.realm = optarg;
4987c478bd9Sstevel@tonic-gate 			params.mask |= KADM5_CONFIG_REALM;
4997c478bd9Sstevel@tonic-gate 			break;
5007c478bd9Sstevel@tonic-gate 		case 'm':
5017c478bd9Sstevel@tonic-gate 			params.mkey_from_kbd = 1;
5027c478bd9Sstevel@tonic-gate 			params.mask |= KADM5_CONFIG_MKEY_FROM_KBD;
5037c478bd9Sstevel@tonic-gate 			break;
5047c478bd9Sstevel@tonic-gate 		case 'd':
5057c478bd9Sstevel@tonic-gate 			nofork = 1;
5067c478bd9Sstevel@tonic-gate 			break;
5077c478bd9Sstevel@tonic-gate 		case 'p':
5087c478bd9Sstevel@tonic-gate 			if (!optarg)
5097c478bd9Sstevel@tonic-gate 				usage();
5107c478bd9Sstevel@tonic-gate 			params.kadmind_port = atoi(optarg);
5117c478bd9Sstevel@tonic-gate 			params.mask |= KADM5_CONFIG_KADMIND_PORT;
5127c478bd9Sstevel@tonic-gate 			break;
51354925bf6Swillf 		case 'x':
51454925bf6Swillf 			if (!optarg)
51554925bf6Swillf 				usage();
51654925bf6Swillf 			db_args_size++;
51754925bf6Swillf 			{
51854925bf6Swillf 			    char **temp = realloc( db_args,
51954925bf6Swillf 				sizeof(char*) * (db_args_size+1)); /* one for NULL */
52054925bf6Swillf 			    if( temp == NULL )
52154925bf6Swillf 			    {
52254925bf6Swillf 				fprintf(stderr, gettext("%s: cannot initialize. Not enough memory\n"),
52354925bf6Swillf 				    whoami);
52454925bf6Swillf 				exit(1);
52554925bf6Swillf 			    }
52654925bf6Swillf 			    db_args = temp;
52754925bf6Swillf 			}
52854925bf6Swillf 			db_args[db_args_size-1] = optarg;
52954925bf6Swillf 			db_args[db_args_size]   = NULL;
53054925bf6Swillf 			break;
5317c478bd9Sstevel@tonic-gate 		case '?':
5327c478bd9Sstevel@tonic-gate 		default:
5337c478bd9Sstevel@tonic-gate 			usage();
5347c478bd9Sstevel@tonic-gate 		}
5357c478bd9Sstevel@tonic-gate 	}
5367c478bd9Sstevel@tonic-gate 
5377c478bd9Sstevel@tonic-gate 
5387c478bd9Sstevel@tonic-gate 	if (getrlimit(RLIMIT_NOFILE, &rl) == 0) {
5397c478bd9Sstevel@tonic-gate 		rl.rlim_cur = rl.rlim_max = MAX(rl.rlim_max, FD_SETSIZE);
540004388ebScasper 		(void) setrlimit(RLIMIT_NOFILE, &rl);
541004388ebScasper 		(void) enable_extended_FILE_stdio(-1, -1);
5427c478bd9Sstevel@tonic-gate 	}
5437c478bd9Sstevel@tonic-gate 
544159d09a2SMark Phalan      if ((ret = kadm5_init_krb5_context(&context))) {
5457c478bd9Sstevel@tonic-gate 	  fprintf(stderr,
5467c478bd9Sstevel@tonic-gate 	      gettext("%s: %s while initializing context, aborting\n"),
5477c478bd9Sstevel@tonic-gate 		  whoami, error_message(ret));
5487c478bd9Sstevel@tonic-gate 	  exit(1);
5497c478bd9Sstevel@tonic-gate      }
5507c478bd9Sstevel@tonic-gate 
5517c478bd9Sstevel@tonic-gate      krb5_klog_init(context, "admin_server", whoami, 1);
552159d09a2SMark Phalan 
553159d09a2SMark Phalan      /* Solaris Kerberos */
554159d09a2SMark Phalan      if((ret = kadm5_init2("kadmind", NULL,
555159d09a2SMark Phalan 			  NULL, &params,
556159d09a2SMark Phalan 			  KADM5_STRUCT_VERSION,
557159d09a2SMark Phalan 			  KADM5_API_VERSION_2,
558159d09a2SMark Phalan 			  db_args,
559159d09a2SMark Phalan 			  &global_server_handle,
560159d09a2SMark Phalan 			  &emsg)) != KADM5_OK) {
561159d09a2SMark Phalan 	  krb5_klog_syslog(LOG_ERR,
562159d09a2SMark Phalan 		gettext("%s while initializing, aborting"),
563159d09a2SMark Phalan 			   (emsg ? emsg : error_message(ret)));
564159d09a2SMark Phalan 	  fprintf(stderr,
565159d09a2SMark Phalan      	    gettext("%s: %s while initializing, aborting\n"),
566159d09a2SMark Phalan 		  whoami, (emsg ? emsg : error_message(ret)));
567159d09a2SMark Phalan 	  if (emsg)
568159d09a2SMark Phalan 		free(emsg);
569159d09a2SMark Phalan 	  krb5_klog_close(context);
57056a424ccSmp153739 	  exit(1);
57156a424ccSmp153739      }
572159d09a2SMark Phalan 
573159d09a2SMark Phalan      if( db_args )
574159d09a2SMark Phalan      {
575159d09a2SMark Phalan 	 free(db_args), db_args=NULL;
576159d09a2SMark Phalan      }
577159d09a2SMark Phalan 
578159d09a2SMark Phalan      if ((ret = kadm5_get_config_params(context, 1, &params,
579159d09a2SMark Phalan 					&params))) {
580159d09a2SMark Phalan 	  const char *e_txt = krb5_get_error_message (context, ret);
581159d09a2SMark Phalan 	  /* Solaris Kerberos: Remove double "whoami" */
582159d09a2SMark Phalan 	  krb5_klog_syslog(LOG_ERR, gettext("%s while initializing, aborting"),
583159d09a2SMark Phalan 			   e_txt);
584159d09a2SMark Phalan 	  fprintf(stderr,
585159d09a2SMark Phalan 		  gettext("%s: %s while initializing, aborting\n"),
586159d09a2SMark Phalan 		  whoami, e_txt);
587159d09a2SMark Phalan 	  kadm5_destroy(global_server_handle);
588159d09a2SMark Phalan 	  krb5_klog_close(context);
589159d09a2SMark Phalan 	  exit(1);
590159d09a2SMark Phalan      }
591159d09a2SMark Phalan 
592159d09a2SMark Phalan #define REQUIRED_PARAMS (KADM5_CONFIG_REALM | KADM5_CONFIG_ACL_FILE)
593159d09a2SMark Phalan 
594159d09a2SMark Phalan      if ((params.mask & REQUIRED_PARAMS) != REQUIRED_PARAMS) {
595159d09a2SMark Phalan 	  /* Solaris Kerberos: Keep error messages consistent */
596159d09a2SMark Phalan 	  krb5_klog_syslog(LOG_ERR,
597159d09a2SMark Phalan 		gettext("Missing required configuration values (%lx)"
598159d09a2SMark Phalan 			   "while initializing, aborting"),
599159d09a2SMark Phalan 			   (params.mask & REQUIRED_PARAMS) ^ REQUIRED_PARAMS);
600159d09a2SMark Phalan 	  fprintf(stderr,
601159d09a2SMark Phalan 		    gettext("%s: Missing required configuration values "
602159d09a2SMark Phalan 			"(%lx) while initializing, aborting\n"), whoami,
603159d09a2SMark Phalan 		  (params.mask & REQUIRED_PARAMS) ^ REQUIRED_PARAMS);
604159d09a2SMark Phalan 	  krb5_klog_close(context);
605159d09a2SMark Phalan 	  kadm5_destroy(global_server_handle);
606159d09a2SMark Phalan 	  exit(1);
607159d09a2SMark Phalan      }
6087c478bd9Sstevel@tonic-gate 
6097c478bd9Sstevel@tonic-gate 	/*
6107c478bd9Sstevel@tonic-gate 	 * When using the Horowitz/IETF protocol for
6117c478bd9Sstevel@tonic-gate 	 * password changing, the default port is 464
6127c478bd9Sstevel@tonic-gate 	 * (officially recognized by IANA)
6137c478bd9Sstevel@tonic-gate 	 *
6147c478bd9Sstevel@tonic-gate 	 * DEFAULT_KPASSWD_PORT -> 464
6157c478bd9Sstevel@tonic-gate 	 */
6167c478bd9Sstevel@tonic-gate 	chgpw_params.kpasswd_port = DEFAULT_KPASSWD_PORT;
6177c478bd9Sstevel@tonic-gate 	chgpw_params.mask |= KADM5_CONFIG_KPASSWD_PORT;
6187c478bd9Sstevel@tonic-gate 	chgpw_params.kpasswd_protocol = KRB5_CHGPWD_CHANGEPW_V2;
6197c478bd9Sstevel@tonic-gate 	chgpw_params.mask |= KADM5_CONFIG_KPASSWD_PROTOCOL;
6207c478bd9Sstevel@tonic-gate 
621159d09a2SMark Phalan      if (ret = kadm5_get_config_params(context, 1, &chgpw_params,
6227c478bd9Sstevel@tonic-gate      	&chgpw_params)) {
6237c64d375Smp153739 	/* Solaris Kerberos: Remove double "whoami" */
6247c64d375Smp153739      	krb5_klog_syslog(LOG_ERR, gettext("%s while initializing,"
6257c64d375Smp153739      			" aborting"), error_message(ret));
6267c478bd9Sstevel@tonic-gate      	fprintf(stderr,
6277c478bd9Sstevel@tonic-gate      	    gettext("%s: %s while initializing, aborting\n"),
6287c478bd9Sstevel@tonic-gate      	    whoami, error_message(ret));
6297c478bd9Sstevel@tonic-gate      	krb5_klog_close(context);
6307c478bd9Sstevel@tonic-gate      	exit(1);
6317c478bd9Sstevel@tonic-gate      }
6327c478bd9Sstevel@tonic-gate 
6337c478bd9Sstevel@tonic-gate 	/*
6347c478bd9Sstevel@tonic-gate 	 * We now setup the socket and bind() to port 464, so that
6357c478bd9Sstevel@tonic-gate 	 * kadmind can now listen to and process change-pwd requests
6367c478bd9Sstevel@tonic-gate 	 * from non-Solaris Kerberos V5 clients such as Microsoft,
6377c478bd9Sstevel@tonic-gate 	 * MIT, AIX, HP etc
6387c478bd9Sstevel@tonic-gate 	 */
6397c478bd9Sstevel@tonic-gate      if ((schpw = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
640159d09a2SMark Phalan 	 const char *e_txt = krb5_get_error_message (context, ret);
6417c478bd9Sstevel@tonic-gate 	 krb5_klog_syslog(LOG_ERR,
642159d09a2SMark Phalan 			 gettext( "Cannot create simple " "chpw socket: %s"),
643159d09a2SMark Phalan 			  e_txt);
644159d09a2SMark Phalan 	 fprintf(stderr, gettext("Cannot create simple chpw socket: %s"),
645159d09a2SMark Phalan 		 e_txt);
646159d09a2SMark Phalan 	 kadm5_destroy(global_server_handle);
6477c478bd9Sstevel@tonic-gate 	 krb5_klog_close(context);
6487c478bd9Sstevel@tonic-gate 	 exit(1);
6497c478bd9Sstevel@tonic-gate      }
6507c64d375Smp153739 
6517c64d375Smp153739 	/* Solaris Kerberos: Ensure that kadmind is only run on a master kdc */
6527c64d375Smp153739 	if (ret = kadm5_is_master(context, params.realm, &is_master)){
6537c64d375Smp153739 		krb5_klog_syslog(LOG_ERR,
6547c64d375Smp153739 		    gettext("Failed to determine whether host is master "
6557c64d375Smp153739 		    "KDC for realm %s: %s"), params.realm,
6567c64d375Smp153739 		    error_message(ret));
6577c64d375Smp153739 		fprintf(stderr,
6587c64d375Smp153739 		    gettext("%s: Failed to determine whether host is master "
6597c64d375Smp153739 		    "KDC for realm %s: %s\n"), whoami, params.realm,
6607c64d375Smp153739 		    error_message(ret));
6617c64d375Smp153739 		krb5_klog_close(context);
6627c64d375Smp153739 		exit(1);
6637c64d375Smp153739 	}
6647c64d375Smp153739 
6657c64d375Smp153739 	if (is_master == FALSE) {
6667c64d375Smp153739 		char *master = NULL;
6677c64d375Smp153739 		kadm5_get_master(context, params.realm, &master);
6687c64d375Smp153739 
6697c64d375Smp153739 		krb5_klog_syslog(LOG_ERR,
6707c64d375Smp153739 		    gettext("%s can only be run on the master KDC, %s, for "
6717c64d375Smp153739 		    "realm %s"), whoami, master ? master : "unknown",
6727c64d375Smp153739 		    params.realm);
6737c64d375Smp153739 		fprintf(stderr,
6747c64d375Smp153739 		    gettext("%s: %s can only be run on the master KDC, %s, for "
6757c64d375Smp153739 		    "realm %s\n"), whoami, whoami, master ? master: "unknown",
6767c64d375Smp153739 		    params.realm);
6777c64d375Smp153739 		krb5_klog_close(context);
6787c64d375Smp153739 		exit(1);
6797c64d375Smp153739 	}
6807c64d375Smp153739 
6817c478bd9Sstevel@tonic-gate      memset((char *) &addr, 0, sizeof (struct sockaddr_in));
6827c478bd9Sstevel@tonic-gate      addr.sin_family = AF_INET;
6837c478bd9Sstevel@tonic-gate      addr.sin_addr.s_addr = INADDR_ANY;
6847c478bd9Sstevel@tonic-gate      l_port = addr.sin_port = htons(params.kadmind_port);
6857c478bd9Sstevel@tonic-gate      sin = &addr;
6867c478bd9Sstevel@tonic-gate 
6877c478bd9Sstevel@tonic-gate 	if ((handlep = setnetconfig()) == (void *) NULL) {
6887c478bd9Sstevel@tonic-gate 		(void) krb5_klog_syslog(LOG_ERR,
6897c478bd9Sstevel@tonic-gate 		    gettext("cannot get any transport information"));
6907c478bd9Sstevel@tonic-gate 		krb5_klog_close(context);
6917c478bd9Sstevel@tonic-gate 		exit(1);
6927c478bd9Sstevel@tonic-gate 	}
693159d09a2SMark Phalan 
6947c478bd9Sstevel@tonic-gate 	while (nconf = getnetconfig(handlep)) {
6957c478bd9Sstevel@tonic-gate 		if ((nconf->nc_semantics == NC_TPI_COTS_ORD) &&
6967c478bd9Sstevel@tonic-gate 		    (strcmp(nconf->nc_protofmly, NC_INET) == 0) &&
6977c478bd9Sstevel@tonic-gate 		    (strcmp(nconf->nc_proto, NC_TCP) == 0))
6987c478bd9Sstevel@tonic-gate 			break;
6997c478bd9Sstevel@tonic-gate 	}
7007c478bd9Sstevel@tonic-gate 
7017c478bd9Sstevel@tonic-gate 	if (nconf == (struct netconfig *) NULL) {
7027c478bd9Sstevel@tonic-gate 		(void) endnetconfig(handlep);
7037c478bd9Sstevel@tonic-gate 		krb5_klog_close(context);
7047c478bd9Sstevel@tonic-gate 		exit(1);
7057c478bd9Sstevel@tonic-gate 	}
7067c478bd9Sstevel@tonic-gate 	fd = t_open(nconf->nc_device, O_RDWR, &tinfo);
7077c478bd9Sstevel@tonic-gate 	if (fd == -1) {
7087c478bd9Sstevel@tonic-gate 		krb5_klog_syslog(LOG_ERR,
7097c478bd9Sstevel@tonic-gate 		    gettext("unable to open connection for ADMIN server"));
7107c478bd9Sstevel@tonic-gate 		krb5_klog_close(context);
7117c478bd9Sstevel@tonic-gate 		exit(1);
7127c478bd9Sstevel@tonic-gate 	}
7137c478bd9Sstevel@tonic-gate 	/* LINTED */
7147c478bd9Sstevel@tonic-gate 	opt = (struct opthdr *) reqbuf;
7157c478bd9Sstevel@tonic-gate 	opt->level = SOL_SOCKET;
7167c478bd9Sstevel@tonic-gate 	opt->name = SO_REUSEADDR;
7177c478bd9Sstevel@tonic-gate 	opt->len = sizeof (int);
7187c478bd9Sstevel@tonic-gate 
7197c478bd9Sstevel@tonic-gate 	/*
7207c478bd9Sstevel@tonic-gate 	 * The option value is "1".  This will allow the server to restart
7217c478bd9Sstevel@tonic-gate 	 * whilst the previous process is cleaning up after itself in a
7227c478bd9Sstevel@tonic-gate 	 * FIN_WAIT_2 or TIME_WAIT state.  If another process is started
7237c478bd9Sstevel@tonic-gate 	 * outside of smf(5) then bind will fail anyway, which is what we want.
7247c478bd9Sstevel@tonic-gate 	 */
7257c478bd9Sstevel@tonic-gate 	reqbuf[sizeof (struct opthdr)] = 1;
7267c478bd9Sstevel@tonic-gate 
7277c478bd9Sstevel@tonic-gate 	req.flags = T_NEGOTIATE;
7287c478bd9Sstevel@tonic-gate 	req.opt.len = sizeof (struct opthdr) + opt->len;
7297c478bd9Sstevel@tonic-gate 	req.opt.buf = (char *) opt;
7307c478bd9Sstevel@tonic-gate 
7317c478bd9Sstevel@tonic-gate 	resp.flags = 0;
7327c478bd9Sstevel@tonic-gate 	resp.opt.buf = reqbuf;
7337c478bd9Sstevel@tonic-gate 	resp.opt.maxlen = sizeof (reqbuf);
7347c478bd9Sstevel@tonic-gate 
7357c478bd9Sstevel@tonic-gate 	if (t_optmgmt(fd, &req, &resp) < 0 || resp.flags != T_SUCCESS) {
7367c478bd9Sstevel@tonic-gate 		t_error("t_optmgmt");
7377c478bd9Sstevel@tonic-gate 		exit(1);
7387c478bd9Sstevel@tonic-gate 	}
7397c478bd9Sstevel@tonic-gate 	/* Transform addr to netbuf */
7407c478bd9Sstevel@tonic-gate 
7417c478bd9Sstevel@tonic-gate 	tres = (struct t_bind *) t_alloc(fd, T_BIND, T_ADDR);
7427c478bd9Sstevel@tonic-gate 	if (tres == NULL) {
7437c478bd9Sstevel@tonic-gate 		(void) t_close(fd);
7447c478bd9Sstevel@tonic-gate 		(void) krb5_klog_syslog(LOG_ERR,
7457c478bd9Sstevel@tonic-gate 					gettext("cannot allocate netbuf"));
7467c478bd9Sstevel@tonic-gate 		krb5_klog_close(context);
7477c478bd9Sstevel@tonic-gate 		exit(1);
7487c478bd9Sstevel@tonic-gate 	}
7497c478bd9Sstevel@tonic-gate 	tbindstr.qlen = 8;
7507c478bd9Sstevel@tonic-gate 	tbindstr.addr.buf = (char *) sin;
7517c478bd9Sstevel@tonic-gate 	tbindstr.addr.len = tbindstr.addr.maxlen = __rpc_get_a_size(tinfo.addr);
7527c478bd9Sstevel@tonic-gate 	sin = (struct sockaddr_in *) tbindstr.addr.buf;
7537c478bd9Sstevel@tonic-gate 	/* SUNWresync121 XXX (void) memset(&addr, 0, sizeof(addr)); */
7547c478bd9Sstevel@tonic-gate 
7557c478bd9Sstevel@tonic-gate      if (t_bind(fd, &tbindstr, tres) < 0) {
7567c478bd9Sstevel@tonic-gate 	  int oerrno = errno;
757159d09a2SMark Phalan 	  const char *e_txt = krb5_get_error_message (context, errno);
7587c478bd9Sstevel@tonic-gate 	  fprintf(stderr, gettext("%s: Cannot bind socket.\n"), whoami);
759159d09a2SMark Phalan 	  fprintf(stderr, gettext("bind: %s\n"), e_txt);
7607c478bd9Sstevel@tonic-gate 	  errno = oerrno;
761159d09a2SMark Phalan 	  krb5_klog_syslog(LOG_ERR, gettext("Cannot bind socket: %s"), e_txt);
7627c478bd9Sstevel@tonic-gate 	  if(oerrno == EADDRINUSE) {
7637c478bd9Sstevel@tonic-gate 	       char *w = strrchr(whoami, '/');
7647c478bd9Sstevel@tonic-gate 	       if (w) {
7657c478bd9Sstevel@tonic-gate 		    w++;
766159d09a2SMark Phalan 	       }
767159d09a2SMark Phalan 	       else {
7687c478bd9Sstevel@tonic-gate 		    w = whoami;
7697c478bd9Sstevel@tonic-gate 	       }
7707c478bd9Sstevel@tonic-gate 	       fprintf(stderr, gettext(
771159d09a2SMark Phalan "This probably means that another %s process is already\n"
772159d09a2SMark Phalan "running, or that another program is using the server port (number %d)\n"
773159d09a2SMark Phalan "after being assigned it by the RPC portmap daemon.  If another\n"
774159d09a2SMark Phalan "%s is already running, you should kill it before\n"
775159d09a2SMark Phalan "restarting the server.  If, on the other hand, another program is\n"
776159d09a2SMark Phalan "using the server port, you should kill it before running\n"
777159d09a2SMark Phalan "%s, and ensure that the conflict does not occur in the\n"
778159d09a2SMark Phalan "future by making sure that %s is started on reboot\n"
779159d09a2SMark Phalan 		       "before portmap.\n"), w, ntohs(addr.sin_port), w, w, w);
780159d09a2SMark Phalan 	       krb5_klog_syslog(LOG_ERR, gettext("Check for already-running %s or for "
7817c478bd9Sstevel@tonic-gate 		      "another process using port %d"), w,
7827c478bd9Sstevel@tonic-gate 		      htons(addr.sin_port));
7837c478bd9Sstevel@tonic-gate 	  }
784159d09a2SMark Phalan 	  kadm5_destroy(global_server_handle);
785159d09a2SMark Phalan 	  krb5_klog_close(context);
786159d09a2SMark Phalan 	  exit(1);
787159d09a2SMark Phalan      }
788159d09a2SMark Phalan      memset(&addr, 0, sizeof(addr));
789159d09a2SMark Phalan      addr.sin_family = AF_INET;
790159d09a2SMark Phalan      addr.sin_addr.s_addr = INADDR_ANY;
791159d09a2SMark Phalan 
792159d09a2SMark Phalan      addr.sin_port = htons(chgpw_params.kpasswd_port);
793159d09a2SMark Phalan 
794159d09a2SMark Phalan      if (bind(schpw, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
795159d09a2SMark Phalan 	  char portbuf[32];
796159d09a2SMark Phalan 	  int oerrno = errno;
797159d09a2SMark Phalan 	  const char *e_txt = krb5_get_error_message (context, errno);
798159d09a2SMark Phalan 	  fprintf(stderr, gettext("%s: Cannot bind socket.\n"), whoami);
799159d09a2SMark Phalan 	  fprintf(stderr, gettext("bind: %s\n"), e_txt);
800159d09a2SMark Phalan 	  errno = oerrno;
801159d09a2SMark Phalan 	  (void) snprintf(portbuf, sizeof (portbuf), "%d", ntohs(addr.sin_port));
802159d09a2SMark Phalan 	  krb5_klog_syslog(LOG_ERR, gettext("cannot bind simple chpw socket: %s"),
803159d09a2SMark Phalan 			   e_txt);
804159d09a2SMark Phalan 	  if(oerrno == EADDRINUSE) {
805159d09a2SMark Phalan 	       char *w = strrchr(whoami, '/');
806159d09a2SMark Phalan 	       if (w) {
807159d09a2SMark Phalan 		    w++;
808159d09a2SMark Phalan 	       }
809159d09a2SMark Phalan 	       else {
810159d09a2SMark Phalan 		    w = whoami;
811159d09a2SMark Phalan 	       }
812159d09a2SMark Phalan 	       fprintf(stderr, gettext(
813159d09a2SMark Phalan "This probably means that another %s process is already\n"
814159d09a2SMark Phalan "running, or that another program is using the server port (number %d).\n"
815159d09a2SMark Phalan "If another %s is already running, you should kill it before\n"
816159d09a2SMark Phalan "restarting the server.\n"),
817159d09a2SMark Phalan 		       w, ntohs(addr.sin_port), w);
818159d09a2SMark Phalan  	  }
8197c478bd9Sstevel@tonic-gate  	  krb5_klog_close(context);
8207c478bd9Sstevel@tonic-gate 	  exit(1);
8217c478bd9Sstevel@tonic-gate      }
822159d09a2SMark Phalan 
8237c478bd9Sstevel@tonic-gate      transp = svc_tli_create(fd, nconf, NULL, 0, 0);
8247c478bd9Sstevel@tonic-gate      (void) t_free((char *) tres, T_BIND);
825159d09a2SMark Phalan      (void) endnetconfig(handlep);
8267c478bd9Sstevel@tonic-gate      if(transp == NULL) {
827159d09a2SMark Phalan 	  fprintf(stderr, gettext("%s: Cannot create RPC service.\n"), whoami);
8287c478bd9Sstevel@tonic-gate 	  krb5_klog_syslog(LOG_ERR, gettext("Cannot create RPC service: %m"));
829159d09a2SMark Phalan 	  kadm5_destroy(global_server_handle);
8307c478bd9Sstevel@tonic-gate 	  krb5_klog_close(context);
8317c478bd9Sstevel@tonic-gate 	  exit(1);
8327c478bd9Sstevel@tonic-gate      }
8337c478bd9Sstevel@tonic-gate      if(!svc_register(transp, KADM, KADMVERS, kadm_1, 0)) {
834159d09a2SMark Phalan 	  fprintf(stderr, gettext("%s: Cannot register RPC service.\n"), whoami);
835159d09a2SMark Phalan 	  krb5_klog_syslog(LOG_ERR, gettext("Cannot register RPC service, failing."));
836159d09a2SMark Phalan 	  kadm5_destroy(global_server_handle);
8377c478bd9Sstevel@tonic-gate 	  krb5_klog_close(context);
8387c478bd9Sstevel@tonic-gate 	  exit(1);
8397c478bd9Sstevel@tonic-gate      }
8407c478bd9Sstevel@tonic-gate 
8417c478bd9Sstevel@tonic-gate 
842a0709436Smp153739 	/* Solaris Kerberos:
843a0709436Smp153739 	 * The only service principals which matter here are
844a0709436Smp153739 	 *  -> names[0].name (kadmin/<fqdn>)
845a0709436Smp153739 	 *  -> names[1].name (changepw/<fqdn>)
846a0709436Smp153739 	 * KADM5_ADMIN_SERVICE_P, KADM5_CHANGEPW_SERVICE_P,
847a0709436Smp153739 	 * OVSEC_KADM_ADMIN_SERVICE_P, OVSEC_KADM_CHANGEPW_SERVICE_P
848a0709436Smp153739 	 * are all legacy service princs and calls to rpc_gss_set_svc_name()
849a0709436Smp153739 	 * using these principals will always fail as they are not host
850a0709436Smp153739 	 * based principals.
851a0709436Smp153739 	 */
852a0709436Smp153739 
8537c64d375Smp153739 	if (ret = kadm5_get_adm_host_srv_name(context, params.realm,
8547c64d375Smp153739 	    &names[0].name)) {
8557c478bd9Sstevel@tonic-gate 		krb5_klog_syslog(LOG_ERR,
8567c64d375Smp153739 		    gettext("Cannot get host based service name for admin "
8577c64d375Smp153739 		    "principal in realm %s: %s"), params.realm,
8587c64d375Smp153739 		    error_message(ret));
8597c478bd9Sstevel@tonic-gate 		fprintf(stderr,
8607c64d375Smp153739 		    gettext("%s: Cannot get host based service name for admin "
8617c64d375Smp153739 		    "principal in realm %s: %s\n"), whoami, params.realm,
8627c64d375Smp153739 		    error_message(ret));
8637c478bd9Sstevel@tonic-gate 		krb5_klog_close(context);
8647c478bd9Sstevel@tonic-gate 		exit(1);
8657c478bd9Sstevel@tonic-gate 	}
8667c478bd9Sstevel@tonic-gate 
8677c64d375Smp153739 	if (ret = kadm5_get_cpw_host_srv_name(context, params.realm,
8687c64d375Smp153739 	    &names[1].name)) {
8697c64d375Smp153739 		krb5_klog_syslog(LOG_ERR,
8707c64d375Smp153739 		    gettext("Cannot get host based service name for changepw "
8717c64d375Smp153739 		    "principal in realm %s: %s"), params.realm,
8727c64d375Smp153739 		    error_message(ret));
8737c64d375Smp153739 		fprintf(stderr,
8747c64d375Smp153739 		    gettext("%s: Cannot get host based service name for "
8757c64d375Smp153739 		    "changepw principal in realm %s: %s\n"), whoami, params.realm,
8767c64d375Smp153739 		    error_message(ret));
8777c64d375Smp153739 		krb5_klog_close(context);
8787c64d375Smp153739 		exit(1);
8797c64d375Smp153739 	}
8807c64d375Smp153739 	names[2].name = KADM5_ADMIN_SERVICE_P;
8817c64d375Smp153739 	names[3].name = KADM5_CHANGEPW_SERVICE_P;
8827c64d375Smp153739 	names[4].name = OVSEC_KADM_ADMIN_SERVICE_P;
8837c64d375Smp153739 	names[5].name = OVSEC_KADM_CHANGEPW_SERVICE_P;
8847c478bd9Sstevel@tonic-gate 
885159d09a2SMark Phalan 	if (names[0].name == NULL || names[1].name == NULL ||
886159d09a2SMark Phalan 	    names[2].name == NULL || names[3].name == NULL ||
887159d09a2SMark Phalan 	    names[4].name == NULL || names[5].name == NULL) {
888159d09a2SMark Phalan 		krb5_klog_syslog(LOG_ERR,
889159d09a2SMark Phalan 		    gettext("Cannot initialize GSS-API authentication, "
890159d09a2SMark Phalan 			"failing."));
891159d09a2SMark Phalan 		fprintf(stderr,
892159d09a2SMark Phalan 		    gettext("%s: Cannot initialize "
893159d09a2SMark Phalan 			"GSS-API authentication.\n"),
894159d09a2SMark Phalan 		    whoami);
895159d09a2SMark Phalan 		krb5_klog_close(context);
896159d09a2SMark Phalan 		exit(1);
897159d09a2SMark Phalan 	}
898159d09a2SMark Phalan 
8997c478bd9Sstevel@tonic-gate      /*
900159d09a2SMark Phalan       * Go through some contortions to point gssapi at a kdb keytab.
901159d09a2SMark Phalan       * This prevents kadmind from needing to use an actual file-based
902159d09a2SMark Phalan       * keytab.
903159d09a2SMark Phalan       */
904159d09a2SMark Phalan      /* XXX extract kadm5's krb5_context */
905159d09a2SMark Phalan      hctx = ((kadm5_server_handle_t)global_server_handle)->context;
906159d09a2SMark Phalan      /* Set ktkdb's internal krb5_context. */
907159d09a2SMark Phalan      ret = krb5_ktkdb_set_context(hctx);
908159d09a2SMark Phalan      if (ret) {
909159d09a2SMark Phalan 	  krb5_klog_syslog(LOG_ERR, "Can't set kdb keytab's internal context.");
910159d09a2SMark Phalan 	  goto kterr;
911159d09a2SMark Phalan      }
912159d09a2SMark Phalan      /* Solaris Kerberos */
913159d09a2SMark Phalan      ret = krb5_db_set_mkey(hctx, &((kadm5_server_handle_t)global_server_handle)->master_keyblock);
914159d09a2SMark Phalan      if (ret) {
915159d09a2SMark Phalan 	  krb5_klog_syslog(LOG_ERR, "Can't set master key for kdb keytab.");
916159d09a2SMark Phalan 	  goto kterr;
917159d09a2SMark Phalan      }
918159d09a2SMark Phalan      ret = krb5_kt_register(context, &krb5_kt_kdb_ops);
919159d09a2SMark Phalan      if (ret) {
920159d09a2SMark Phalan 	  krb5_klog_syslog(LOG_ERR, "Can't register kdb keytab.");
921159d09a2SMark Phalan 	  goto kterr;
922159d09a2SMark Phalan      }
923159d09a2SMark Phalan      /* Tell gssapi about the kdb keytab. */
924159d09a2SMark Phalan      ret = krb5_gss_register_acceptor_identity("KDB:");
925159d09a2SMark Phalan      if (ret) {
926159d09a2SMark Phalan 	  krb5_klog_syslog(LOG_ERR, "Can't register acceptor keytab.");
927159d09a2SMark Phalan 	  goto kterr;
928159d09a2SMark Phalan      }
929159d09a2SMark Phalan kterr:
930159d09a2SMark Phalan      if (ret) {
931159d09a2SMark Phalan 	  krb5_klog_syslog(LOG_ERR, "%s", krb5_get_error_message (context, ret));
932159d09a2SMark Phalan 	  fprintf(stderr, "%s: Can't set up keytab for RPC.\n", whoami);
933159d09a2SMark Phalan 	  kadm5_destroy(global_server_handle);
934159d09a2SMark Phalan 	  krb5_klog_close(context);
935159d09a2SMark Phalan 	  exit(1);
936159d09a2SMark Phalan      }
937159d09a2SMark Phalan 
938159d09a2SMark Phalan      /*
939159d09a2SMark Phalan       * Try to acquire creds for the old OV services as well as the
940159d09a2SMark Phalan       * new names, but if that fails just fall back on the new names.
9417c478bd9Sstevel@tonic-gate       */
9427c478bd9Sstevel@tonic-gate 
9437c478bd9Sstevel@tonic-gate 	if (rpc_gss_set_svc_name(names[5].name,
9447c478bd9Sstevel@tonic-gate 				"kerberos_v5", 0, KADM, KADMVERS) &&
9457c478bd9Sstevel@tonic-gate 	    rpc_gss_set_svc_name(names[4].name,
9467c478bd9Sstevel@tonic-gate 				"kerberos_v5", 0, KADM, KADMVERS))
9477c478bd9Sstevel@tonic-gate 		oldnames++;
9487c478bd9Sstevel@tonic-gate 	if (rpc_gss_set_svc_name(names[3].name,
9497c478bd9Sstevel@tonic-gate 				"kerberos_v5", 0, KADM, KADMVERS))
9507c478bd9Sstevel@tonic-gate 		oldnames++;
9517c478bd9Sstevel@tonic-gate 	if (rpc_gss_set_svc_name(names[2].name,
9527c478bd9Sstevel@tonic-gate 				"kerberos_v5", 0, KADM, KADMVERS))
9537c478bd9Sstevel@tonic-gate 		oldnames++;
954a0709436Smp153739 
955a0709436Smp153739     /* If rpc_gss_set_svc_name() fails for either kadmin/<fqdn> or
956a0709436Smp153739      * for changepw/<fqdn> then try to determine if this is caused
957a0709436Smp153739      * by a missing keytab file or entry. If so, log it and continue.
958a0709436Smp153739      */
9597c478bd9Sstevel@tonic-gate 	if (rpc_gss_set_svc_name(names[0].name,
9607c478bd9Sstevel@tonic-gate 				"kerberos_v5", 0, KADM, KADMVERS))
9617c478bd9Sstevel@tonic-gate 		oldnames++;
962159d09a2SMark Phalan 
9637c478bd9Sstevel@tonic-gate 	if (rpc_gss_set_svc_name(names[1].name,
9647c478bd9Sstevel@tonic-gate 				"kerberos_v5", 0, KADM, KADMVERS))
9657c478bd9Sstevel@tonic-gate 		oldnames++;
9667c478bd9Sstevel@tonic-gate 
9677c478bd9Sstevel@tonic-gate 	retdn = getdomnames(context, params.realm, &dnames);
9687c478bd9Sstevel@tonic-gate 	if (retdn == 0 && dnames) {
9697c478bd9Sstevel@tonic-gate 		/*
9707c478bd9Sstevel@tonic-gate 		 * Multi-homed KDCs sometimes may need to set svc names
9717c478bd9Sstevel@tonic-gate 		 * for multiple net interfaces so we set them for
9727c478bd9Sstevel@tonic-gate 		 * all interfaces just in case.
9737c478bd9Sstevel@tonic-gate 		 */
9747c478bd9Sstevel@tonic-gate 		set_svc_domnames(KADM5_ADMIN_HOST_SERVICE,
9757c478bd9Sstevel@tonic-gate 				dnames, KADM, KADMVERS);
9767c478bd9Sstevel@tonic-gate 		set_svc_domnames(KADM5_CHANGEPW_HOST_SERVICE,
9777c478bd9Sstevel@tonic-gate 				dnames, KADM, KADMVERS);
9787c478bd9Sstevel@tonic-gate 	}
9797c478bd9Sstevel@tonic-gate 
9807c478bd9Sstevel@tonic-gate      /* if set_names succeeded, this will too */
9817c478bd9Sstevel@tonic-gate      in_buf.value = names[1].name;
9827c478bd9Sstevel@tonic-gate      in_buf.length = strlen(names[1].name) + 1;
9837c478bd9Sstevel@tonic-gate      (void) gss_import_name(&OMret, &in_buf, (gss_OID) nt_krb5_name_oid,
9847c478bd9Sstevel@tonic-gate 			    &gss_changepw_name);
9857c478bd9Sstevel@tonic-gate      if (oldnames) {
9867c478bd9Sstevel@tonic-gate 	  in_buf.value = names[3].name;
9877c478bd9Sstevel@tonic-gate 	  in_buf.length = strlen(names[3].name) + 1;
988159d09a2SMark Phalan 	  (void) gss_import_name(&OMret, &in_buf, (gss_OID) nt_krb5_name_oid,
9897c478bd9Sstevel@tonic-gate 				 &gss_oldchangepw_name);
9907c478bd9Sstevel@tonic-gate      }
991159d09a2SMark Phalan 
992159d09a2SMark Phalan      if ((ret = kadm5int_acl_init(context, 0, params.acl_file))) {
993159d09a2SMark Phalan 	  errmsg = krb5_get_error_message (context, ret);
9947c478bd9Sstevel@tonic-gate 	  krb5_klog_syslog(LOG_ERR, gettext("Cannot initialize acl file: %s"),
995159d09a2SMark Phalan 		 errmsg);
9967c478bd9Sstevel@tonic-gate 	  fprintf(stderr, gettext("%s: Cannot initialize acl file: %s\n"),
997159d09a2SMark Phalan 		  whoami, errmsg);
998159d09a2SMark Phalan 	  kadm5_destroy(global_server_handle);
9997c478bd9Sstevel@tonic-gate 	  krb5_klog_close(context);
10007c478bd9Sstevel@tonic-gate 	  exit(1);
10017c478bd9Sstevel@tonic-gate      }
10027c64d375Smp153739 
10037c64d375Smp153739 	/*
10047c64d375Smp153739 	 * Solaris Kerberos:
1005d15b0992SMark Phalan 	 * Warn if the acl file contains an entry for a principal matching the
1006d15b0992SMark Phalan 	 * default (unconfigured) acl rule.
10077c64d375Smp153739 	 */
1008d15b0992SMark Phalan 	gssbuf.length = strlen("x/admin@___default_realm___");
1009d15b0992SMark Phalan 	gssbuf.value = "x/admin@___default_realm___";
1010d15b0992SMark Phalan 	/* Use any value as the first component - 'x' in this case */
1011d15b0992SMark Phalan 	if (gss_import_name(&minor_status, &gssbuf, GSS_C_NT_USER_NAME, &name)
1012d15b0992SMark Phalan 	    == GSS_S_COMPLETE) {
1013d15b0992SMark Phalan 		if (kadm5int_acl_check(context, name, ACL_MODIFY, NULL, NULL)) {
10147c64d375Smp153739 			krb5_klog_syslog(LOG_WARNING,
1015d15b0992SMark Phalan 			    gettext("acls may not be properly configured: "
1016d15b0992SMark Phalan 			    "found an acl matching \"___default_realm___\" in "
1017d15b0992SMark Phalan 			    " %s"), params.acl_file);
10187c64d375Smp153739 			(void) fprintf(stderr, gettext("%s: Warning: "
1019d15b0992SMark Phalan 			    "acls may not be properly configured: found an acl "
1020d15b0992SMark Phalan 			    "matching \"___default_realm___\" in %s\n"),
1021d15b0992SMark Phalan 			    whoami, params.acl_file);
10227c64d375Smp153739 		}
10237c64d375Smp153739 		(void) gss_release_name(&minor_status, &name);
10247c64d375Smp153739 	}
10257c64d375Smp153739 	gssbuf.value = NULL;
10267c64d375Smp153739 	gssbuf.length = 0;
10277c64d375Smp153739 
10287c64d375Smp153739 	/*
10297c64d375Smp153739 	 * Solaris Kerberos:
10307c64d375Smp153739 	 * List the logs (FILE, STDERR, etc) which are currently being
10317c64d375Smp153739 	 * logged to and print to stderr. Useful when trying to
10327c64d375Smp153739 	 * track down a failure via SMF.
10337c64d375Smp153739 	 */
10347c64d375Smp153739 	if (ret = krb5_klog_list_logs(whoami)) {
10357c64d375Smp153739 		fprintf(stderr, gettext("%s: %s while listing logs\n"),
10367c64d375Smp153739 		    whoami, error_message(ret));
10377c64d375Smp153739 		krb5_klog_syslog(LOG_ERR, gettext("%s while listing logs"),
10387c64d375Smp153739 		    error_message(ret));
10397c64d375Smp153739 	}
10407c64d375Smp153739 
10413441f6a1Ssemery      if (!nofork && (ret = daemon(0, 0))) {
10423441f6a1Ssemery 	  ret = errno;
1043159d09a2SMark Phalan 	  errmsg = krb5_get_error_message (context, ret);
10443441f6a1Ssemery 	  krb5_klog_syslog(LOG_ERR,
1045159d09a2SMark Phalan 		    gettext("Cannot detach from tty: %s"), errmsg);
10463441f6a1Ssemery 	  fprintf(stderr, gettext("%s: Cannot detach from tty: %s\n"),
1047159d09a2SMark Phalan 		  whoami, errmsg);
1048159d09a2SMark Phalan 	  kadm5_destroy(global_server_handle);
10493441f6a1Ssemery 	  krb5_klog_close(context);
10503441f6a1Ssemery 	  exit(1);
10513441f6a1Ssemery      }
10523441f6a1Ssemery 
1053159d09a2SMark Phalan     /* SUNW14resync */
1054159d09a2SMark Phalan #if 0
1055159d09a2SMark Phalan      krb5_klog_syslog(LOG_INFO, "Seeding random number generator");
1056159d09a2SMark Phalan      ret = krb5_c_random_os_entropy(context, 1, NULL);
1057159d09a2SMark Phalan      if (ret) {
1058159d09a2SMark Phalan 	  krb5_klog_syslog(LOG_ERR, "Error getting random seed: %s, aborting",
1059159d09a2SMark Phalan 			   krb5_get_error_message(context, ret));
1060159d09a2SMark Phalan 	  kadm5_destroy(global_server_handle);
1061159d09a2SMark Phalan 	  krb5_klog_close(context);
1062159d09a2SMark Phalan 	  exit(1);
106354925bf6Swillf      }
1064159d09a2SMark Phalan #endif
1065159d09a2SMark Phalan 
106654925bf6Swillf 
10677c478bd9Sstevel@tonic-gate 	handle = global_server_handle;
10687c478bd9Sstevel@tonic-gate 	ctx = handle->context;
106954925bf6Swillf 	if (params.iprop_enabled == TRUE) {
107054925bf6Swillf 		if (ret = krb5_db_supports_iprop(ctx, &iprop_supported)) {
107154925bf6Swillf 			fprintf(stderr,
107254925bf6Swillf 				gettext("%s: %s while trying to determine if KDB "
107354925bf6Swillf 				"plugin supports iprop\n"), whoami,
107454925bf6Swillf 				error_message(ret));
107554925bf6Swillf 			krb5_klog_syslog(LOG_ERR,
107654925bf6Swillf 				gettext("%s while trying to determine if KDB "
107754925bf6Swillf 				"plugin supports iprop"), error_message(ret));
107854925bf6Swillf 			krb5_klog_close(ctx);
107954925bf6Swillf 			exit(1);
108054925bf6Swillf 		}
108154925bf6Swillf 
108254925bf6Swillf 		if (!iprop_supported) {
108354925bf6Swillf 			fprintf(stderr,
108454925bf6Swillf 				gettext("%s: Warning, current KDB "
108554925bf6Swillf 				"plugin does not support iprop, continuing "
108654925bf6Swillf 				"with iprop disabled\n"), whoami);
108754925bf6Swillf 			krb5_klog_syslog(LOG_WARNING,
108878894ffcSmp153739 				gettext("Warning, current KDB "
108954925bf6Swillf 				"plugin does not support iprop, continuing "
109054925bf6Swillf 				"with iprop disabled"));
109154925bf6Swillf 
109254925bf6Swillf 			ulog_set_role(ctx, IPROP_NULL);
109354925bf6Swillf 		} else
10947c478bd9Sstevel@tonic-gate 			ulog_set_role(ctx, IPROP_MASTER);
109554925bf6Swillf 	} else
10967c478bd9Sstevel@tonic-gate 		ulog_set_role(ctx, IPROP_NULL);
10977c478bd9Sstevel@tonic-gate 
10987c478bd9Sstevel@tonic-gate 	log_ctx = ctx->kdblog_context;
10997c478bd9Sstevel@tonic-gate 
11007c478bd9Sstevel@tonic-gate 	if (log_ctx && (log_ctx->iproprole == IPROP_MASTER)) {
11017c478bd9Sstevel@tonic-gate 		/*
11027c478bd9Sstevel@tonic-gate 		 * IProp is enabled, so let's map in the update log
11037c478bd9Sstevel@tonic-gate 		 * and setup the service.
11047c478bd9Sstevel@tonic-gate 		 */
11057c478bd9Sstevel@tonic-gate 		if (ret = ulog_map(ctx, &params, FKADMIND)) {
11067c478bd9Sstevel@tonic-gate 			fprintf(stderr,
11077c478bd9Sstevel@tonic-gate 				gettext("%s: %s while mapping update log "
11087c478bd9Sstevel@tonic-gate 				"(`%s.ulog')\n"), whoami, error_message(ret),
11097c478bd9Sstevel@tonic-gate 				params.dbname);
11107c478bd9Sstevel@tonic-gate 			krb5_klog_syslog(LOG_ERR,
11117c478bd9Sstevel@tonic-gate 				gettext("%s while mapping update log "
11127c478bd9Sstevel@tonic-gate 				"(`%s.ulog')"), error_message(ret),
11137c478bd9Sstevel@tonic-gate 				params.dbname);
11147c478bd9Sstevel@tonic-gate 			krb5_klog_close(ctx);
11157c478bd9Sstevel@tonic-gate 			exit(1);
11167c478bd9Sstevel@tonic-gate 		}
11177c478bd9Sstevel@tonic-gate 
11187c478bd9Sstevel@tonic-gate 
11197c478bd9Sstevel@tonic-gate 		if (nofork)
11207c478bd9Sstevel@tonic-gate 			fprintf(stderr,
11217c478bd9Sstevel@tonic-gate 				"%s: create IPROP svc (PROG=%d, VERS=%d)\n",
11227c478bd9Sstevel@tonic-gate 				whoami, KRB5_IPROP_PROG, KRB5_IPROP_VERS);
11237c478bd9Sstevel@tonic-gate 
11247c478bd9Sstevel@tonic-gate 		if (!svc_create(krb5_iprop_prog_1,
11257c478bd9Sstevel@tonic-gate 				KRB5_IPROP_PROG, KRB5_IPROP_VERS,
11267c478bd9Sstevel@tonic-gate 				"circuit_v")) {
11277c478bd9Sstevel@tonic-gate 			fprintf(stderr,
11287c478bd9Sstevel@tonic-gate     gettext("%s: Cannot create IProp RPC service (PROG=%d, VERS=%d)\n"),
11297c478bd9Sstevel@tonic-gate 				whoami,
11307c478bd9Sstevel@tonic-gate 				KRB5_IPROP_PROG, KRB5_IPROP_VERS);
11317c478bd9Sstevel@tonic-gate 			krb5_klog_syslog(LOG_ERR,
11327c478bd9Sstevel@tonic-gate     gettext("Cannot create IProp RPC service (PROG=%d, VERS=%d), failing."),
11337c478bd9Sstevel@tonic-gate 					KRB5_IPROP_PROG, KRB5_IPROP_VERS);
11347c478bd9Sstevel@tonic-gate 			krb5_klog_close(ctx);
11357c478bd9Sstevel@tonic-gate 			exit(1);
11367c478bd9Sstevel@tonic-gate 		}
11377c478bd9Sstevel@tonic-gate 
11387c478bd9Sstevel@tonic-gate 		if (ret = kiprop_get_adm_host_srv_name(ctx,
11397c478bd9Sstevel@tonic-gate 							params.realm,
11407c478bd9Sstevel@tonic-gate 							&kiprop_name)) {
11417c478bd9Sstevel@tonic-gate 			krb5_klog_syslog(LOG_ERR,
11427c478bd9Sstevel@tonic-gate 			gettext("%s while getting IProp svc name, failing"),
11437c478bd9Sstevel@tonic-gate 					error_message(ret));
11447c478bd9Sstevel@tonic-gate 			fprintf(stderr,
11457c478bd9Sstevel@tonic-gate 		gettext("%s: %s while getting IProp svc name, failing\n"),
11467c478bd9Sstevel@tonic-gate 				whoami, error_message(ret));
11477c478bd9Sstevel@tonic-gate 			krb5_klog_close(ctx);
11487c478bd9Sstevel@tonic-gate 			exit(1);
11497c478bd9Sstevel@tonic-gate 		}
11507c478bd9Sstevel@tonic-gate 
11517c478bd9Sstevel@tonic-gate 		if (!rpc_gss_set_svc_name(kiprop_name, "kerberos_v5", 0,
11527c478bd9Sstevel@tonic-gate 					KRB5_IPROP_PROG, KRB5_IPROP_VERS)) {
11537c478bd9Sstevel@tonic-gate 			rpc_gss_error_t err;
11547c478bd9Sstevel@tonic-gate 			(void) rpc_gss_get_error(&err);
11557c478bd9Sstevel@tonic-gate 
11567c478bd9Sstevel@tonic-gate 			krb5_klog_syslog(LOG_ERR,
11577c478bd9Sstevel@tonic-gate     gettext("Unable to set RPCSEC_GSS service name (`%s'), failing."),
11587c478bd9Sstevel@tonic-gate 					kiprop_name ? kiprop_name : "<null>");
11597c478bd9Sstevel@tonic-gate 			fprintf(stderr,
11607c478bd9Sstevel@tonic-gate     gettext("%s: Unable to set RPCSEC_GSS service name (`%s'), failing.\n"),
11617c478bd9Sstevel@tonic-gate 				whoami,
11627c478bd9Sstevel@tonic-gate 				kiprop_name ? kiprop_name : "<null>");
11637c478bd9Sstevel@tonic-gate 
11647c478bd9Sstevel@tonic-gate 			if (nofork) {
11657c478bd9Sstevel@tonic-gate 				fprintf(stderr,
11667c478bd9Sstevel@tonic-gate 			"%s: set svc name (rpcsec err=%d, sys err=%d)\n",
11677c478bd9Sstevel@tonic-gate 					whoami,
11687c478bd9Sstevel@tonic-gate 					err.rpc_gss_error,
11697c478bd9Sstevel@tonic-gate 					err.system_error);
11707c478bd9Sstevel@tonic-gate 			}
11717c478bd9Sstevel@tonic-gate 
11727c478bd9Sstevel@tonic-gate 			exit(1);
11737c478bd9Sstevel@tonic-gate 		}
11747c478bd9Sstevel@tonic-gate 		free(kiprop_name);
11757c478bd9Sstevel@tonic-gate 
11767c478bd9Sstevel@tonic-gate 		if (retdn == 0 && dnames) {
11777c478bd9Sstevel@tonic-gate 			set_svc_domnames(KADM5_KIPROP_HOST_SERVICE,
11787c478bd9Sstevel@tonic-gate 					dnames,
11797c478bd9Sstevel@tonic-gate 					KRB5_IPROP_PROG, KRB5_IPROP_VERS);
11807c478bd9Sstevel@tonic-gate 		}
11817c478bd9Sstevel@tonic-gate 
11827c8de920Smp153739 	} else {
11837c8de920Smp153739 		if (!oldnames) {
11847c8de920Smp153739 		/* rpc_gss_set_svc_name failed for both kadmin/<fqdn> and
11857c8de920Smp153739 		 * changepw/<fqdn>.
11867c8de920Smp153739 		 */
11877c8de920Smp153739 			krb5_klog_syslog(LOG_ERR,
11887c8de920Smp153739 					gettext("Unable to set RPCSEC_GSS service names "
11897c8de920Smp153739 						"('%s, %s')"),
11907c8de920Smp153739 					names[0].name, names[1].name);
11917c8de920Smp153739 			fprintf(stderr,
11927c8de920Smp153739 					gettext("%s: Unable to set RPCSEC_GSS service names "
11937c8de920Smp153739 						"('%s, %s')\n"),
11947c8de920Smp153739 					whoami,
11957c8de920Smp153739 					names[0].name, names[1].name);
11967c8de920Smp153739 			krb5_klog_close(context);
11977c8de920Smp153739 			exit(1);
11987c8de920Smp153739 		}
11997c478bd9Sstevel@tonic-gate 	}
12007c478bd9Sstevel@tonic-gate 
12017c478bd9Sstevel@tonic-gate 	if (dnames)
12027c478bd9Sstevel@tonic-gate 		freedomnames(dnames);
12037c478bd9Sstevel@tonic-gate 
12047c478bd9Sstevel@tonic-gate 	setup_signal_handlers(log_ctx->iproprole);
12057c478bd9Sstevel@tonic-gate 	krb5_klog_syslog(LOG_INFO, gettext("starting"));
12067c478bd9Sstevel@tonic-gate 	if (nofork)
12077c478bd9Sstevel@tonic-gate 		fprintf(stderr, "%s: starting...\n", whoami);
12087c478bd9Sstevel@tonic-gate 
12097c478bd9Sstevel@tonic-gate 
12107c478bd9Sstevel@tonic-gate 	/*
12117c478bd9Sstevel@tonic-gate 	 * We now call our own customized async event processing
12127c478bd9Sstevel@tonic-gate 	 * function kadm_svc_run(), as opposed to svc_run() earlier,
12137c478bd9Sstevel@tonic-gate 	 * since this enables kadmind to also listen-to/process
12147c478bd9Sstevel@tonic-gate 	 * non-RPCSEC_GSS based change-pwd requests apart from the
12157c478bd9Sstevel@tonic-gate 	 * regular, RPCSEC_GSS kpasswd requests from Solaris Krb5 clients.
12167c478bd9Sstevel@tonic-gate 	 */
12177c478bd9Sstevel@tonic-gate 	kadm_svc_run();
12187c478bd9Sstevel@tonic-gate 
12197c478bd9Sstevel@tonic-gate 	krb5_klog_syslog(LOG_INFO, gettext("finished, exiting"));
12207c478bd9Sstevel@tonic-gate 	kadm5_destroy(global_server_handle);
12217c478bd9Sstevel@tonic-gate 	t_close(fd);
12227c478bd9Sstevel@tonic-gate 	krb5_klog_close(context);
12237c478bd9Sstevel@tonic-gate 	exit(0);
12247c478bd9Sstevel@tonic-gate }
12257c478bd9Sstevel@tonic-gate 
12267c478bd9Sstevel@tonic-gate /*
12277c478bd9Sstevel@tonic-gate  * Function: kadm_svc_run
12287c478bd9Sstevel@tonic-gate  *
12297c478bd9Sstevel@tonic-gate  * Purpose: modified version of sunrpc svc_run.
12307c478bd9Sstevel@tonic-gate  *	    which closes the database every TIMEOUT seconds.
12317c478bd9Sstevel@tonic-gate  *
12327c478bd9Sstevel@tonic-gate  * Arguments:
12337c478bd9Sstevel@tonic-gate  * Requires:
12347c478bd9Sstevel@tonic-gate  * Effects:
12357c478bd9Sstevel@tonic-gate  * Modifies:
12367c478bd9Sstevel@tonic-gate  */
1237159d09a2SMark Phalan 
kadm_svc_run(void)1238159d09a2SMark Phalan void kadm_svc_run(void)
12397c478bd9Sstevel@tonic-gate {
12407c478bd9Sstevel@tonic-gate      struct pollfd	*rfd = 0;
12417c478bd9Sstevel@tonic-gate      struct	timeval	    timeout;
12427c478bd9Sstevel@tonic-gate      int pollret;
12437c478bd9Sstevel@tonic-gate      int nfds = 0;
12447c478bd9Sstevel@tonic-gate      int i;
12457c478bd9Sstevel@tonic-gate 
12467c478bd9Sstevel@tonic-gate      while(signal_request_exit == 0) {
12477c478bd9Sstevel@tonic-gate 		timeout.tv_sec = TIMEOUT;
12487c478bd9Sstevel@tonic-gate 		timeout.tv_usec = 0;
12497c478bd9Sstevel@tonic-gate 
12507c478bd9Sstevel@tonic-gate 		if (nfds != svc_max_pollfd) {
12517c478bd9Sstevel@tonic-gate 			rfd = realloc(rfd, sizeof (pollfd_t) * svc_max_pollfd);
12527c478bd9Sstevel@tonic-gate 			nfds = svc_max_pollfd;
12537c478bd9Sstevel@tonic-gate 		}
12547c478bd9Sstevel@tonic-gate 
12557c478bd9Sstevel@tonic-gate 		(void) memcpy(rfd, svc_pollfd,
12567c478bd9Sstevel@tonic-gate 			sizeof (pollfd_t) * svc_max_pollfd);
12577c478bd9Sstevel@tonic-gate 
12587c478bd9Sstevel@tonic-gate 		for (i = 0; i < nfds; i++) {
12597c478bd9Sstevel@tonic-gate 			if (rfd[i].fd == -1) {
12607c478bd9Sstevel@tonic-gate 				rfd[i].fd = schpw;
12617c478bd9Sstevel@tonic-gate 				rfd[i].events = POLLIN;
12627c478bd9Sstevel@tonic-gate 				break;
12637c478bd9Sstevel@tonic-gate 			}
12647c478bd9Sstevel@tonic-gate 		}
12657c478bd9Sstevel@tonic-gate 
12667c478bd9Sstevel@tonic-gate 		switch(pollret = poll(rfd, nfds,
12677c478bd9Sstevel@tonic-gate 				__rpc_timeval_to_msec(&timeout))) {
12687c478bd9Sstevel@tonic-gate 		case -1:
12697c478bd9Sstevel@tonic-gate 			if(errno == EINTR)
12707c478bd9Sstevel@tonic-gate 				continue;
12717c478bd9Sstevel@tonic-gate 			perror("poll");
12727c478bd9Sstevel@tonic-gate 			return;
12737c478bd9Sstevel@tonic-gate 		case 0:
12747c478bd9Sstevel@tonic-gate 			continue;
12757c478bd9Sstevel@tonic-gate 		default:
12767c478bd9Sstevel@tonic-gate 			for (i = 0; i < nfds; i++) {
12777c478bd9Sstevel@tonic-gate 				if (rfd[i].revents & POLLIN) {
12787c478bd9Sstevel@tonic-gate 					if (rfd[i].fd == schpw)
12797c478bd9Sstevel@tonic-gate 						handle_chpw(context, schpw,
12807c478bd9Sstevel@tonic-gate 							global_server_handle,
12817c478bd9Sstevel@tonic-gate 							&chgpw_params);
12827c478bd9Sstevel@tonic-gate 					else
12837c478bd9Sstevel@tonic-gate 						svc_getreq_poll(rfd, pollret);
12847c478bd9Sstevel@tonic-gate 					break;
12857c478bd9Sstevel@tonic-gate 				} else {
12867c478bd9Sstevel@tonic-gate 					if (i == (nfds - 1))
12877c478bd9Sstevel@tonic-gate 						perror("poll");
12887c478bd9Sstevel@tonic-gate 				}
12897c478bd9Sstevel@tonic-gate 			}
12907c478bd9Sstevel@tonic-gate 			break;
12917c478bd9Sstevel@tonic-gate 		}
12927c478bd9Sstevel@tonic-gate 	}
12937c478bd9Sstevel@tonic-gate }
12947c478bd9Sstevel@tonic-gate 
12957c478bd9Sstevel@tonic-gate 
12967c478bd9Sstevel@tonic-gate /*
12977c478bd9Sstevel@tonic-gate  * Function: setup_signal_handlers
12987c478bd9Sstevel@tonic-gate  *
1299*4e2a441bSPeter Shoults  * Purpose: Setup signal handling functions with either
1300*4e2a441bSPeter Shoults  * System V's signal() or POSIX_SIGNALS.
13017c478bd9Sstevel@tonic-gate  */
setup_signal_handlers(iprop_role iproprole)13027c478bd9Sstevel@tonic-gate void setup_signal_handlers(iprop_role iproprole) {
1303*4e2a441bSPeter Shoults #ifdef POSIX_SIGNALS
1304*4e2a441bSPeter Shoults 	(void) sigemptyset(&s_action.sa_mask);
1305*4e2a441bSPeter Shoults 	s_action.sa_handler = request_exit;
1306*4e2a441bSPeter Shoults 	(void) sigaction(SIGINT, &s_action, (struct sigaction *) NULL);
1307*4e2a441bSPeter Shoults 	(void) sigaction(SIGTERM, &s_action, (struct sigaction *) NULL);
1308*4e2a441bSPeter Shoults 	(void) sigaction(SIGQUIT, &s_action, (struct sigaction *) NULL);
1309*4e2a441bSPeter Shoults 	s_action.sa_handler = sig_pipe;
1310*4e2a441bSPeter Shoults 	(void) sigaction(SIGPIPE, &s_action, (struct sigaction *) NULL);
1311*4e2a441bSPeter Shoults 
1312*4e2a441bSPeter Shoults 	/*
1313*4e2a441bSPeter Shoults 	 * IProp will fork for a full-resync, we don't want to
1314*4e2a441bSPeter Shoults 	 * wait on it and we don't want the living dead procs either.
1315*4e2a441bSPeter Shoults 	 */
1316*4e2a441bSPeter Shoults 	if (iproprole == IPROP_MASTER) {
1317*4e2a441bSPeter Shoults 		s_action.sa_handler = SIG_IGN;
1318*4e2a441bSPeter Shoults 		(void) sigaction(SIGCHLD, &s_action, (struct sigaction *) NULL);
1319*4e2a441bSPeter Shoults 	}
1320*4e2a441bSPeter Shoults #else
1321159d09a2SMark Phalan      signal(SIGINT, request_exit);
1322159d09a2SMark Phalan      signal(SIGTERM, request_exit);
1323159d09a2SMark Phalan      signal(SIGQUIT, request_exit);
13247c478bd9Sstevel@tonic-gate      signal(SIGPIPE, sig_pipe);
13257c478bd9Sstevel@tonic-gate 
13267c478bd9Sstevel@tonic-gate 	/*
13277c478bd9Sstevel@tonic-gate 	 * IProp will fork for a full-resync, we don't want to
13287c478bd9Sstevel@tonic-gate 	 * wait on it and we don't want the living dead procs either.
13297c478bd9Sstevel@tonic-gate 	 */
13307c478bd9Sstevel@tonic-gate 	if (iproprole == IPROP_MASTER)
13317c478bd9Sstevel@tonic-gate 		(void) signal(SIGCHLD, SIG_IGN);
13327c478bd9Sstevel@tonic-gate 
1333*4e2a441bSPeter Shoults #endif /* POSIX_SIGNALS */
13347c478bd9Sstevel@tonic-gate 	return;
13357c478bd9Sstevel@tonic-gate }
13367c478bd9Sstevel@tonic-gate 
13377c478bd9Sstevel@tonic-gate 
13387c478bd9Sstevel@tonic-gate /*
1339159d09a2SMark Phalan  * Function: request_exit
13407c478bd9Sstevel@tonic-gate  *
13417c478bd9Sstevel@tonic-gate  * Purpose: sets flags saying the server got a signal and that it
1342159d09a2SMark Phalan  *	    should exit when convient.
13437c478bd9Sstevel@tonic-gate  *
1344159d09a2SMark Phalan  * Arguments:
1345159d09a2SMark Phalan  * Requires:
13467c478bd9Sstevel@tonic-gate  * Effects:
1347159d09a2SMark Phalan  *	modifies signal_request_exit which ideally makes the server exit
13487c478bd9Sstevel@tonic-gate  *	at some point.
13497c478bd9Sstevel@tonic-gate  *
13507c478bd9Sstevel@tonic-gate  * Modifies:
1351159d09a2SMark Phalan  *	signal_request_exit
13527c478bd9Sstevel@tonic-gate  */
1353159d09a2SMark Phalan 
request_exit(int signum)1354159d09a2SMark Phalan void request_exit(int signum)
13557c478bd9Sstevel@tonic-gate {
13567c478bd9Sstevel@tonic-gate      krb5_klog_syslog(LOG_NOTICE, gettext("Got signal to request exit"));
13577c478bd9Sstevel@tonic-gate      signal_request_exit = 1;
13587c478bd9Sstevel@tonic-gate      return;
13597c478bd9Sstevel@tonic-gate }
13607c478bd9Sstevel@tonic-gate 
13617c478bd9Sstevel@tonic-gate /*
13627c478bd9Sstevel@tonic-gate  * Function: sig_pipe
13637c478bd9Sstevel@tonic-gate  *
13647c478bd9Sstevel@tonic-gate  * Purpose: SIGPIPE handler
13657c478bd9Sstevel@tonic-gate  *
1366159d09a2SMark Phalan  * Effects: krb5_klog_syslogs a message that a SIGPIPE occurred and returns,
13677c478bd9Sstevel@tonic-gate  * thus causing the read() or write() to fail and, presumable, the RPC
13687c478bd9Sstevel@tonic-gate  * to recover.  Otherwise, the process aborts.
13697c478bd9Sstevel@tonic-gate  */
sig_pipe(int unused)1370159d09a2SMark Phalan void sig_pipe(int unused)
13717c478bd9Sstevel@tonic-gate {
1372*4e2a441bSPeter Shoults #ifndef POSIX_SIGNALS
1373*4e2a441bSPeter Shoults      signal(SIGPIPE, sig_pipe);
1374*4e2a441bSPeter Shoults #endif /* POSIX_SIGNALS */
13757c478bd9Sstevel@tonic-gate      krb5_klog_syslog(LOG_NOTICE, gettext("Warning: Received a SIGPIPE; "
13767c478bd9Sstevel@tonic-gate 	    "probably a client aborted.  Continuing."));
1377159d09a2SMark Phalan      return;
1378a0709436Smp153739 }
1379a0709436Smp153739 
1380