xref: /titanic_50/usr/src/lib/krb5/kadm5/srv/logger.c (revision 159d09a20817016f09b3ea28d1bdada4a336bb91)
17c478bd9Sstevel@tonic-gate /*
27c64d375Smp153739  * Copyright 2008 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  * lib/kadm/logger.c
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * Copyright 1995 by the Massachusetts Institute of Technology.
107c478bd9Sstevel@tonic-gate  * All Rights Reserved.
117c478bd9Sstevel@tonic-gate  *
127c478bd9Sstevel@tonic-gate  * Export of this software from the United States of America may
137c478bd9Sstevel@tonic-gate  *   require a specific license from the United States Government.
147c478bd9Sstevel@tonic-gate  *   It is the responsibility of any person or organization contemplating
157c478bd9Sstevel@tonic-gate  *   export to obtain such a license before exporting.
167c478bd9Sstevel@tonic-gate  *
177c478bd9Sstevel@tonic-gate  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
187c478bd9Sstevel@tonic-gate  * distribute this software and its documentation for any purpose and
197c478bd9Sstevel@tonic-gate  * without fee is hereby granted, provided that the above copyright
207c478bd9Sstevel@tonic-gate  * notice appear in all copies and that both that copyright notice and
217c478bd9Sstevel@tonic-gate  * this permission notice appear in supporting documentation, and that
227c478bd9Sstevel@tonic-gate  * the name of M.I.T. not be used in advertising or publicity pertaining
237c478bd9Sstevel@tonic-gate  * to distribution of the software without specific, written prior
247c478bd9Sstevel@tonic-gate  * permission.  Furthermore if you modify this software you must label
257c478bd9Sstevel@tonic-gate  * your software as modified software and not distribute it in such a
267c478bd9Sstevel@tonic-gate  * fashion that it might be confused with the original M.I.T. software.
277c478bd9Sstevel@tonic-gate  * M.I.T. makes no representations about the suitability of
287c478bd9Sstevel@tonic-gate  * this software for any purpose.  It is provided "as is" without express
297c478bd9Sstevel@tonic-gate  * or implied warranty.
307c478bd9Sstevel@tonic-gate  *
317c478bd9Sstevel@tonic-gate  */
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate /* KADM5 wants non-syslog log files to contain syslog-like entries */
347c478bd9Sstevel@tonic-gate #define VERBOSE_LOGS
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate /*
377c478bd9Sstevel@tonic-gate  * logger.c	- Handle logging functions for those who want it.
387c478bd9Sstevel@tonic-gate  */
397c478bd9Sstevel@tonic-gate #include "k5-int.h"
407c478bd9Sstevel@tonic-gate #include "adm_proto.h"
417c478bd9Sstevel@tonic-gate #include "com_err.h"
427c478bd9Sstevel@tonic-gate #include <stdio.h>
437c478bd9Sstevel@tonic-gate #include <ctype.h>
447c478bd9Sstevel@tonic-gate #include <ctype.h>
45*159d09a2SMark Phalan #ifdef	HAVE_SYSLOG_H
467c478bd9Sstevel@tonic-gate #include <syslog.h>
47*159d09a2SMark Phalan #endif	/* HAVE_SYSLOG_H */
48*159d09a2SMark Phalan #ifdef	HAVE_STDARG_H
497c478bd9Sstevel@tonic-gate #include <stdarg.h>
50*159d09a2SMark Phalan #else	/* HAVE_STDARG_H */
51*159d09a2SMark Phalan #include <varargs.h>
52*159d09a2SMark Phalan #endif	/* HAVE_STDARG_H */
537c478bd9Sstevel@tonic-gate #include <libintl.h>
547c478bd9Sstevel@tonic-gate #include <sys/types.h>
557c478bd9Sstevel@tonic-gate #include <sys/stat.h>
567c478bd9Sstevel@tonic-gate 
5746736d35Ssemery #define	KRB5_KLOG_MAX_ERRMSG_SIZE	2048
587c478bd9Sstevel@tonic-gate #ifndef	MAXHOSTNAMELEN
597c478bd9Sstevel@tonic-gate #define	MAXHOSTNAMELEN	256
607c478bd9Sstevel@tonic-gate #endif	/* MAXHOSTNAMELEN */
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate #define LSPEC_PARSE_ERR_1 	1
637c478bd9Sstevel@tonic-gate #define LSPEC_PARSE_ERR_2	2
647c478bd9Sstevel@tonic-gate #define LOG_FILE_ERR		3
657c478bd9Sstevel@tonic-gate #define LOG_DEVICE_ERR		4
667c478bd9Sstevel@tonic-gate #define LOG_UFO_STRING		5
677c478bd9Sstevel@tonic-gate #define LOG_EMERG_STRING	6
687c478bd9Sstevel@tonic-gate #define LOG_ALERT_STRING	7
697c478bd9Sstevel@tonic-gate #define LOG_CRIT_STRING		8
707c478bd9Sstevel@tonic-gate #define LOG_ERR_STRING		9
717c478bd9Sstevel@tonic-gate #define LOG_WARNING_STRING	10
727c478bd9Sstevel@tonic-gate #define LOG_NOTICE_STRING	11
737c478bd9Sstevel@tonic-gate #define LOG_INFO_STRING	12
747c478bd9Sstevel@tonic-gate #define LOG_DEBUG_STRING	13
757c478bd9Sstevel@tonic-gate /* This is to assure that we have at least one match in the syslog stuff */
767c478bd9Sstevel@tonic-gate /*
777c478bd9Sstevel@tonic-gate static const char LSPEC_PARSE_ERR_1[] =	"%s: cannot parse <%s>\n";
787c478bd9Sstevel@tonic-gate static const char LSPEC_PARSE_ERR_2[] =	"%s: warning - logging entry syntax error\n";
797c478bd9Sstevel@tonic-gate static const char LOG_FILE_ERR[] =	"%s: error writing to %s\n";
807c478bd9Sstevel@tonic-gate static const char LOG_DEVICE_ERR[] =	"%s: error writing to %s device\n";
817c478bd9Sstevel@tonic-gate static const char LOG_UFO_STRING[] =	"???";
827c478bd9Sstevel@tonic-gate static const char LOG_EMERG_STRING[] =	"EMERGENCY";
837c478bd9Sstevel@tonic-gate static const char LOG_ALERT_STRING[] =	"ALERT";
847c478bd9Sstevel@tonic-gate static const char LOG_CRIT_STRING[] =	"CRITICAL";
857c478bd9Sstevel@tonic-gate static const char LOG_ERR_STRING[] =	"Error";
867c478bd9Sstevel@tonic-gate static const char LOG_WARNING_STRING[] =	"Warning";
877c478bd9Sstevel@tonic-gate static const char LOG_NOTICE_STRING[] =	"Notice";
887c478bd9Sstevel@tonic-gate static const char LOG_INFO_STRING[] =	"info";
897c478bd9Sstevel@tonic-gate static const char LOG_DEBUG_STRING[] =	"debug";
907c478bd9Sstevel@tonic-gate */
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate const char *
krb5_log_error_table(long errorno)947c478bd9Sstevel@tonic-gate krb5_log_error_table(long errorno) {
957c478bd9Sstevel@tonic-gate switch (errorno) {
967c478bd9Sstevel@tonic-gate 	case LSPEC_PARSE_ERR_1:
977c478bd9Sstevel@tonic-gate 		return(gettext("%s: cannot parse <%s>\n"));
987c478bd9Sstevel@tonic-gate 	case LSPEC_PARSE_ERR_2:
997c478bd9Sstevel@tonic-gate 		return(gettext("%s: warning - logging entry syntax error\n"));
1007c478bd9Sstevel@tonic-gate 	case LOG_FILE_ERR:
1017c478bd9Sstevel@tonic-gate 		return(gettext("%s: error writing to %s\n"));
1027c478bd9Sstevel@tonic-gate 	case LOG_DEVICE_ERR:
1037c478bd9Sstevel@tonic-gate 		return(gettext("%s: error writing to %s device\n"));
1047c478bd9Sstevel@tonic-gate 	case LOG_UFO_STRING:
105814a60b1Sgtb         default:
1067c478bd9Sstevel@tonic-gate 		return(gettext("???"));
1077c478bd9Sstevel@tonic-gate 	case LOG_EMERG_STRING:
1087c478bd9Sstevel@tonic-gate 		return(gettext("EMERGENCY"));
1097c478bd9Sstevel@tonic-gate 	case LOG_ALERT_STRING:
1107c478bd9Sstevel@tonic-gate 		return(gettext("ALERT"));
1117c478bd9Sstevel@tonic-gate 	case LOG_CRIT_STRING:
1127c478bd9Sstevel@tonic-gate 		return(gettext("CRITICAL"));
1137c478bd9Sstevel@tonic-gate 	case LOG_ERR_STRING:
1147c478bd9Sstevel@tonic-gate 		return(gettext("Error"));
1157c478bd9Sstevel@tonic-gate 	case LOG_WARNING_STRING:
1167c478bd9Sstevel@tonic-gate 		return(gettext("Warning"));
1177c478bd9Sstevel@tonic-gate 	case LOG_NOTICE_STRING:
1187c478bd9Sstevel@tonic-gate 		return(gettext("Notice"));
1197c478bd9Sstevel@tonic-gate 	case LOG_INFO_STRING:
1207c478bd9Sstevel@tonic-gate 		return(gettext("info"));
1217c478bd9Sstevel@tonic-gate 	case LOG_DEBUG_STRING:
1227c478bd9Sstevel@tonic-gate 		return(gettext("info"));
1237c478bd9Sstevel@tonic-gate 	}
1247c478bd9Sstevel@tonic-gate }
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate /*
1277c478bd9Sstevel@tonic-gate  * Output logging.
1287c478bd9Sstevel@tonic-gate  *
1297c478bd9Sstevel@tonic-gate  * Output logging is now controlled by the configuration file.  We can specify
1307c478bd9Sstevel@tonic-gate  * the following syntaxes under the [logging]->entity specification.
1317c478bd9Sstevel@tonic-gate  *	FILE<opentype><pathname>
1327c478bd9Sstevel@tonic-gate  *	SYSLOG[=<severity>[:<facility>]]
1337c478bd9Sstevel@tonic-gate  *	STDERR
1347c478bd9Sstevel@tonic-gate  *	CONSOLE
1357c478bd9Sstevel@tonic-gate  *	DEVICE=<device-spec>
1367c478bd9Sstevel@tonic-gate  *
1377c478bd9Sstevel@tonic-gate  * Where:
1387c478bd9Sstevel@tonic-gate  *	<opentype> is ":" for open/append, "=" for open/create.
1397c478bd9Sstevel@tonic-gate  *	<pathname> is a valid path name.
1407c478bd9Sstevel@tonic-gate  *	<severity> is one of: (default = ERR)
1417c478bd9Sstevel@tonic-gate  *		EMERG
1427c478bd9Sstevel@tonic-gate  *		ALERT
1437c478bd9Sstevel@tonic-gate  *		CRIT
1447c478bd9Sstevel@tonic-gate  *		ERR
1457c478bd9Sstevel@tonic-gate  *		WARNING
1467c478bd9Sstevel@tonic-gate  *		NOTICE
1477c478bd9Sstevel@tonic-gate  *		INFO
1487c478bd9Sstevel@tonic-gate  *		DEBUG
1497c478bd9Sstevel@tonic-gate  *	<facility> is one of: (default = AUTH)
1507c478bd9Sstevel@tonic-gate  *		KERN
1517c478bd9Sstevel@tonic-gate  *		USER
1527c478bd9Sstevel@tonic-gate  *		MAIL
1537c478bd9Sstevel@tonic-gate  *		DAEMON
1547c478bd9Sstevel@tonic-gate  *		AUTH
1557c478bd9Sstevel@tonic-gate  *		LPR
1567c478bd9Sstevel@tonic-gate  *		NEWS
1577c478bd9Sstevel@tonic-gate  *		UUCP
1587c478bd9Sstevel@tonic-gate  *		CRON
1597c478bd9Sstevel@tonic-gate  *		LOCAL0..LOCAL7
1607c478bd9Sstevel@tonic-gate  *	<device-spec> is a valid device specification.
1617c478bd9Sstevel@tonic-gate  */
1627c478bd9Sstevel@tonic-gate struct log_entry {
1637c478bd9Sstevel@tonic-gate     enum log_type { K_LOG_FILE,
1647c478bd9Sstevel@tonic-gate 			K_LOG_SYSLOG,
1657c478bd9Sstevel@tonic-gate 			K_LOG_STDERR,
1667c478bd9Sstevel@tonic-gate 			K_LOG_CONSOLE,
1677c478bd9Sstevel@tonic-gate 			K_LOG_DEVICE,
1687c478bd9Sstevel@tonic-gate 			K_LOG_NONE } log_type;
1697c478bd9Sstevel@tonic-gate     krb5_pointer log_2free;
1707c478bd9Sstevel@tonic-gate     union log_union {
1717c478bd9Sstevel@tonic-gate 	struct log_file {
1727c478bd9Sstevel@tonic-gate 	    FILE	*lf_filep;
1737c478bd9Sstevel@tonic-gate 	    char	*lf_fname;
1747c478bd9Sstevel@tonic-gate 	    char	*lf_fopen_mode; /* "a+" or "w" */
1757c478bd9Sstevel@tonic-gate #define	K_LOG_DEF_FILE_ROTATE_PERIOD	-1	/* never */
1767c478bd9Sstevel@tonic-gate #define	K_LOG_DEF_FILE_ROTATE_VERSIONS	0	/* no versions */
1777c478bd9Sstevel@tonic-gate 	    time_t	lf_rotate_period;
1787c478bd9Sstevel@tonic-gate 	    time_t	lf_last_rotated;
1797c478bd9Sstevel@tonic-gate 	    int		lf_rotate_versions;
1807c478bd9Sstevel@tonic-gate 	} log_file;
1817c478bd9Sstevel@tonic-gate 	struct log_syslog {
1827c478bd9Sstevel@tonic-gate 	    int		ls_facility;
1837c478bd9Sstevel@tonic-gate 	    int		ls_severity;
1847c478bd9Sstevel@tonic-gate 	} log_syslog;
1857c478bd9Sstevel@tonic-gate 	struct log_device {
1867c478bd9Sstevel@tonic-gate 	    FILE	*ld_filep;
1877c478bd9Sstevel@tonic-gate 	    char	*ld_devname;
1887c478bd9Sstevel@tonic-gate 	} log_device;
1897c478bd9Sstevel@tonic-gate     } log_union;
1907c478bd9Sstevel@tonic-gate };
1917c478bd9Sstevel@tonic-gate #define	lfu_filep	log_union.log_file.lf_filep
1927c478bd9Sstevel@tonic-gate #define	lfu_fname	log_union.log_file.lf_fname
1937c478bd9Sstevel@tonic-gate #define	lfu_fopen_mode	log_union.log_file.lf_fopen_mode
1947c478bd9Sstevel@tonic-gate #define	lfu_rotate_period	log_union.log_file.lf_rotate_period
1957c478bd9Sstevel@tonic-gate #define	lfu_last_rotated	log_union.log_file.lf_last_rotated
1967c478bd9Sstevel@tonic-gate #define	lfu_rotate_versions	log_union.log_file.lf_rotate_versions
1977c478bd9Sstevel@tonic-gate #define	lsu_facility	log_union.log_syslog.ls_facility
1987c478bd9Sstevel@tonic-gate #define	lsu_severity	log_union.log_syslog.ls_severity
1997c478bd9Sstevel@tonic-gate #define	ldu_filep	log_union.log_device.ld_filep
2007c478bd9Sstevel@tonic-gate #define	ldu_devname	log_union.log_device.ld_devname
2017c478bd9Sstevel@tonic-gate 
2027c478bd9Sstevel@tonic-gate struct log_control {
2037c478bd9Sstevel@tonic-gate     struct log_entry	*log_entries;
2047c478bd9Sstevel@tonic-gate     int			log_nentries;
2057c478bd9Sstevel@tonic-gate     char		*log_whoami;
2067c478bd9Sstevel@tonic-gate     char		*log_hostname;
2077c478bd9Sstevel@tonic-gate     krb5_boolean	log_opened;
2087c478bd9Sstevel@tonic-gate };
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate static struct log_control log_control = {
2117c478bd9Sstevel@tonic-gate     (struct log_entry *) NULL,
2127c478bd9Sstevel@tonic-gate     0,
2137c478bd9Sstevel@tonic-gate     (char *) NULL,
2147c478bd9Sstevel@tonic-gate     (char *) NULL,
2157c478bd9Sstevel@tonic-gate     0
2167c478bd9Sstevel@tonic-gate };
2177c478bd9Sstevel@tonic-gate static struct log_entry	def_log_entry;
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate /*
2207c478bd9Sstevel@tonic-gate  * These macros define any special processing that needs to happen for
2217c478bd9Sstevel@tonic-gate  * devices.  For unix, of course, this is hardly anything.
2227c478bd9Sstevel@tonic-gate  */
2237c478bd9Sstevel@tonic-gate #define	DEVICE_OPEN(d, m)	fopen(d, m)
2247c478bd9Sstevel@tonic-gate #define	CONSOLE_OPEN(m)		fopen("/dev/console", m)
2257c478bd9Sstevel@tonic-gate #define	DEVICE_PRINT(f, m)	((fprintf(f, "%s\r\n", m) >= 0) ? 	\
2267c478bd9Sstevel@tonic-gate 				 (fflush(f), 0) :			\
2277c478bd9Sstevel@tonic-gate 				 -1)
2287c478bd9Sstevel@tonic-gate #define	DEVICE_CLOSE(d)		fclose(d)
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate /*
2327c478bd9Sstevel@tonic-gate  * klog_rotate() - roate a log file if we have specified rotation
2337c478bd9Sstevel@tonic-gate  * parameters in krb5.conf.
2347c478bd9Sstevel@tonic-gate  */
2357c478bd9Sstevel@tonic-gate static void
klog_rotate(struct log_entry * le)2367c478bd9Sstevel@tonic-gate klog_rotate(struct log_entry *le)
2377c478bd9Sstevel@tonic-gate {
2387c478bd9Sstevel@tonic-gate 	time_t t;
2397c478bd9Sstevel@tonic-gate 	int i;
2407c478bd9Sstevel@tonic-gate 	char *name_buf1;
2417c478bd9Sstevel@tonic-gate 	char *name_buf2;
2427c478bd9Sstevel@tonic-gate 	char *old_name;
2437c478bd9Sstevel@tonic-gate 	char *new_name;
2447c478bd9Sstevel@tonic-gate 	char *tmp;
2457c478bd9Sstevel@tonic-gate 	FILE *fp;
2467c478bd9Sstevel@tonic-gate 	int num_vers;
2477c478bd9Sstevel@tonic-gate 	mode_t old_umask;
2487c478bd9Sstevel@tonic-gate 
2497c478bd9Sstevel@tonic-gate 
2507c478bd9Sstevel@tonic-gate 	/*
2517c478bd9Sstevel@tonic-gate 	 * By default we don't rotate.
2527c478bd9Sstevel@tonic-gate 	 */
2537c478bd9Sstevel@tonic-gate 	if (le->lfu_rotate_period == K_LOG_DEF_FILE_ROTATE_PERIOD)
2547c478bd9Sstevel@tonic-gate 		return;
2557c478bd9Sstevel@tonic-gate 
2567c478bd9Sstevel@tonic-gate 	t = time(0);
2577c478bd9Sstevel@tonic-gate 
2587c478bd9Sstevel@tonic-gate 	if (t >= le->lfu_last_rotated + le->lfu_rotate_period) {
2597c478bd9Sstevel@tonic-gate 		/*
2607c478bd9Sstevel@tonic-gate 		 * The N log file versions will be renamed X.N-1 X.N-2, ... X.0.
2617c478bd9Sstevel@tonic-gate 		 * So the allocate file name buffers that can the version
2627c478bd9Sstevel@tonic-gate 		 * number extensions.
2637c478bd9Sstevel@tonic-gate 		 * 32 extra bytes is plenty.
2647c478bd9Sstevel@tonic-gate 		 */
2657c478bd9Sstevel@tonic-gate 		name_buf1 = malloc(strlen(le->lfu_fname) + 32);
2667c478bd9Sstevel@tonic-gate 
2677c478bd9Sstevel@tonic-gate 		if (name_buf1 == NULL)
2687c478bd9Sstevel@tonic-gate 			return;
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate 		name_buf2 = malloc(strlen(le->lfu_fname) + 32);
2717c478bd9Sstevel@tonic-gate 
2727c478bd9Sstevel@tonic-gate 		if (name_buf2 == NULL) {
2737c478bd9Sstevel@tonic-gate 			free(name_buf1);
2747c478bd9Sstevel@tonic-gate 			return;
2757c478bd9Sstevel@tonic-gate 		}
2767c478bd9Sstevel@tonic-gate 
2777c478bd9Sstevel@tonic-gate 		old_name = name_buf1;
2787c478bd9Sstevel@tonic-gate 		new_name = name_buf2;
2797c478bd9Sstevel@tonic-gate 
2807c478bd9Sstevel@tonic-gate 		/*
2817c478bd9Sstevel@tonic-gate 		 * If there N versions, then the first one has file extension
2827c478bd9Sstevel@tonic-gate 		 * of N-1.
2837c478bd9Sstevel@tonic-gate 		 */
2847c478bd9Sstevel@tonic-gate 		(void) sprintf(new_name, "%s.%d", le->lfu_fname,
2857c478bd9Sstevel@tonic-gate 			le->lfu_rotate_versions - 1);
2867c478bd9Sstevel@tonic-gate 
2877c478bd9Sstevel@tonic-gate 		/*
2887c478bd9Sstevel@tonic-gate 		 * Rename file.N-2 to file.N-1, file.N-3 to file.N-2, ...
2897c478bd9Sstevel@tonic-gate 		 * file.0 to file.1
2907c478bd9Sstevel@tonic-gate 		 */
2917c478bd9Sstevel@tonic-gate 		for (i = le->lfu_rotate_versions - 1; i > 0; i--) {
2927c478bd9Sstevel@tonic-gate 			(void) sprintf(old_name, "%s.%d", le->lfu_fname, i - 1);
2937c478bd9Sstevel@tonic-gate 			(void) rename(old_name, new_name);
2947c478bd9Sstevel@tonic-gate 
2957c478bd9Sstevel@tonic-gate 			/*
2967c478bd9Sstevel@tonic-gate 			 * swap old name and new name. This way,
2977c478bd9Sstevel@tonic-gate 			 * on the next iteration, new_name.X
2987c478bd9Sstevel@tonic-gate 			 * becomes new_name.X-1.
2997c478bd9Sstevel@tonic-gate 			 */
3007c478bd9Sstevel@tonic-gate 			tmp = old_name;
3017c478bd9Sstevel@tonic-gate 			old_name = new_name;
3027c478bd9Sstevel@tonic-gate 			new_name = tmp;
3037c478bd9Sstevel@tonic-gate 		}
3047c478bd9Sstevel@tonic-gate 		old_name = le->lfu_fname;
3057c478bd9Sstevel@tonic-gate 
3067c478bd9Sstevel@tonic-gate 		(void) rename(old_name, new_name);
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate 		/*
3097c478bd9Sstevel@tonic-gate 		 * Even though we don't know yet if the fopen()
3107c478bd9Sstevel@tonic-gate 		 * of the log file will succeed, we mark the log
3117c478bd9Sstevel@tonic-gate 		 * as rotated. This is so we don't repeatably
3127c478bd9Sstevel@tonic-gate 		 * rotate file.N-2 to file.N-1 ... etc without
3137c478bd9Sstevel@tonic-gate 		 * waiting for the rotate period to elapse.
3147c478bd9Sstevel@tonic-gate 		 */
3157c478bd9Sstevel@tonic-gate 		le->lfu_last_rotated = t;
3167c478bd9Sstevel@tonic-gate 
3177c478bd9Sstevel@tonic-gate 		/*
3187c478bd9Sstevel@tonic-gate 		 * Default log file creation mode should be read-only
3197c478bd9Sstevel@tonic-gate 		 * by owner(root), but the admin can override with
3207c478bd9Sstevel@tonic-gate 		 * chmod(1) if desired.
3217c478bd9Sstevel@tonic-gate 		 */
3227c478bd9Sstevel@tonic-gate 
3237c478bd9Sstevel@tonic-gate 		old_umask = umask(077);
3247c478bd9Sstevel@tonic-gate 		fp = fopen(old_name, le->lfu_fopen_mode);
3257c478bd9Sstevel@tonic-gate 
3267c478bd9Sstevel@tonic-gate 		umask(old_umask);
3277c478bd9Sstevel@tonic-gate 
3287c478bd9Sstevel@tonic-gate 		if (fp != NULL) {
3297c478bd9Sstevel@tonic-gate 
3307c478bd9Sstevel@tonic-gate 			(void) fclose(le->lfu_filep);
3317c478bd9Sstevel@tonic-gate 			le->lfu_filep = fp;
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate 			/*
3347c478bd9Sstevel@tonic-gate 			 * If the version parameter in krb5.conf was
3357c478bd9Sstevel@tonic-gate 			 * 0, then we take this to mean that rotating the
3367c478bd9Sstevel@tonic-gate 			 * log file will cause us to dispose of the
3377c478bd9Sstevel@tonic-gate 			 * old one, and created a new one. We have just
3387c478bd9Sstevel@tonic-gate 			 * renamed the old one to file.-1, so remove it.
3397c478bd9Sstevel@tonic-gate 			 */
3407c478bd9Sstevel@tonic-gate 			if (le->lfu_rotate_versions <= 0)
3417c478bd9Sstevel@tonic-gate 				(void) unlink(new_name);
3427c478bd9Sstevel@tonic-gate 
3437c478bd9Sstevel@tonic-gate 		} else {
3447c478bd9Sstevel@tonic-gate 			fprintf(stderr,
3457c478bd9Sstevel@tonic-gate 		gettext("During rotate, couldn't open log file %s: %s\n"),
3467c478bd9Sstevel@tonic-gate 				old_name, error_message(errno));
3477c478bd9Sstevel@tonic-gate 			/*
3487c478bd9Sstevel@tonic-gate 			 * Put it back.
3497c478bd9Sstevel@tonic-gate 			 */
3507c478bd9Sstevel@tonic-gate 			(void) rename(new_name, old_name);
3517c478bd9Sstevel@tonic-gate 		}
3527c478bd9Sstevel@tonic-gate 		free(name_buf1);
3537c478bd9Sstevel@tonic-gate 		free(name_buf2);
3547c478bd9Sstevel@tonic-gate 	}
3557c478bd9Sstevel@tonic-gate }
3567c478bd9Sstevel@tonic-gate 
3577c478bd9Sstevel@tonic-gate /*
3587c478bd9Sstevel@tonic-gate  * klog_com_err_proc()	- Handle com_err(3) messages as specified by the
3597c478bd9Sstevel@tonic-gate  *			  profile.
3607c478bd9Sstevel@tonic-gate  */
3617c64d375Smp153739 static krb5_context err_context;
3627c478bd9Sstevel@tonic-gate static void
klog_com_err_proc(const char * whoami,long code,const char * format,va_list ap)363*159d09a2SMark Phalan klog_com_err_proc(const char *whoami, long code, const char *format, va_list ap)
3647c478bd9Sstevel@tonic-gate {
3657c478bd9Sstevel@tonic-gate     char	outbuf[KRB5_KLOG_MAX_ERRMSG_SIZE];
3667c478bd9Sstevel@tonic-gate     int		lindex;
367*159d09a2SMark Phalan     const char	*actual_format;
368*159d09a2SMark Phalan #ifdef	HAVE_SYSLOG
3697c478bd9Sstevel@tonic-gate     int		log_pri = -1;
370*159d09a2SMark Phalan #endif	/* HAVE_SYSLOG */
3717c478bd9Sstevel@tonic-gate     char	*cp;
3727c478bd9Sstevel@tonic-gate     char	*syslogp;
3737c478bd9Sstevel@tonic-gate 
3747c478bd9Sstevel@tonic-gate     /* Make the header */
3757c478bd9Sstevel@tonic-gate     sprintf(outbuf, "%s: ", whoami);
3767c478bd9Sstevel@tonic-gate     /*
3777c478bd9Sstevel@tonic-gate      * Squirrel away address after header for syslog since syslog makes
3787c478bd9Sstevel@tonic-gate      * a header
3797c478bd9Sstevel@tonic-gate      */
3807c478bd9Sstevel@tonic-gate     syslogp = &outbuf[strlen(outbuf)];
3817c478bd9Sstevel@tonic-gate 
3827c478bd9Sstevel@tonic-gate     /* If reporting an error message, separate it. */
3837c478bd9Sstevel@tonic-gate     if (code) {
384*159d09a2SMark Phalan 	/* Solaris Kerberos */
3857c64d375Smp153739         const char *emsg;
3867c478bd9Sstevel@tonic-gate         outbuf[sizeof(outbuf) - 1] = '\0';
38746736d35Ssemery 
3887c64d375Smp153739 	emsg = krb5_get_error_message (err_context, code);
3897c64d375Smp153739 	strncat(outbuf, emsg, sizeof(outbuf) - 1 - strlen(outbuf));
390*159d09a2SMark Phalan 	strncat(outbuf, " - ", sizeof(outbuf) - 1 - strlen(outbuf));
3917c64d375Smp153739 	krb5_free_error_message(err_context, emsg);
3927c478bd9Sstevel@tonic-gate     }
3937c478bd9Sstevel@tonic-gate     cp = &outbuf[strlen(outbuf)];
3947c478bd9Sstevel@tonic-gate 
395*159d09a2SMark Phalan     actual_format = format;
396*159d09a2SMark Phalan #ifdef	HAVE_SYSLOG
3977c478bd9Sstevel@tonic-gate     /*
3987c478bd9Sstevel@tonic-gate      * This is an unpleasant hack.  If the first character is less than
3997c478bd9Sstevel@tonic-gate      * 8, then we assume that it is a priority.
4007c478bd9Sstevel@tonic-gate      *
4017c478bd9Sstevel@tonic-gate      * Since it is not guaranteed that there is a direct mapping between
4027c478bd9Sstevel@tonic-gate      * syslog priorities (e.g. Ultrix and old BSD), we resort to this
4037c478bd9Sstevel@tonic-gate      * intermediate representation.
4047c478bd9Sstevel@tonic-gate      */
4057c478bd9Sstevel@tonic-gate     if ((((unsigned char) *format) > 0) && (((unsigned char) *format) <= 8)) {
406*159d09a2SMark Phalan 	actual_format = (format + 1);
4077c478bd9Sstevel@tonic-gate 	switch ((unsigned char) *format) {
408*159d09a2SMark Phalan #ifdef	LOG_EMERG
4097c478bd9Sstevel@tonic-gate 	case 1:
4107c478bd9Sstevel@tonic-gate 	    log_pri = LOG_EMERG;
4117c478bd9Sstevel@tonic-gate 	    break;
412*159d09a2SMark Phalan #endif /* LOG_EMERG */
413*159d09a2SMark Phalan #ifdef	LOG_ALERT
4147c478bd9Sstevel@tonic-gate 	case 2:
4157c478bd9Sstevel@tonic-gate 	    log_pri = LOG_ALERT;
4167c478bd9Sstevel@tonic-gate 	    break;
417*159d09a2SMark Phalan #endif /* LOG_ALERT */
418*159d09a2SMark Phalan #ifdef	LOG_CRIT
4197c478bd9Sstevel@tonic-gate 	case 3:
4207c478bd9Sstevel@tonic-gate 	    log_pri = LOG_CRIT;
4217c478bd9Sstevel@tonic-gate 	    break;
422*159d09a2SMark Phalan #endif /* LOG_CRIT */
4237c478bd9Sstevel@tonic-gate 	default:
4247c478bd9Sstevel@tonic-gate 	case 4:
4257c478bd9Sstevel@tonic-gate 	    log_pri = LOG_ERR;
4267c478bd9Sstevel@tonic-gate 	    break;
427*159d09a2SMark Phalan #ifdef	LOG_WARNING
4287c478bd9Sstevel@tonic-gate 	case 5:
4297c478bd9Sstevel@tonic-gate 	    log_pri = LOG_WARNING;
4307c478bd9Sstevel@tonic-gate 	    break;
431*159d09a2SMark Phalan #endif /* LOG_WARNING */
432*159d09a2SMark Phalan #ifdef	LOG_NOTICE
4337c478bd9Sstevel@tonic-gate 	case 6:
4347c478bd9Sstevel@tonic-gate 	    log_pri = LOG_NOTICE;
4357c478bd9Sstevel@tonic-gate 	    break;
436*159d09a2SMark Phalan #endif /* LOG_NOTICE */
437*159d09a2SMark Phalan #ifdef	LOG_INFO
4387c478bd9Sstevel@tonic-gate 	case 7:
4397c478bd9Sstevel@tonic-gate 	    log_pri = LOG_INFO;
4407c478bd9Sstevel@tonic-gate 	    break;
441*159d09a2SMark Phalan #endif /* LOG_INFO */
442*159d09a2SMark Phalan #ifdef	LOG_DEBUG
4437c478bd9Sstevel@tonic-gate 	case 8:
4447c478bd9Sstevel@tonic-gate 	    log_pri = LOG_DEBUG;
4457c478bd9Sstevel@tonic-gate 	    break;
446*159d09a2SMark Phalan #endif /* LOG_DEBUG */
4477c478bd9Sstevel@tonic-gate 	}
4487c478bd9Sstevel@tonic-gate     }
449*159d09a2SMark Phalan #endif	/* HAVE_SYSLOG */
4507c478bd9Sstevel@tonic-gate 
4517c478bd9Sstevel@tonic-gate     /* Now format the actual message */
452*159d09a2SMark Phalan #if	HAVE_VSNPRINTF
45346736d35Ssemery     vsnprintf(cp, sizeof(outbuf) - (cp - outbuf), actual_format, ap);
454*159d09a2SMark Phalan #elif	HAVE_VSPRINTF
455*159d09a2SMark Phalan     vsprintf(cp, actual_format, ap);
456*159d09a2SMark Phalan #else	/* HAVE_VSPRINTF */
457*159d09a2SMark Phalan     sprintf(cp, actual_format, ((int *) ap)[0], ((int *) ap)[1],
458*159d09a2SMark Phalan 	    ((int *) ap)[2], ((int *) ap)[3],
459*159d09a2SMark Phalan 	    ((int *) ap)[4], ((int *) ap)[5]);
460*159d09a2SMark Phalan #endif	/* HAVE_VSPRINTF */
4617c478bd9Sstevel@tonic-gate 
4627c478bd9Sstevel@tonic-gate     /*
4637c478bd9Sstevel@tonic-gate      * Now that we have the message formatted, perform the output to each
4647c478bd9Sstevel@tonic-gate      * logging specification.
4657c478bd9Sstevel@tonic-gate      */
4667c478bd9Sstevel@tonic-gate     for (lindex = 0; lindex < log_control.log_nentries; lindex++) {
4677c478bd9Sstevel@tonic-gate 	switch (log_control.log_entries[lindex].log_type) {
4687c478bd9Sstevel@tonic-gate 	case K_LOG_FILE:
4697c478bd9Sstevel@tonic-gate 
4707c478bd9Sstevel@tonic-gate 	    klog_rotate(&log_control.log_entries[lindex]);
4717c478bd9Sstevel@tonic-gate 	    /*FALLTHRU*/
4727c478bd9Sstevel@tonic-gate 	case K_LOG_STDERR:
4737c478bd9Sstevel@tonic-gate 	    /*
4747c478bd9Sstevel@tonic-gate 	     * Files/standard error.
4757c478bd9Sstevel@tonic-gate 	     */
4767c478bd9Sstevel@tonic-gate 	    if (fprintf(log_control.log_entries[lindex].lfu_filep, "%s\n",
4777c478bd9Sstevel@tonic-gate 			outbuf) < 0) {
4787c478bd9Sstevel@tonic-gate 		/* Attempt to report error */
4797c478bd9Sstevel@tonic-gate 		fprintf(stderr, krb5_log_error_table(LOG_FILE_ERR), whoami,
4807c478bd9Sstevel@tonic-gate 			log_control.log_entries[lindex].lfu_fname);
4817c478bd9Sstevel@tonic-gate 	    }
4827c478bd9Sstevel@tonic-gate 	    else {
4837c478bd9Sstevel@tonic-gate 		fflush(log_control.log_entries[lindex].lfu_filep);
4847c478bd9Sstevel@tonic-gate 	    }
4857c478bd9Sstevel@tonic-gate 	    break;
4867c478bd9Sstevel@tonic-gate 	case K_LOG_CONSOLE:
4877c478bd9Sstevel@tonic-gate 	case K_LOG_DEVICE:
4887c478bd9Sstevel@tonic-gate 	    /*
4897c478bd9Sstevel@tonic-gate 	     * Devices (may need special handling)
4907c478bd9Sstevel@tonic-gate 	     */
4917c478bd9Sstevel@tonic-gate 	    if (DEVICE_PRINT(log_control.log_entries[lindex].ldu_filep,
4927c478bd9Sstevel@tonic-gate 			     outbuf) < 0) {
4937c478bd9Sstevel@tonic-gate 		/* Attempt to report error */
4947c478bd9Sstevel@tonic-gate 		fprintf(stderr, krb5_log_error_table(LOG_DEVICE_ERR), whoami,
4957c478bd9Sstevel@tonic-gate 			log_control.log_entries[lindex].ldu_devname);
4967c478bd9Sstevel@tonic-gate 	    }
4977c478bd9Sstevel@tonic-gate 	    break;
498*159d09a2SMark Phalan #ifdef	HAVE_SYSLOG
4997c478bd9Sstevel@tonic-gate 	case K_LOG_SYSLOG:
5007c478bd9Sstevel@tonic-gate 	    /*
5017c478bd9Sstevel@tonic-gate 	     * System log.
5027c478bd9Sstevel@tonic-gate 	     */
5037c478bd9Sstevel@tonic-gate 	    /*
5047c478bd9Sstevel@tonic-gate 	     * If we have specified a priority through our hackery, then
5057c478bd9Sstevel@tonic-gate 	     * use it, otherwise use the default.
5067c478bd9Sstevel@tonic-gate 	     */
5077c478bd9Sstevel@tonic-gate 	    if (log_pri >= 0)
5087c478bd9Sstevel@tonic-gate 		log_pri |= log_control.log_entries[lindex].lsu_facility;
5097c478bd9Sstevel@tonic-gate 	    else
5107c478bd9Sstevel@tonic-gate 		log_pri = log_control.log_entries[lindex].lsu_facility |
5117c478bd9Sstevel@tonic-gate 		    log_control.log_entries[lindex].lsu_severity;
5127c478bd9Sstevel@tonic-gate 
5137c478bd9Sstevel@tonic-gate 	    /* Log the message with our header trimmed off */
5147c478bd9Sstevel@tonic-gate 	    syslog(log_pri, "%s", syslogp);
5157c478bd9Sstevel@tonic-gate 	    break;
516*159d09a2SMark Phalan #endif /* HAVE_SYSLOG */
5177c478bd9Sstevel@tonic-gate 	default:
5187c478bd9Sstevel@tonic-gate 	    break;
5197c478bd9Sstevel@tonic-gate 	}
5207c478bd9Sstevel@tonic-gate     }
5217c478bd9Sstevel@tonic-gate }
5227c478bd9Sstevel@tonic-gate 
5237c478bd9Sstevel@tonic-gate /*
5247c478bd9Sstevel@tonic-gate  * krb5_klog_init()	- Initialize logging.
5257c478bd9Sstevel@tonic-gate  *
5267c478bd9Sstevel@tonic-gate  * This routine parses the syntax described above to specify destinations for
5277c478bd9Sstevel@tonic-gate  * com_err(3) or krb5_klog_syslog() messages generated by the caller.
5287c478bd9Sstevel@tonic-gate  *
5297c478bd9Sstevel@tonic-gate  * Parameters:
5307c478bd9Sstevel@tonic-gate  *	kcontext	- Kerberos context.
5317c478bd9Sstevel@tonic-gate  *	ename		- Entity name as it is to appear in the profile.
5327c478bd9Sstevel@tonic-gate  *	whoami		- Entity name as it is to appear in error output.
5337c478bd9Sstevel@tonic-gate  *	do_com_err	- Take over com_err(3) processing.
5347c478bd9Sstevel@tonic-gate  *
5357c478bd9Sstevel@tonic-gate  * Implicit inputs:
5367c478bd9Sstevel@tonic-gate  *	stderr		- This is where STDERR output goes.
5377c478bd9Sstevel@tonic-gate  *
5387c478bd9Sstevel@tonic-gate  * Implicit outputs:
5397c478bd9Sstevel@tonic-gate  *	log_nentries	- Number of log entries, both valid and invalid.
5407c478bd9Sstevel@tonic-gate  *	log_control	- List of entries (log_nentries long) which contains
5417c478bd9Sstevel@tonic-gate  *			  data for klog_com_err_proc() to use to determine
5427c478bd9Sstevel@tonic-gate  *			  where/how to send output.
5437c478bd9Sstevel@tonic-gate  */
5447c478bd9Sstevel@tonic-gate krb5_error_code
krb5_klog_init(krb5_context kcontext,char * ename,char * whoami,krb5_boolean do_com_err)545*159d09a2SMark Phalan krb5_klog_init(krb5_context kcontext, char *ename, char *whoami, krb5_boolean do_com_err)
5467c478bd9Sstevel@tonic-gate {
5477c478bd9Sstevel@tonic-gate     const char	*logging_profent[3];
5487c478bd9Sstevel@tonic-gate     const char	*logging_defent[3];
5497c478bd9Sstevel@tonic-gate     char	**logging_specs;
5507c478bd9Sstevel@tonic-gate     int		i, ngood;
5517c478bd9Sstevel@tonic-gate     char	*cp, *cp2;
552*159d09a2SMark Phalan     char	savec = '\0';
5537c478bd9Sstevel@tonic-gate     int		error;
5547c478bd9Sstevel@tonic-gate     int		do_openlog, log_facility;
5557c478bd9Sstevel@tonic-gate     FILE	*f;
5567c478bd9Sstevel@tonic-gate     mode_t      old_umask;
5577c478bd9Sstevel@tonic-gate 
5587c478bd9Sstevel@tonic-gate     /* Initialize */
5597c478bd9Sstevel@tonic-gate     do_openlog = 0;
5607c478bd9Sstevel@tonic-gate     log_facility = 0;
5617c478bd9Sstevel@tonic-gate 
5627c64d375Smp153739     err_context = kcontext;
5637c64d375Smp153739 
5647c478bd9Sstevel@tonic-gate     /*
5657c478bd9Sstevel@tonic-gate      * Look up [logging]-><ename> in the profile.  If that doesn't
5667c478bd9Sstevel@tonic-gate      * succeed, then look for [logging]->default.
5677c478bd9Sstevel@tonic-gate      */
5687c478bd9Sstevel@tonic-gate     logging_profent[0] = "logging";
5697c478bd9Sstevel@tonic-gate     logging_profent[1] = ename;
5707c478bd9Sstevel@tonic-gate     logging_profent[2] = (char *) NULL;
5717c478bd9Sstevel@tonic-gate     logging_defent[0] = "logging";
5727c478bd9Sstevel@tonic-gate     logging_defent[1] = "default";
5737c478bd9Sstevel@tonic-gate     logging_defent[2] = (char *) NULL;
5747c478bd9Sstevel@tonic-gate     logging_specs = (char **) NULL;
5757c478bd9Sstevel@tonic-gate     ngood = 0;
5767c478bd9Sstevel@tonic-gate     log_control.log_nentries = 0;
5777c478bd9Sstevel@tonic-gate     if (!profile_get_values(kcontext->profile,
5787c478bd9Sstevel@tonic-gate 			    logging_profent,
5797c478bd9Sstevel@tonic-gate 			    &logging_specs) ||
5807c478bd9Sstevel@tonic-gate 	!profile_get_values(kcontext->profile,
5817c478bd9Sstevel@tonic-gate 			    logging_defent,
5827c478bd9Sstevel@tonic-gate 			    &logging_specs)) {
5837c478bd9Sstevel@tonic-gate 	/*
5847c478bd9Sstevel@tonic-gate 	 * We have a match, so we first count the number of elements
5857c478bd9Sstevel@tonic-gate 	 */
5867c478bd9Sstevel@tonic-gate 	for (log_control.log_nentries = 0;
5877c478bd9Sstevel@tonic-gate 	     logging_specs[log_control.log_nentries];
5887c478bd9Sstevel@tonic-gate 	     log_control.log_nentries++);
5897c478bd9Sstevel@tonic-gate 
5907c478bd9Sstevel@tonic-gate 	/*
5917c478bd9Sstevel@tonic-gate 	 * Now allocate our structure.
5927c478bd9Sstevel@tonic-gate 	 */
5937c478bd9Sstevel@tonic-gate 	log_control.log_entries = (struct log_entry *)
5947c478bd9Sstevel@tonic-gate 	    malloc(log_control.log_nentries * sizeof(struct log_entry));
5957c478bd9Sstevel@tonic-gate 	if (log_control.log_entries) {
5967c478bd9Sstevel@tonic-gate 	    /*
5977c478bd9Sstevel@tonic-gate 	     * Scan through the list.
5987c478bd9Sstevel@tonic-gate 	     */
5997c478bd9Sstevel@tonic-gate 	    for (i=0; i<log_control.log_nentries; i++) {
6007c478bd9Sstevel@tonic-gate 		log_control.log_entries[i].log_type = K_LOG_NONE;
6017c478bd9Sstevel@tonic-gate 		log_control.log_entries[i].log_2free = logging_specs[i];
6027c478bd9Sstevel@tonic-gate 		/*
6037c478bd9Sstevel@tonic-gate 		 * The format is:
6047c478bd9Sstevel@tonic-gate 		 *	<whitespace><data><whitespace>
6057c478bd9Sstevel@tonic-gate 		 * so, trim off the leading and trailing whitespace here.
6067c478bd9Sstevel@tonic-gate 		 */
607*159d09a2SMark Phalan 		for (cp = logging_specs[i]; isspace((int) *cp); cp++);
6087c478bd9Sstevel@tonic-gate 		for (cp2 = &logging_specs[i][strlen(logging_specs[i])-1];
609*159d09a2SMark Phalan 		     isspace((int) *cp2); cp2--);
6107c478bd9Sstevel@tonic-gate 		cp2++;
6117c478bd9Sstevel@tonic-gate 		*cp2 = '\0';
6127c478bd9Sstevel@tonic-gate 		/*
6137c478bd9Sstevel@tonic-gate 		 * Is this a file?
6147c478bd9Sstevel@tonic-gate 		 */
6157c478bd9Sstevel@tonic-gate 		if (!strncasecmp(cp, "FILE", 4)) {
6167c478bd9Sstevel@tonic-gate 		    /*
6177c478bd9Sstevel@tonic-gate 		     * Check for append/overwrite, then open the file.
6187c478bd9Sstevel@tonic-gate 		     */
6197c478bd9Sstevel@tonic-gate 		    if (cp[4] == ':' || cp[4] == '=') {
6207c478bd9Sstevel@tonic-gate 			log_control.log_entries[i].lfu_fopen_mode =
621004388ebScasper 				(cp[4] == ':') ? "a+F" : "wF";
6227c478bd9Sstevel@tonic-gate 			old_umask = umask(077);
6237c478bd9Sstevel@tonic-gate 			f = fopen(&cp[5],
6247c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lfu_fopen_mode);
6257c478bd9Sstevel@tonic-gate 			umask(old_umask);
6267c478bd9Sstevel@tonic-gate 			if (f) {
6277c478bd9Sstevel@tonic-gate                             char rotate_kw[128];
6287c478bd9Sstevel@tonic-gate 
6297c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lfu_filep = f;
6307c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].log_type = K_LOG_FILE;
6317c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lfu_fname = &cp[5];
6327c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lfu_rotate_period =
6337c478bd9Sstevel@tonic-gate 				K_LOG_DEF_FILE_ROTATE_PERIOD;
6347c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lfu_rotate_versions =
6357c478bd9Sstevel@tonic-gate 				K_LOG_DEF_FILE_ROTATE_VERSIONS;
6367c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lfu_last_rotated =
6377c478bd9Sstevel@tonic-gate 				time(0);
6387c478bd9Sstevel@tonic-gate 
6397c478bd9Sstevel@tonic-gate 			/*
6407c478bd9Sstevel@tonic-gate 			 * Now parse for ename_"rotate" = {
6417c478bd9Sstevel@tonic-gate 			 *	period = XXX
6427c478bd9Sstevel@tonic-gate 			 * 	versions = 10
6437c478bd9Sstevel@tonic-gate 			 * }
6447c478bd9Sstevel@tonic-gate 			 */
6457c478bd9Sstevel@tonic-gate 			    if (strlen(ename) + strlen("_rotate") <
6467c478bd9Sstevel@tonic-gate 				sizeof (rotate_kw)) {
6477c478bd9Sstevel@tonic-gate 
6487c478bd9Sstevel@tonic-gate 				    char *time;
6497c478bd9Sstevel@tonic-gate 				    krb5_deltat	dt;
6507c478bd9Sstevel@tonic-gate 				    int vers;
6517c478bd9Sstevel@tonic-gate 
6527c478bd9Sstevel@tonic-gate 				    strcpy(rotate_kw, ename);
6537c478bd9Sstevel@tonic-gate 				    strcat(rotate_kw, "_rotate");
6547c478bd9Sstevel@tonic-gate 
6557c478bd9Sstevel@tonic-gate 				    if (!profile_get_string(kcontext->profile,
6567c478bd9Sstevel@tonic-gate 				        "logging", rotate_kw, "period",
6577c478bd9Sstevel@tonic-gate 					NULL, &time)) {
6587c478bd9Sstevel@tonic-gate 
6597c478bd9Sstevel@tonic-gate 					if (time != NULL) {
6607c478bd9Sstevel@tonic-gate 					    if (!krb5_string_to_deltat(time,
6617c478bd9Sstevel@tonic-gate 						&dt)) {
6627c478bd9Sstevel@tonic-gate 			log_control.log_entries[i].lfu_rotate_period =
6637c478bd9Sstevel@tonic-gate 							(time_t) dt;
6647c478bd9Sstevel@tonic-gate 					    }
6657c478bd9Sstevel@tonic-gate 					    free(time);
6667c478bd9Sstevel@tonic-gate 					}
6677c478bd9Sstevel@tonic-gate 				    }
6687c478bd9Sstevel@tonic-gate 
6697c478bd9Sstevel@tonic-gate 				    if (!profile_get_integer(
6707c478bd9Sstevel@tonic-gate 					kcontext->profile, "logging",
6717c478bd9Sstevel@tonic-gate 					rotate_kw, "versions",
6727c478bd9Sstevel@tonic-gate 					K_LOG_DEF_FILE_ROTATE_VERSIONS,
6737c478bd9Sstevel@tonic-gate 					&vers)) {
6747c478bd9Sstevel@tonic-gate 			log_control.log_entries[i].lfu_rotate_versions = vers;
6757c478bd9Sstevel@tonic-gate 				    }
6767c478bd9Sstevel@tonic-gate 
6777c478bd9Sstevel@tonic-gate 			   }
6787c478bd9Sstevel@tonic-gate 			} else {
6797c478bd9Sstevel@tonic-gate 			    fprintf(stderr, gettext("Couldn't open log file %s: %s\n"),
6807c478bd9Sstevel@tonic-gate 				    &cp[5], error_message(errno));
6817c478bd9Sstevel@tonic-gate 			    continue;
6827c478bd9Sstevel@tonic-gate 			}
6837c478bd9Sstevel@tonic-gate 		    }
6847c478bd9Sstevel@tonic-gate 		}
685*159d09a2SMark Phalan #ifdef	HAVE_SYSLOG
6867c478bd9Sstevel@tonic-gate 		/*
6877c478bd9Sstevel@tonic-gate 		 * Is this a syslog?
6887c478bd9Sstevel@tonic-gate 		 */
6897c478bd9Sstevel@tonic-gate 		else if (!strncasecmp(cp, "SYSLOG", 6)) {
6907c478bd9Sstevel@tonic-gate 		    error = 0;
6917c478bd9Sstevel@tonic-gate 		    log_control.log_entries[i].lsu_facility = LOG_AUTH;
6927c478bd9Sstevel@tonic-gate 		    log_control.log_entries[i].lsu_severity = LOG_ERR;
6937c478bd9Sstevel@tonic-gate 		    /*
6947c478bd9Sstevel@tonic-gate 		     * Is there a severify specified?
6957c478bd9Sstevel@tonic-gate 		     */
6967c478bd9Sstevel@tonic-gate 		    if (cp[6] == ':') {
6977c478bd9Sstevel@tonic-gate 			/*
6987c478bd9Sstevel@tonic-gate 			 * Find the end of the severity.
6997c478bd9Sstevel@tonic-gate 			 */
700*159d09a2SMark Phalan 			cp2 = strchr(&cp[7], ':');
701*159d09a2SMark Phalan 			if (cp2) {
7027c478bd9Sstevel@tonic-gate 			    savec = *cp2;
7037c478bd9Sstevel@tonic-gate 			    *cp2 = '\0';
7047c478bd9Sstevel@tonic-gate 			    cp2++;
7057c478bd9Sstevel@tonic-gate 			}
7067c478bd9Sstevel@tonic-gate 
7077c478bd9Sstevel@tonic-gate 			/*
7087c478bd9Sstevel@tonic-gate 			 * Match a severity.
7097c478bd9Sstevel@tonic-gate 			 */
7107c478bd9Sstevel@tonic-gate 			if (!strcasecmp(&cp[7], "ERR")) {
7117c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lsu_severity = LOG_ERR;
7127c478bd9Sstevel@tonic-gate 			}
713*159d09a2SMark Phalan #ifdef	LOG_EMERG
7147c478bd9Sstevel@tonic-gate 			else if (!strcasecmp(&cp[7], "EMERG")) {
7157c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lsu_severity =
7167c478bd9Sstevel@tonic-gate 				LOG_EMERG;
7177c478bd9Sstevel@tonic-gate 			}
718*159d09a2SMark Phalan #endif	/* LOG_EMERG */
719*159d09a2SMark Phalan #ifdef	LOG_ALERT
7207c478bd9Sstevel@tonic-gate 			else if (!strcasecmp(&cp[7], "ALERT")) {
7217c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lsu_severity =
7227c478bd9Sstevel@tonic-gate 				LOG_ALERT;
7237c478bd9Sstevel@tonic-gate 			}
724*159d09a2SMark Phalan #endif	/* LOG_ALERT */
725*159d09a2SMark Phalan #ifdef	LOG_CRIT
7267c478bd9Sstevel@tonic-gate 			else if (!strcasecmp(&cp[7], "CRIT")) {
7277c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lsu_severity = LOG_CRIT;
7287c478bd9Sstevel@tonic-gate 			}
729*159d09a2SMark Phalan #endif	/* LOG_CRIT */
730*159d09a2SMark Phalan #ifdef	LOG_WARNING
7317c478bd9Sstevel@tonic-gate 			else if (!strcasecmp(&cp[7], "WARNING")) {
7327c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lsu_severity =
7337c478bd9Sstevel@tonic-gate 				LOG_WARNING;
7347c478bd9Sstevel@tonic-gate 			}
735*159d09a2SMark Phalan #endif	/* LOG_WARNING */
736*159d09a2SMark Phalan #ifdef	LOG_NOTICE
7377c478bd9Sstevel@tonic-gate 			else if (!strcasecmp(&cp[7], "NOTICE")) {
7387c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lsu_severity =
7397c478bd9Sstevel@tonic-gate 				LOG_NOTICE;
7407c478bd9Sstevel@tonic-gate 			}
741*159d09a2SMark Phalan #endif	/* LOG_NOTICE */
742*159d09a2SMark Phalan #ifdef	LOG_INFO
7437c478bd9Sstevel@tonic-gate 			else if (!strcasecmp(&cp[7], "INFO")) {
7447c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lsu_severity = LOG_INFO;
7457c478bd9Sstevel@tonic-gate 			}
746*159d09a2SMark Phalan #endif	/* LOG_INFO */
747*159d09a2SMark Phalan #ifdef	LOG_DEBUG
7487c478bd9Sstevel@tonic-gate 			else if (!strcasecmp(&cp[7], "DEBUG")) {
7497c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lsu_severity =
7507c478bd9Sstevel@tonic-gate 				LOG_DEBUG;
7517c478bd9Sstevel@tonic-gate 			}
752*159d09a2SMark Phalan #endif	/* LOG_DEBUG */
7537c478bd9Sstevel@tonic-gate 			else
7547c478bd9Sstevel@tonic-gate 			    error = 1;
7557c478bd9Sstevel@tonic-gate 
7567c478bd9Sstevel@tonic-gate 			/*
7577c478bd9Sstevel@tonic-gate 			 * If there is a facility present, then parse that.
7587c478bd9Sstevel@tonic-gate 			 */
7597c478bd9Sstevel@tonic-gate 			if (cp2) {
7607c478bd9Sstevel@tonic-gate 			    if (!strcasecmp(cp2, "AUTH")) {
7617c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_AUTH;
7627c478bd9Sstevel@tonic-gate 			    }
7637c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "KERN")) {
7647c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_KERN;
7657c478bd9Sstevel@tonic-gate 			    }
7667c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "USER")) {
7677c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_USER;
7687c478bd9Sstevel@tonic-gate 			    }
7697c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "MAIL")) {
7707c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_MAIL;
7717c478bd9Sstevel@tonic-gate 			    }
7727c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "DAEMON")) {
7737c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_DAEMON;
7747c478bd9Sstevel@tonic-gate 			    }
7757c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "LPR")) {
7767c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_LPR;
7777c478bd9Sstevel@tonic-gate 			    }
7787c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "NEWS")) {
7797c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_NEWS;
7807c478bd9Sstevel@tonic-gate 			    }
7817c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "UUCP")) {
7827c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_UUCP;
7837c478bd9Sstevel@tonic-gate 			    }
7847c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "CRON")) {
7857c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_CRON;
7867c478bd9Sstevel@tonic-gate 			    }
7877c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "LOCAL0")) {
7887c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_LOCAL0;
7897c478bd9Sstevel@tonic-gate 			    }
7907c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "LOCAL1")) {
7917c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_LOCAL1;
7927c478bd9Sstevel@tonic-gate 			    }
7937c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "LOCAL2")) {
7947c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_LOCAL2;
7957c478bd9Sstevel@tonic-gate 			    }
7967c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "LOCAL3")) {
7977c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_LOCAL3;
7987c478bd9Sstevel@tonic-gate 			    }
7997c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "LOCAL4")) {
8007c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_LOCAL4;
8017c478bd9Sstevel@tonic-gate 			    }
8027c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "LOCAL5")) {
8037c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_LOCAL5;
8047c478bd9Sstevel@tonic-gate 			    }
8057c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "LOCAL6")) {
8067c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_LOCAL6;
8077c478bd9Sstevel@tonic-gate 			    }
8087c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "LOCAL7")) {
8097c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_LOCAL7;
8107c478bd9Sstevel@tonic-gate 			    }
8117c478bd9Sstevel@tonic-gate 			    cp2--;
8127c478bd9Sstevel@tonic-gate 			    *cp2 = savec;
8137c478bd9Sstevel@tonic-gate 			}
8147c478bd9Sstevel@tonic-gate 		    }
8157c478bd9Sstevel@tonic-gate 		    if (!error) {
8167c478bd9Sstevel@tonic-gate 			log_control.log_entries[i].log_type = K_LOG_SYSLOG;
8177c478bd9Sstevel@tonic-gate 			do_openlog = 1;
8187c478bd9Sstevel@tonic-gate 			log_facility = log_control.log_entries[i].lsu_facility;
8197c478bd9Sstevel@tonic-gate 		    }
8207c478bd9Sstevel@tonic-gate 		}
821*159d09a2SMark Phalan #endif	/* HAVE_SYSLOG */
8227c478bd9Sstevel@tonic-gate 		/*
8237c478bd9Sstevel@tonic-gate 		 * Is this a standard error specification?
8247c478bd9Sstevel@tonic-gate 		 */
8257c478bd9Sstevel@tonic-gate 		else if (!strcasecmp(cp, "STDERR")) {
826*159d09a2SMark Phalan 		    log_control.log_entries[i].lfu_filep =
827*159d09a2SMark Phalan 			fdopen(fileno(stderr), "a+F");
828*159d09a2SMark Phalan 		    if (log_control.log_entries[i].lfu_filep) {
8297c478bd9Sstevel@tonic-gate 			log_control.log_entries[i].log_type = K_LOG_STDERR;
8307c478bd9Sstevel@tonic-gate 			log_control.log_entries[i].lfu_fname =
8317c478bd9Sstevel@tonic-gate 			    "standard error";
8327c478bd9Sstevel@tonic-gate 		    }
8337c478bd9Sstevel@tonic-gate 		}
8347c478bd9Sstevel@tonic-gate 		/*
8357c478bd9Sstevel@tonic-gate 		 * Is this a specification of the console?
8367c478bd9Sstevel@tonic-gate 		 */
8377c478bd9Sstevel@tonic-gate 		else if (!strcasecmp(cp, "CONSOLE")) {
838*159d09a2SMark Phalan 		    log_control.log_entries[i].ldu_filep =
839*159d09a2SMark Phalan 			CONSOLE_OPEN("a+F");
840*159d09a2SMark Phalan 		    if (log_control.log_entries[i].ldu_filep) {
8417c478bd9Sstevel@tonic-gate 			log_control.log_entries[i].log_type = K_LOG_CONSOLE;
8427c478bd9Sstevel@tonic-gate 			log_control.log_entries[i].ldu_devname = "console";
8437c478bd9Sstevel@tonic-gate 		    }
8447c478bd9Sstevel@tonic-gate 		}
8457c478bd9Sstevel@tonic-gate 		/*
8467c478bd9Sstevel@tonic-gate 		 * Is this a specification of a device?
8477c478bd9Sstevel@tonic-gate 		 */
8487c478bd9Sstevel@tonic-gate 		else if (!strncasecmp(cp, "DEVICE", 6)) {
8497c478bd9Sstevel@tonic-gate 		    /*
8507c478bd9Sstevel@tonic-gate 		     * We handle devices very similarly to files.
8517c478bd9Sstevel@tonic-gate 		     */
8527c478bd9Sstevel@tonic-gate 		    if (cp[6] == '=') {
853*159d09a2SMark Phalan 			log_control.log_entries[i].ldu_filep =
854*159d09a2SMark Phalan 			    DEVICE_OPEN(&cp[7], "wF");
855*159d09a2SMark Phalan 			if (log_control.log_entries[i].ldu_filep) {
8567c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].log_type = K_LOG_DEVICE;
8577c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].ldu_devname = &cp[7];
8587c478bd9Sstevel@tonic-gate 			}
8597c478bd9Sstevel@tonic-gate 		    }
8607c478bd9Sstevel@tonic-gate 		}
8617c478bd9Sstevel@tonic-gate 		/*
8627c478bd9Sstevel@tonic-gate 		 * See if we successfully parsed this specification.
8637c478bd9Sstevel@tonic-gate 		 */
8647c478bd9Sstevel@tonic-gate 		if (log_control.log_entries[i].log_type == K_LOG_NONE) {
8657c478bd9Sstevel@tonic-gate 		    fprintf(stderr, krb5_log_error_table(LSPEC_PARSE_ERR_1), whoami, cp);
8667c478bd9Sstevel@tonic-gate 		    fprintf(stderr, krb5_log_error_table(LSPEC_PARSE_ERR_2), whoami);
8677c478bd9Sstevel@tonic-gate 		}
8687c478bd9Sstevel@tonic-gate 		else
8697c478bd9Sstevel@tonic-gate 		    ngood++;
8707c478bd9Sstevel@tonic-gate 	    }
8717c478bd9Sstevel@tonic-gate 	}
8727c478bd9Sstevel@tonic-gate 	/*
8737c478bd9Sstevel@tonic-gate 	 * If we didn't find anything, then free our lists.
8747c478bd9Sstevel@tonic-gate 	 */
8757c478bd9Sstevel@tonic-gate 	if (ngood == 0) {
8767c478bd9Sstevel@tonic-gate 	    for (i=0; i<log_control.log_nentries; i++)
8777c478bd9Sstevel@tonic-gate 		free(logging_specs[i]);
8787c478bd9Sstevel@tonic-gate 	}
8797c478bd9Sstevel@tonic-gate 	free(logging_specs);
8807c478bd9Sstevel@tonic-gate     }
8817c478bd9Sstevel@tonic-gate     /*
8827c478bd9Sstevel@tonic-gate      * If we didn't find anything, go for the default which is to log to
8837c478bd9Sstevel@tonic-gate      * the system log.
8847c478bd9Sstevel@tonic-gate      */
8857c478bd9Sstevel@tonic-gate     if (ngood == 0) {
8867c478bd9Sstevel@tonic-gate 	if (log_control.log_entries)
8877c478bd9Sstevel@tonic-gate 	    free(log_control.log_entries);
8887c478bd9Sstevel@tonic-gate 	log_control.log_entries = &def_log_entry;
8897c478bd9Sstevel@tonic-gate 	log_control.log_entries->log_type = K_LOG_SYSLOG;
8907c478bd9Sstevel@tonic-gate 	log_control.log_entries->log_2free = (krb5_pointer) NULL;
8917c478bd9Sstevel@tonic-gate 	log_facility = log_control.log_entries->lsu_facility = LOG_AUTH;
8927c478bd9Sstevel@tonic-gate 	log_control.log_entries->lsu_severity = LOG_ERR;
8937c478bd9Sstevel@tonic-gate 	do_openlog = 1;
8947c478bd9Sstevel@tonic-gate 	log_control.log_nentries = 1;
8957c478bd9Sstevel@tonic-gate     }
8967c478bd9Sstevel@tonic-gate     if (log_control.log_nentries) {
897*159d09a2SMark Phalan 	log_control.log_whoami = (char *) malloc(strlen(whoami)+1);
898*159d09a2SMark Phalan 	if (log_control.log_whoami)
8997c478bd9Sstevel@tonic-gate 	    strcpy(log_control.log_whoami, whoami);
900*159d09a2SMark Phalan 
901*159d09a2SMark Phalan 	log_control.log_hostname = (char *) malloc(MAXHOSTNAMELEN + 1);
902*159d09a2SMark Phalan 	if (log_control.log_hostname) {
9037c478bd9Sstevel@tonic-gate 	    gethostname(log_control.log_hostname, MAXHOSTNAMELEN);
904*159d09a2SMark Phalan 	    log_control.log_hostname[MAXHOSTNAMELEN] = '\0';
905*159d09a2SMark Phalan 	}
906*159d09a2SMark Phalan #ifdef	HAVE_OPENLOG
9077c478bd9Sstevel@tonic-gate 	if (do_openlog) {
9087c478bd9Sstevel@tonic-gate 	    openlog(whoami, LOG_NDELAY|LOG_PID, log_facility);
9097c478bd9Sstevel@tonic-gate 	    log_control.log_opened = 1;
9107c478bd9Sstevel@tonic-gate 	}
911*159d09a2SMark Phalan #endif /* HAVE_OPENLOG */
9127c478bd9Sstevel@tonic-gate 	if (do_com_err)
9137c478bd9Sstevel@tonic-gate 	    (void) set_com_err_hook(klog_com_err_proc);
9147c478bd9Sstevel@tonic-gate     }
9157c478bd9Sstevel@tonic-gate     return((log_control.log_nentries) ? 0 : ENOENT);
9167c478bd9Sstevel@tonic-gate }
9177c478bd9Sstevel@tonic-gate 
9187c478bd9Sstevel@tonic-gate /*
9197c478bd9Sstevel@tonic-gate  * krb5_klog_close()	- Close the logging context and free all data.
9207c478bd9Sstevel@tonic-gate  */
9217c478bd9Sstevel@tonic-gate void
krb5_klog_close(krb5_context kcontext)922*159d09a2SMark Phalan krb5_klog_close(krb5_context kcontext)
9237c478bd9Sstevel@tonic-gate {
9247c478bd9Sstevel@tonic-gate     int lindex;
9257c478bd9Sstevel@tonic-gate     (void) reset_com_err_hook();
9267c478bd9Sstevel@tonic-gate     for (lindex = 0; lindex < log_control.log_nentries; lindex++) {
9277c478bd9Sstevel@tonic-gate 	switch (log_control.log_entries[lindex].log_type) {
9287c478bd9Sstevel@tonic-gate 	case K_LOG_FILE:
9297c478bd9Sstevel@tonic-gate 	case K_LOG_STDERR:
9307c478bd9Sstevel@tonic-gate 	    /*
9317c478bd9Sstevel@tonic-gate 	     * Files/standard error.
9327c478bd9Sstevel@tonic-gate 	     */
9337c478bd9Sstevel@tonic-gate 	    fclose(log_control.log_entries[lindex].lfu_filep);
9347c478bd9Sstevel@tonic-gate 	    break;
9357c478bd9Sstevel@tonic-gate 	case K_LOG_CONSOLE:
9367c478bd9Sstevel@tonic-gate 	case K_LOG_DEVICE:
9377c478bd9Sstevel@tonic-gate 	    /*
9387c478bd9Sstevel@tonic-gate 	     * Devices (may need special handling)
9397c478bd9Sstevel@tonic-gate 	     */
9407c478bd9Sstevel@tonic-gate 	    DEVICE_CLOSE(log_control.log_entries[lindex].ldu_filep);
9417c478bd9Sstevel@tonic-gate 	    break;
942*159d09a2SMark Phalan #ifdef	HAVE_SYSLOG
9437c478bd9Sstevel@tonic-gate 	case K_LOG_SYSLOG:
9447c478bd9Sstevel@tonic-gate 	    /*
9457c478bd9Sstevel@tonic-gate 	     * System log.
9467c478bd9Sstevel@tonic-gate 	     */
9477c478bd9Sstevel@tonic-gate 	    break;
948*159d09a2SMark Phalan #endif	/* HAVE_SYSLOG */
9497c478bd9Sstevel@tonic-gate 	default:
9507c478bd9Sstevel@tonic-gate 	    break;
9517c478bd9Sstevel@tonic-gate 	}
9527c478bd9Sstevel@tonic-gate 	if (log_control.log_entries[lindex].log_2free)
9537c478bd9Sstevel@tonic-gate 	    free(log_control.log_entries[lindex].log_2free);
9547c478bd9Sstevel@tonic-gate     }
9557c478bd9Sstevel@tonic-gate     if (log_control.log_entries != &def_log_entry)
9567c478bd9Sstevel@tonic-gate 	free(log_control.log_entries);
9577c478bd9Sstevel@tonic-gate     log_control.log_entries = (struct log_entry *) NULL;
9587c478bd9Sstevel@tonic-gate     log_control.log_nentries = 0;
9597c478bd9Sstevel@tonic-gate     if (log_control.log_whoami)
9607c478bd9Sstevel@tonic-gate 	free(log_control.log_whoami);
9617c478bd9Sstevel@tonic-gate     log_control.log_whoami = (char *) NULL;
9627c478bd9Sstevel@tonic-gate     if (log_control.log_hostname)
9637c478bd9Sstevel@tonic-gate 	free(log_control.log_hostname);
9647c478bd9Sstevel@tonic-gate     log_control.log_hostname = (char *) NULL;
965*159d09a2SMark Phalan #ifdef	HAVE_CLOSELOG
9667c478bd9Sstevel@tonic-gate     if (log_control.log_opened)
9677c478bd9Sstevel@tonic-gate 	closelog();
968*159d09a2SMark Phalan #endif	/* HAVE_CLOSELOG */
9697c478bd9Sstevel@tonic-gate }
9707c478bd9Sstevel@tonic-gate 
9717c478bd9Sstevel@tonic-gate /*
9727c478bd9Sstevel@tonic-gate  * severity2string()	- Convert a severity to a string.
9737c478bd9Sstevel@tonic-gate  */
974*159d09a2SMark Phalan static const char *
severity2string(int severity)975*159d09a2SMark Phalan severity2string(int severity)
9767c478bd9Sstevel@tonic-gate {
9777c478bd9Sstevel@tonic-gate     int s;
9787c478bd9Sstevel@tonic-gate     const char *ss;
9797c478bd9Sstevel@tonic-gate 
9807c478bd9Sstevel@tonic-gate     s = severity & LOG_PRIMASK;
9817c478bd9Sstevel@tonic-gate     ss = krb5_log_error_table(LOG_UFO_STRING);
9827c478bd9Sstevel@tonic-gate     switch (s) {
983*159d09a2SMark Phalan #ifdef	LOG_EMERG
9847c478bd9Sstevel@tonic-gate     case LOG_EMERG:
9857c478bd9Sstevel@tonic-gate 	ss = krb5_log_error_table(LOG_EMERG_STRING);
9867c478bd9Sstevel@tonic-gate 	break;
987*159d09a2SMark Phalan #endif	/* LOG_EMERG */
988*159d09a2SMark Phalan #ifdef	LOG_ALERT
9897c478bd9Sstevel@tonic-gate     case LOG_ALERT:
9907c478bd9Sstevel@tonic-gate 	ss = krb5_log_error_table(LOG_ALERT_STRING);
9917c478bd9Sstevel@tonic-gate 	break;
992*159d09a2SMark Phalan #endif	/* LOG_ALERT */
993*159d09a2SMark Phalan #ifdef	LOG_CRIT
9947c478bd9Sstevel@tonic-gate     case LOG_CRIT:
9957c478bd9Sstevel@tonic-gate 	ss = krb5_log_error_table(LOG_CRIT_STRING);
9967c478bd9Sstevel@tonic-gate 	break;
997*159d09a2SMark Phalan #endif	/* LOG_CRIT */
9987c478bd9Sstevel@tonic-gate     case LOG_ERR:
9997c478bd9Sstevel@tonic-gate 	ss = krb5_log_error_table(LOG_ERR_STRING);
10007c478bd9Sstevel@tonic-gate 	break;
1001*159d09a2SMark Phalan #ifdef	LOG_WARNING
10027c478bd9Sstevel@tonic-gate     case LOG_WARNING:
10037c478bd9Sstevel@tonic-gate 	ss = krb5_log_error_table(LOG_WARNING_STRING);
10047c478bd9Sstevel@tonic-gate 	break;
1005*159d09a2SMark Phalan #endif	/* LOG_WARNING */
1006*159d09a2SMark Phalan #ifdef	LOG_NOTICE
10077c478bd9Sstevel@tonic-gate     case LOG_NOTICE:
10087c478bd9Sstevel@tonic-gate 	ss = krb5_log_error_table(LOG_NOTICE_STRING);
10097c478bd9Sstevel@tonic-gate 	break;
1010*159d09a2SMark Phalan #endif	/* LOG_NOTICE */
1011*159d09a2SMark Phalan #ifdef	LOG_INFO
10127c478bd9Sstevel@tonic-gate     case LOG_INFO:
10137c478bd9Sstevel@tonic-gate 	ss = krb5_log_error_table(LOG_INFO_STRING);
10147c478bd9Sstevel@tonic-gate 	break;
1015*159d09a2SMark Phalan #endif	/* LOG_INFO */
1016*159d09a2SMark Phalan #ifdef	LOG_DEBUG
10177c478bd9Sstevel@tonic-gate     case LOG_DEBUG:
10187c478bd9Sstevel@tonic-gate 	ss = krb5_log_error_table(LOG_DEBUG_STRING);
10197c478bd9Sstevel@tonic-gate 	break;
1020*159d09a2SMark Phalan #endif	/* LOG_DEBUG */
10217c478bd9Sstevel@tonic-gate     }
10227c478bd9Sstevel@tonic-gate     return((char *) ss);
10237c478bd9Sstevel@tonic-gate }
10247c478bd9Sstevel@tonic-gate 
10257c478bd9Sstevel@tonic-gate /*
10267c478bd9Sstevel@tonic-gate  * krb5_klog_syslog()	- Simulate the calling sequence of syslog(3), while
10277c478bd9Sstevel@tonic-gate  *			  also performing the logging redirection as specified
10287c478bd9Sstevel@tonic-gate  *			  by krb5_klog_init().
10297c478bd9Sstevel@tonic-gate  */
10307c478bd9Sstevel@tonic-gate static int
klog_vsyslog(int priority,const char * format,va_list arglist)1031*159d09a2SMark Phalan klog_vsyslog(int priority, const char *format, va_list arglist)
10327c478bd9Sstevel@tonic-gate {
10337c478bd9Sstevel@tonic-gate     char	outbuf[KRB5_KLOG_MAX_ERRMSG_SIZE];
10347c478bd9Sstevel@tonic-gate     int		lindex;
10357c478bd9Sstevel@tonic-gate     char	*syslogp;
10367c478bd9Sstevel@tonic-gate     char	*cp;
10377c478bd9Sstevel@tonic-gate     time_t	now;
1038*159d09a2SMark Phalan #ifdef	HAVE_STRFTIME
10397c478bd9Sstevel@tonic-gate     size_t	soff;
1040*159d09a2SMark Phalan #endif	/* HAVE_STRFTIME */
10417c478bd9Sstevel@tonic-gate 
10427c478bd9Sstevel@tonic-gate     /*
10437c478bd9Sstevel@tonic-gate      * Format a syslog-esque message of the format:
10447c478bd9Sstevel@tonic-gate      *
10457c478bd9Sstevel@tonic-gate      * (verbose form)
10467c478bd9Sstevel@tonic-gate      * 		<date> <hostname> <id>[<pid>](<priority>): <message>
10477c478bd9Sstevel@tonic-gate      *
10487c478bd9Sstevel@tonic-gate      * (short form)
10497c478bd9Sstevel@tonic-gate      *		<date> <message>
10507c478bd9Sstevel@tonic-gate      */
10517c478bd9Sstevel@tonic-gate     cp = outbuf;
10527c478bd9Sstevel@tonic-gate     (void) time(&now);
1053*159d09a2SMark Phalan #ifdef	HAVE_STRFTIME
10547c478bd9Sstevel@tonic-gate     /*
10557c478bd9Sstevel@tonic-gate      * Format the date: mon dd hh:mm:ss
10567c478bd9Sstevel@tonic-gate      */
10577c478bd9Sstevel@tonic-gate     soff = strftime(outbuf, sizeof(outbuf), "%b %d %H:%M:%S", localtime(&now));
10587c478bd9Sstevel@tonic-gate     if (soff > 0)
10597c478bd9Sstevel@tonic-gate 	cp += soff;
10607c478bd9Sstevel@tonic-gate     else
10617c478bd9Sstevel@tonic-gate 	return(-1);
1062*159d09a2SMark Phalan #else	/* HAVE_STRFTIME */
1063*159d09a2SMark Phalan     /*
1064*159d09a2SMark Phalan      * Format the date:
1065*159d09a2SMark Phalan      * We ASSUME here that the output of ctime is of the format:
1066*159d09a2SMark Phalan      *	dow mon dd hh:mm:ss tzs yyyy\n
1067*159d09a2SMark Phalan      *  012345678901234567890123456789
1068*159d09a2SMark Phalan      */
1069*159d09a2SMark Phalan     strncpy(outbuf, ctime(&now) + 4, 15);
1070*159d09a2SMark Phalan     cp += 15;
1071*159d09a2SMark Phalan #endif	/* HAVE_STRFTIME */
10727c478bd9Sstevel@tonic-gate #ifdef VERBOSE_LOGS
10737c478bd9Sstevel@tonic-gate     sprintf(cp, " %s %s[%ld](%s): ",
10747c478bd9Sstevel@tonic-gate 	    log_control.log_hostname, log_control.log_whoami, (long) getpid(),
10757c478bd9Sstevel@tonic-gate 	    severity2string(priority));
10767c478bd9Sstevel@tonic-gate #else
10777c478bd9Sstevel@tonic-gate     sprintf(cp, " ");
10787c478bd9Sstevel@tonic-gate #endif
10797c478bd9Sstevel@tonic-gate     syslogp = &outbuf[strlen(outbuf)];
10807c478bd9Sstevel@tonic-gate 
10817c478bd9Sstevel@tonic-gate     /* Now format the actual message */
1082*159d09a2SMark Phalan #ifdef	HAVE_VSNPRINTF
108346736d35Ssemery     vsnprintf(syslogp, sizeof(outbuf) - (syslogp - outbuf), format, arglist);
1084*159d09a2SMark Phalan #elif	HAVE_VSPRINTF
1085*159d09a2SMark Phalan     vsprintf(syslogp, format, arglist);
1086*159d09a2SMark Phalan #else	/* HAVE_VSPRINTF */
1087*159d09a2SMark Phalan     sprintf(syslogp, format, ((int *) arglist)[0], ((int *) arglist)[1],
1088*159d09a2SMark Phalan 	    ((int *) arglist)[2], ((int *) arglist)[3],
1089*159d09a2SMark Phalan 	    ((int *) arglist)[4], ((int *) arglist)[5]);
1090*159d09a2SMark Phalan #endif	/* HAVE_VSPRINTF */
1091*159d09a2SMark Phalan 
1092*159d09a2SMark Phalan     /*
1093*159d09a2SMark Phalan      * If the user did not use krb5_klog_init() instead of dropping
1094*159d09a2SMark Phalan      * the request on the floor, syslog it - if it exists
1095*159d09a2SMark Phalan      */
1096*159d09a2SMark Phalan #ifdef HAVE_SYSLOG
1097*159d09a2SMark Phalan     if (log_control.log_nentries == 0) {
1098*159d09a2SMark Phalan 	/* Log the message with our header trimmed off */
1099*159d09a2SMark Phalan 	syslog(priority, "%s", syslogp);
1100*159d09a2SMark Phalan     }
1101*159d09a2SMark Phalan #endif
11027c478bd9Sstevel@tonic-gate 
11037c478bd9Sstevel@tonic-gate     /*
11047c478bd9Sstevel@tonic-gate      * Now that we have the message formatted, perform the output to each
11057c478bd9Sstevel@tonic-gate      * logging specification.
11067c478bd9Sstevel@tonic-gate      */
11077c478bd9Sstevel@tonic-gate     for (lindex = 0; lindex < log_control.log_nentries; lindex++) {
11087c478bd9Sstevel@tonic-gate 	switch (log_control.log_entries[lindex].log_type) {
11097c478bd9Sstevel@tonic-gate 	case K_LOG_FILE:
11107c478bd9Sstevel@tonic-gate 
11117c478bd9Sstevel@tonic-gate 	    klog_rotate(&log_control.log_entries[lindex]);
11127c478bd9Sstevel@tonic-gate 	    /*FALLTHRU*/
11137c478bd9Sstevel@tonic-gate 	case K_LOG_STDERR:
11147c478bd9Sstevel@tonic-gate 	    /*
11157c478bd9Sstevel@tonic-gate 	     * Files/standard error.
11167c478bd9Sstevel@tonic-gate 	     */
11177c478bd9Sstevel@tonic-gate 	    if (fprintf(log_control.log_entries[lindex].lfu_filep, "%s\n",
11187c478bd9Sstevel@tonic-gate 			outbuf) < 0) {
11197c478bd9Sstevel@tonic-gate 		/* Attempt to report error */
11207c478bd9Sstevel@tonic-gate 		fprintf(stderr, krb5_log_error_table(LOG_FILE_ERR),
11217c478bd9Sstevel@tonic-gate 			log_control.log_whoami,
11227c478bd9Sstevel@tonic-gate 			log_control.log_entries[lindex].lfu_fname);
11237c478bd9Sstevel@tonic-gate 	    }
11247c478bd9Sstevel@tonic-gate 	    else {
11257c478bd9Sstevel@tonic-gate 		fflush(log_control.log_entries[lindex].lfu_filep);
11267c478bd9Sstevel@tonic-gate 	    }
11277c478bd9Sstevel@tonic-gate 	    break;
11287c478bd9Sstevel@tonic-gate 	case K_LOG_CONSOLE:
11297c478bd9Sstevel@tonic-gate 	case K_LOG_DEVICE:
11307c478bd9Sstevel@tonic-gate 	    /*
11317c478bd9Sstevel@tonic-gate 	     * Devices (may need special handling)
11327c478bd9Sstevel@tonic-gate 	     */
11337c478bd9Sstevel@tonic-gate 	    if (DEVICE_PRINT(log_control.log_entries[lindex].ldu_filep,
11347c478bd9Sstevel@tonic-gate 			     outbuf) < 0) {
11357c478bd9Sstevel@tonic-gate 		/* Attempt to report error */
11367c478bd9Sstevel@tonic-gate 		fprintf(stderr, krb5_log_error_table(LOG_DEVICE_ERR),
11377c478bd9Sstevel@tonic-gate 			log_control.log_whoami,
11387c478bd9Sstevel@tonic-gate 			log_control.log_entries[lindex].ldu_devname);
11397c478bd9Sstevel@tonic-gate 	    }
11407c478bd9Sstevel@tonic-gate 	    break;
1141*159d09a2SMark Phalan #ifdef	HAVE_SYSLOG
11427c478bd9Sstevel@tonic-gate 	case K_LOG_SYSLOG:
11437c478bd9Sstevel@tonic-gate 	    /*
11447c478bd9Sstevel@tonic-gate 	     * System log.
11457c478bd9Sstevel@tonic-gate 	     */
11467c478bd9Sstevel@tonic-gate 
11477c478bd9Sstevel@tonic-gate 	    /* Log the message with our header trimmed off */
11487c478bd9Sstevel@tonic-gate 	    syslog(priority, "%s", syslogp);
11497c478bd9Sstevel@tonic-gate 	    break;
1150*159d09a2SMark Phalan #endif /* HAVE_SYSLOG */
11517c478bd9Sstevel@tonic-gate 	default:
11527c478bd9Sstevel@tonic-gate 	    break;
11537c478bd9Sstevel@tonic-gate 	}
11547c478bd9Sstevel@tonic-gate     }
11557c478bd9Sstevel@tonic-gate     return(0);
11567c478bd9Sstevel@tonic-gate }
11577c478bd9Sstevel@tonic-gate 
11587c478bd9Sstevel@tonic-gate int
krb5_klog_syslog(int priority,const char * format,...)11597c478bd9Sstevel@tonic-gate krb5_klog_syslog(int priority, const char *format, ...)
11607c478bd9Sstevel@tonic-gate {
11617c478bd9Sstevel@tonic-gate     int		retval;
11627c478bd9Sstevel@tonic-gate     va_list	pvar;
11637c478bd9Sstevel@tonic-gate 
11647c478bd9Sstevel@tonic-gate     va_start(pvar, format);
11657c478bd9Sstevel@tonic-gate     retval = klog_vsyslog(priority, format, pvar);
11667c478bd9Sstevel@tonic-gate     va_end(pvar);
11677c478bd9Sstevel@tonic-gate     return(retval);
11687c478bd9Sstevel@tonic-gate }
11697c478bd9Sstevel@tonic-gate 
11707c478bd9Sstevel@tonic-gate /*
11717c478bd9Sstevel@tonic-gate  * krb5_klog_reopen() - Close and reopen any open (non-syslog) log files.
11727c478bd9Sstevel@tonic-gate  *                      This function is called when a SIGHUP is received
11737c478bd9Sstevel@tonic-gate  *                      so that external log-archival utilities may
11747c478bd9Sstevel@tonic-gate  *                      alert the Kerberos daemons that they should get
11757c478bd9Sstevel@tonic-gate  *                      a new file descriptor for the give filename.
11767c478bd9Sstevel@tonic-gate  */
11777c478bd9Sstevel@tonic-gate void
krb5_klog_reopen(krb5_context kcontext)1178*159d09a2SMark Phalan krb5_klog_reopen(krb5_context kcontext)
11797c478bd9Sstevel@tonic-gate {
11807c478bd9Sstevel@tonic-gate     int lindex;
11817c478bd9Sstevel@tonic-gate     FILE *f;
11827c478bd9Sstevel@tonic-gate 
11837c478bd9Sstevel@tonic-gate     /*
11847c478bd9Sstevel@tonic-gate      * Only logs which are actually files need to be closed
11857c478bd9Sstevel@tonic-gate      * and reopened in response to a SIGHUP
11867c478bd9Sstevel@tonic-gate      */
11877c478bd9Sstevel@tonic-gate     for (lindex = 0; lindex < log_control.log_nentries; lindex++) {
11887c478bd9Sstevel@tonic-gate 	if (log_control.log_entries[lindex].log_type == K_LOG_FILE) {
11897c478bd9Sstevel@tonic-gate 	    fclose(log_control.log_entries[lindex].lfu_filep);
11907c478bd9Sstevel@tonic-gate 	    /*
11917c478bd9Sstevel@tonic-gate 	     * In case the old logfile did not get moved out of the
11927c478bd9Sstevel@tonic-gate 	     * way, open for append to prevent squashing the old logs.
11937c478bd9Sstevel@tonic-gate 	     */
1194004388ebScasper 	    f = fopen(log_control.log_entries[lindex].lfu_fname, "a+F");
11957c478bd9Sstevel@tonic-gate 	    if (f) {
11967c478bd9Sstevel@tonic-gate 		log_control.log_entries[lindex].lfu_filep = f;
11977c478bd9Sstevel@tonic-gate 	    } else {
11987c478bd9Sstevel@tonic-gate 		fprintf(stderr, "Couldn't open log file %s: %s\n",
11997c478bd9Sstevel@tonic-gate 			log_control.log_entries[lindex].lfu_fname,
12007c478bd9Sstevel@tonic-gate 			error_message(errno));
12017c478bd9Sstevel@tonic-gate 	    }
12027c478bd9Sstevel@tonic-gate 	}
12037c478bd9Sstevel@tonic-gate     }
12047c478bd9Sstevel@tonic-gate }
12057c64d375Smp153739 
12067c64d375Smp153739 /*
12077c64d375Smp153739  * Solaris Kerberos:
12087c64d375Smp153739  * Switch the current context to the one supplied
12097c64d375Smp153739  */
krb5_klog_set_context(krb5_context context)12107c64d375Smp153739 void krb5_klog_set_context(krb5_context context) {
12117c64d375Smp153739 	err_context = context;
12127c64d375Smp153739 }
12137c64d375Smp153739 
12147c64d375Smp153739 /*
12157c64d375Smp153739  * Solaris Kerberos:
12167c64d375Smp153739  * Return a string representation of "facility"
12177c64d375Smp153739  */
facility2string(int facility)12187c64d375Smp153739 static const char * facility2string(int facility) {
12197c64d375Smp153739 	switch (facility) {
12207c64d375Smp153739 		case (LOG_AUTH):
12217c64d375Smp153739 			return ("AUTH");
12227c64d375Smp153739 		case (LOG_KERN):
12237c64d375Smp153739 			return ("KERN");
12247c64d375Smp153739 		case (LOG_USER):
12257c64d375Smp153739 			return ("USER");
12267c64d375Smp153739 		case (LOG_MAIL):
12277c64d375Smp153739 			return ("MAIL");
12287c64d375Smp153739 		case (LOG_DAEMON):
12297c64d375Smp153739 			return ("DAEMON");
12307c64d375Smp153739 		case (LOG_LPR):
12317c64d375Smp153739 			return ("LPR");
12327c64d375Smp153739 		case (LOG_NEWS):
12337c64d375Smp153739 			return ("NEWS");
12347c64d375Smp153739 		case (LOG_UUCP):
12357c64d375Smp153739 			return ("UUCP");
12367c64d375Smp153739 		case (LOG_CRON):
12377c64d375Smp153739 			return ("CRON");
12387c64d375Smp153739 		case (LOG_LOCAL0):
12397c64d375Smp153739 			return ("LOCAL0");
12407c64d375Smp153739 		case (LOG_LOCAL1):
12417c64d375Smp153739 			return ("LOCAL1");
12427c64d375Smp153739 		case (LOG_LOCAL2):
12437c64d375Smp153739 			return ("LOCAL2");
12447c64d375Smp153739 		case (LOG_LOCAL3):
12457c64d375Smp153739 			return ("LOCAL3");
12467c64d375Smp153739 		case (LOG_LOCAL4):
12477c64d375Smp153739 			return ("LOCAL4");
12487c64d375Smp153739 		case (LOG_LOCAL5):
12497c64d375Smp153739 			return ("LOCAL6");
12507c64d375Smp153739 		case (LOG_LOCAL7):
12517c64d375Smp153739 			return ("LOCAL7");
12527c64d375Smp153739 	}
12537c64d375Smp153739 	return ("UNKNOWN");
12547c64d375Smp153739 }
12557c64d375Smp153739 
12567c64d375Smp153739 /*
12577c64d375Smp153739  * Solaris Kerberos:
12587c64d375Smp153739  * Print to stderr where logging is being done
12597c64d375Smp153739  */
krb5_klog_list_logs(const char * whoami)12607c64d375Smp153739 krb5_error_code krb5_klog_list_logs(const char *whoami) {
12617c64d375Smp153739 	int lindex;
12627c64d375Smp153739 
12637c64d375Smp153739 	fprintf(stderr, gettext("%s: logging to "), whoami);
12647c64d375Smp153739 	for (lindex = 0; lindex < log_control.log_nentries; lindex++) {
12657c64d375Smp153739 		if (lindex != 0 && log_control.log_entries[lindex].log_type != K_LOG_NONE)
12667c64d375Smp153739 			fprintf(stderr, ", ");
12677c64d375Smp153739 		switch (log_control.log_entries[lindex].log_type) {
12687c64d375Smp153739 			case K_LOG_FILE:
12697c64d375Smp153739 				fprintf(stderr, "FILE=%s", log_control.log_entries[lindex].lfu_fname);
12707c64d375Smp153739 				break;
12717c64d375Smp153739 			case K_LOG_STDERR:
12727c64d375Smp153739 				fprintf(stderr, "STDERR");
12737c64d375Smp153739 				break;
12747c64d375Smp153739 			case K_LOG_CONSOLE:
12757c64d375Smp153739 				fprintf(stderr, "CONSOLE");
12767c64d375Smp153739 				break;
12777c64d375Smp153739 			case K_LOG_DEVICE:
12787c64d375Smp153739 				fprintf(stderr, "DEVICE=%s", log_control.log_entries[lindex].ldu_devname);
12797c64d375Smp153739 				break;
12807c64d375Smp153739 			case K_LOG_SYSLOG:
12817c64d375Smp153739 				fprintf(stderr, "SYSLOG=%s:%s",
12827c64d375Smp153739 				    severity2string(log_control.log_entries[lindex].lsu_severity),
12837c64d375Smp153739 				    facility2string(log_control.log_entries[lindex].lsu_facility));
12847c64d375Smp153739 				break;
12857c64d375Smp153739 			case K_LOG_NONE:
12867c64d375Smp153739 				break;
12877c64d375Smp153739 			default: /* Should never get here */
12887c64d375Smp153739 				return (-1);
12897c64d375Smp153739 		}
12907c64d375Smp153739 	}
12917c64d375Smp153739 	fprintf(stderr, "\n");
12927c64d375Smp153739 	return (0);
12937c64d375Smp153739 }
12947c64d375Smp153739 
12957c64d375Smp153739 /*
12967c64d375Smp153739  * Solaris Kerberos:
12977c64d375Smp153739  * Add logging to stderr.
12987c64d375Smp153739  */
krb5_klog_add_stderr()12997c64d375Smp153739 krb5_error_code krb5_klog_add_stderr() {
13007c64d375Smp153739 
13017c64d375Smp153739 	struct log_entry *tmp_log_entries = log_control.log_entries;
13027c64d375Smp153739 	int i;
13037c64d375Smp153739 
13047c64d375Smp153739 	if (log_control.log_entries != &def_log_entry) {
13057c64d375Smp153739 		log_control.log_entries = realloc(log_control.log_entries,
13067c64d375Smp153739 		    (log_control.log_nentries + 1) * sizeof(struct log_entry));
13077c64d375Smp153739 		if (log_control.log_entries == NULL) {
13087c64d375Smp153739 			log_control.log_entries = tmp_log_entries;
13097c64d375Smp153739 			return (ENOMEM);
13107c64d375Smp153739 		}
13117c64d375Smp153739 	} else {
13127c64d375Smp153739 		log_control.log_entries = malloc(2 * sizeof(struct log_entry));
13137c64d375Smp153739 		if (log_control.log_entries == NULL) {
13147c64d375Smp153739 			log_control.log_entries = &def_log_entry;
13157c64d375Smp153739 			return (ENOMEM);
13167c64d375Smp153739 		}
13177c64d375Smp153739 		(void) memcpy(&log_control.log_entries[0], &def_log_entry,
13187c64d375Smp153739 		    sizeof(struct log_entry));
13197c64d375Smp153739 	}
13207c64d375Smp153739 
13217c64d375Smp153739 	i = log_control.log_nentries;
13227c64d375Smp153739 	if (log_control.log_entries[i].lfu_filep =
13237c64d375Smp153739 	    fdopen(fileno(stderr), "a+F")) {
13247c64d375Smp153739 		log_control.log_entries[i].log_type = K_LOG_STDERR;
13257c64d375Smp153739 		log_control.log_entries[i].log_2free = NULL;
13267c64d375Smp153739 		log_control.log_entries[i].lfu_fname = "standard error";
13277c64d375Smp153739 		log_control.log_nentries++;
13287c64d375Smp153739 	} else {
13297c64d375Smp153739 		/* Free the alloc'ed extra entry */
13307c64d375Smp153739 		int err = errno;
13317c64d375Smp153739 		tmp_log_entries = log_control.log_entries;
13327c64d375Smp153739 		log_control.log_entries = realloc(log_control.log_entries,
13337c64d375Smp153739 		    (log_control.log_nentries) * sizeof(struct log_entry));
13347c64d375Smp153739 		if (log_control.log_entries == NULL)
13357c64d375Smp153739 			log_control.log_entries = tmp_log_entries;
13367c64d375Smp153739 		return (err);
13377c64d375Smp153739 	}
13387c64d375Smp153739 
13397c64d375Smp153739 	return (0);
13407c64d375Smp153739 }
13417c64d375Smp153739 
13427c64d375Smp153739 /*
13437c64d375Smp153739  * Solaris Kerberos
13447c64d375Smp153739  * Remove logging to stderr.
13457c64d375Smp153739  */
krb5_klog_remove_stderr()13467c64d375Smp153739 void krb5_klog_remove_stderr() {
13477c64d375Smp153739 
13487c64d375Smp153739 	struct log_entry *tmp_log_entries = log_control.log_entries;
13497c64d375Smp153739 	int i;
13507c64d375Smp153739 
13517c64d375Smp153739 	/* Find the entry (if it exists) */
13527c64d375Smp153739 	for (i = 0; i < log_control.log_nentries; i++) {
13537c64d375Smp153739 		if (log_control.log_entries[i].log_type == K_LOG_STDERR) {
13547c64d375Smp153739 			break;
13557c64d375Smp153739 		}
13567c64d375Smp153739 	}
13577c64d375Smp153739 
13587c64d375Smp153739 	if ( i < log_control.log_nentries) {
13597c64d375Smp153739 		for (; i < log_control.log_nentries - 1; i++)
13607c64d375Smp153739 			log_control.log_entries[i] =
13617c64d375Smp153739 			    log_control.log_entries[i + 1];
13627c64d375Smp153739 
13637c64d375Smp153739 		if (log_control.log_nentries > 1) {
13647c64d375Smp153739 			log_control.log_entries =
13657c64d375Smp153739 			    realloc(log_control.log_entries,
13667c64d375Smp153739 			    (log_control.log_nentries + 1) *
13677c64d375Smp153739 			    sizeof(struct log_entry));
13687c64d375Smp153739 			if (log_control.log_entries != NULL)
13697c64d375Smp153739 				log_control.log_nentries--;
13707c64d375Smp153739 			else
13717c64d375Smp153739 				log_control.log_entries = tmp_log_entries;
13727c64d375Smp153739 		} else {
13737c64d375Smp153739 			if (log_control.log_entries != NULL)
13747c64d375Smp153739 				free(log_control.log_entries);
13757c64d375Smp153739 		}
13767c64d375Smp153739 	}
13777c64d375Smp153739 }
13787c64d375Smp153739 
13797c64d375Smp153739 /* Solaris Kerberos: Indicate if currently logging to stderr */
krb5_klog_logging_to_stderr()13807c64d375Smp153739 krb5_boolean krb5_klog_logging_to_stderr() {
13817c64d375Smp153739 	int i;
13827c64d375Smp153739 
13837c64d375Smp153739 	/* Find the entry (if it exists) */
13847c64d375Smp153739 	for (i = 0; i < log_control.log_nentries; i++) {
13857c64d375Smp153739 		if (log_control.log_entries[i].log_type == K_LOG_STDERR) {
13867c64d375Smp153739 			return (TRUE);
13877c64d375Smp153739 		}
13887c64d375Smp153739 	}
13897c64d375Smp153739 	return (FALSE);
13907c64d375Smp153739 }
13917c64d375Smp153739 
1392