xref: /illumos-gate/usr/src/lib/krb5/kadm5/clnt/logger.c (revision 55fea89d)
1159d09a2SMark Phalan /*
2159d09a2SMark Phalan  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
3159d09a2SMark Phalan  * Use is subject to license terms.
4159d09a2SMark Phalan  */
5159d09a2SMark Phalan 
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
24159d09a2SMark Phalan  * permission.  Furthermore if you modify this software you must label
25159d09a2SMark Phalan  * your software as modified software and not distribute it in such a
26159d09a2SMark Phalan  * fashion that it might be confused with the original M.I.T. software.
27159d09a2SMark Phalan  * 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>
44159d09a2SMark Phalan #include <ctype.h>
45159d09a2SMark Phalan #ifdef	HAVE_SYSLOG_H
467c478bd9Sstevel@tonic-gate #include <syslog.h>
47159d09a2SMark Phalan #endif	/* HAVE_SYSLOG_H */
48159d09a2SMark Phalan #ifdef	HAVE_STDARG_H
497c478bd9Sstevel@tonic-gate #include <stdarg.h>
50159d09a2SMark Phalan #else	/* HAVE_STDARG_H */
51159d09a2SMark Phalan #include <varargs.h>
52159d09a2SMark Phalan #endif	/* HAVE_STDARG_H */
537c478bd9Sstevel@tonic-gate #include <libintl.h>
54159d09a2SMark Phalan #include <sys/types.h>
55159d09a2SMark Phalan #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
70*55fea89dSDan Cross #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:
1057c478bd9Sstevel@tonic-gate 		return(gettext("???"));
1067c478bd9Sstevel@tonic-gate 	case LOG_EMERG_STRING:
1077c478bd9Sstevel@tonic-gate 		return(gettext("EMERGENCY"));
1087c478bd9Sstevel@tonic-gate 	case LOG_ALERT_STRING:
1097c478bd9Sstevel@tonic-gate 		return(gettext("ALERT"));
1107c478bd9Sstevel@tonic-gate 	case LOG_CRIT_STRING:
1117c478bd9Sstevel@tonic-gate 		return(gettext("CRITICAL"));
1127c478bd9Sstevel@tonic-gate 	case LOG_ERR_STRING:
1137c478bd9Sstevel@tonic-gate 		return(gettext("Error"));
1147c478bd9Sstevel@tonic-gate 	case LOG_WARNING_STRING:
1157c478bd9Sstevel@tonic-gate 		return(gettext("Warning"));
1167c478bd9Sstevel@tonic-gate 	case LOG_NOTICE_STRING:
1177c478bd9Sstevel@tonic-gate 		return(gettext("Notice"));
1187c478bd9Sstevel@tonic-gate 	case LOG_INFO_STRING:
1197c478bd9Sstevel@tonic-gate 	case LOG_DEBUG_STRING:
1207c478bd9Sstevel@tonic-gate 	default:
1217c478bd9Sstevel@tonic-gate 		return(gettext("info"));
1227c478bd9Sstevel@tonic-gate 	}
1237c478bd9Sstevel@tonic-gate }
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate /*
1267c478bd9Sstevel@tonic-gate  * Output logging.
1277c478bd9Sstevel@tonic-gate  *
1287c478bd9Sstevel@tonic-gate  * Output logging is now controlled by the configuration file.  We can specify
1297c478bd9Sstevel@tonic-gate  * the following syntaxes under the [logging]->entity specification.
1307c478bd9Sstevel@tonic-gate  *	FILE<opentype><pathname>
1317c478bd9Sstevel@tonic-gate  *	SYSLOG[=<severity>[:<facility>]]
1327c478bd9Sstevel@tonic-gate  *	STDERR
1337c478bd9Sstevel@tonic-gate  *	CONSOLE
1347c478bd9Sstevel@tonic-gate  *	DEVICE=<device-spec>
1357c478bd9Sstevel@tonic-gate  *
1367c478bd9Sstevel@tonic-gate  * Where:
1377c478bd9Sstevel@tonic-gate  *	<opentype> is ":" for open/append, "=" for open/create.
1387c478bd9Sstevel@tonic-gate  *	<pathname> is a valid path name.
1397c478bd9Sstevel@tonic-gate  *	<severity> is one of: (default = ERR)
1407c478bd9Sstevel@tonic-gate  *		EMERG
1417c478bd9Sstevel@tonic-gate  *		ALERT
1427c478bd9Sstevel@tonic-gate  *		CRIT
1437c478bd9Sstevel@tonic-gate  *		ERR
1447c478bd9Sstevel@tonic-gate  *		WARNING
1457c478bd9Sstevel@tonic-gate  *		NOTICE
1467c478bd9Sstevel@tonic-gate  *		INFO
1477c478bd9Sstevel@tonic-gate  *		DEBUG
1487c478bd9Sstevel@tonic-gate  *	<facility> is one of: (default = AUTH)
1497c478bd9Sstevel@tonic-gate  *		KERN
1507c478bd9Sstevel@tonic-gate  *		USER
1517c478bd9Sstevel@tonic-gate  *		MAIL
1527c478bd9Sstevel@tonic-gate  *		DAEMON
1537c478bd9Sstevel@tonic-gate  *		AUTH
1547c478bd9Sstevel@tonic-gate  *		LPR
1557c478bd9Sstevel@tonic-gate  *		NEWS
1567c478bd9Sstevel@tonic-gate  *		UUCP
1577c478bd9Sstevel@tonic-gate  *		AUDIT
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)
225159d09a2SMark Phalan #define	DEVICE_PRINT(f, m)	((fprintf(f, "%s\r\n", m) >= 0) ? 	\
226159d09a2SMark Phalan 				 (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;
247159d09a2SMark Phalan 	mode_t old_umask;
248159d09a2SMark Phalan 
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 		/*
288*55fea89dSDan Cross 		 * 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 
317159d09a2SMark Phalan 		/*
318159d09a2SMark Phalan 		 * Default log file creation mode should be read-only
319159d09a2SMark Phalan 		 * by owner(root), but the admin can override with
320159d09a2SMark Phalan 		 * chmod(1) if desired.
321*55fea89dSDan Cross 		 */
322159d09a2SMark Phalan 
323159d09a2SMark Phalan 		old_umask = umask(077);
3247c478bd9Sstevel@tonic-gate 		fp = fopen(old_name, le->lfu_fopen_mode);
3257c478bd9Sstevel@tonic-gate 
326159d09a2SMark Phalan 		umask(old_umask);
3277c478bd9Sstevel@tonic-gate 
328159d09a2SMark Phalan 		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.
339*55fea89dSDan Cross 			 */
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  */
361159d09a2SMark Phalan 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)363159d09a2SMark 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;
367159d09a2SMark Phalan     const char	*actual_format;
368159d09a2SMark Phalan #ifdef	HAVE_SYSLOG
3697c478bd9Sstevel@tonic-gate     int		log_pri = -1;
370159d09a2SMark 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) {
384159d09a2SMark Phalan         const char *emsg;
385159d09a2SMark Phalan         outbuf[sizeof(outbuf) - 1] = '\0';
38646736d35Ssemery 
387159d09a2SMark Phalan 	emsg = krb5_get_error_message (err_context, code);
388159d09a2SMark Phalan 	strncat(outbuf, emsg, sizeof(outbuf) - 1 - strlen(outbuf));
38946736d35Ssemery 	strncat(outbuf, " - ", sizeof(outbuf) - 1 - strlen(outbuf));
390159d09a2SMark Phalan 	krb5_free_error_message(err_context, emsg);
3917c478bd9Sstevel@tonic-gate     }
3927c478bd9Sstevel@tonic-gate     cp = &outbuf[strlen(outbuf)];
393*55fea89dSDan Cross 
394159d09a2SMark Phalan     actual_format = format;
395159d09a2SMark Phalan #ifdef	HAVE_SYSLOG
3967c478bd9Sstevel@tonic-gate     /*
3977c478bd9Sstevel@tonic-gate      * This is an unpleasant hack.  If the first character is less than
3987c478bd9Sstevel@tonic-gate      * 8, then we assume that it is a priority.
3997c478bd9Sstevel@tonic-gate      *
4007c478bd9Sstevel@tonic-gate      * Since it is not guaranteed that there is a direct mapping between
4017c478bd9Sstevel@tonic-gate      * syslog priorities (e.g. Ultrix and old BSD), we resort to this
4027c478bd9Sstevel@tonic-gate      * intermediate representation.
4037c478bd9Sstevel@tonic-gate      */
4047c478bd9Sstevel@tonic-gate     if ((((unsigned char) *format) > 0) && (((unsigned char) *format) <= 8)) {
405159d09a2SMark Phalan 	actual_format = (format + 1);
4067c478bd9Sstevel@tonic-gate 	switch ((unsigned char) *format) {
407159d09a2SMark Phalan #ifdef	LOG_EMERG
4087c478bd9Sstevel@tonic-gate 	case 1:
4097c478bd9Sstevel@tonic-gate 	    log_pri = LOG_EMERG;
4107c478bd9Sstevel@tonic-gate 	    break;
411159d09a2SMark Phalan #endif /* LOG_EMERG */
412159d09a2SMark Phalan #ifdef	LOG_ALERT
4137c478bd9Sstevel@tonic-gate 	case 2:
4147c478bd9Sstevel@tonic-gate 	    log_pri = LOG_ALERT;
4157c478bd9Sstevel@tonic-gate 	    break;
416159d09a2SMark Phalan #endif /* LOG_ALERT */
417159d09a2SMark Phalan #ifdef	LOG_CRIT
4187c478bd9Sstevel@tonic-gate 	case 3:
4197c478bd9Sstevel@tonic-gate 	    log_pri = LOG_CRIT;
4207c478bd9Sstevel@tonic-gate 	    break;
421159d09a2SMark Phalan #endif /* LOG_CRIT */
4227c478bd9Sstevel@tonic-gate 	default:
4237c478bd9Sstevel@tonic-gate 	case 4:
4247c478bd9Sstevel@tonic-gate 	    log_pri = LOG_ERR;
4257c478bd9Sstevel@tonic-gate 	    break;
426159d09a2SMark Phalan #ifdef	LOG_WARNING
4277c478bd9Sstevel@tonic-gate 	case 5:
4287c478bd9Sstevel@tonic-gate 	    log_pri = LOG_WARNING;
4297c478bd9Sstevel@tonic-gate 	    break;
430159d09a2SMark Phalan #endif /* LOG_WARNING */
431159d09a2SMark Phalan #ifdef	LOG_NOTICE
4327c478bd9Sstevel@tonic-gate 	case 6:
4337c478bd9Sstevel@tonic-gate 	    log_pri = LOG_NOTICE;
4347c478bd9Sstevel@tonic-gate 	    break;
435159d09a2SMark Phalan #endif /* LOG_NOTICE */
436159d09a2SMark Phalan #ifdef	LOG_INFO
4377c478bd9Sstevel@tonic-gate 	case 7:
4387c478bd9Sstevel@tonic-gate 	    log_pri = LOG_INFO;
4397c478bd9Sstevel@tonic-gate 	    break;
440159d09a2SMark Phalan #endif /* LOG_INFO */
441159d09a2SMark Phalan #ifdef	LOG_DEBUG
4427c478bd9Sstevel@tonic-gate 	case 8:
4437c478bd9Sstevel@tonic-gate 	    log_pri = LOG_DEBUG;
4447c478bd9Sstevel@tonic-gate 	    break;
445159d09a2SMark Phalan #endif /* LOG_DEBUG */
4467c478bd9Sstevel@tonic-gate 	}
447*55fea89dSDan Cross     }
448159d09a2SMark Phalan #endif	/* HAVE_SYSLOG */
4497c478bd9Sstevel@tonic-gate 
4507c478bd9Sstevel@tonic-gate     /* Now format the actual message */
451159d09a2SMark Phalan #if	HAVE_VSNPRINTF
452159d09a2SMark Phalan     vsnprintf(cp, sizeof(outbuf) - (cp - outbuf), actual_format, ap);
453159d09a2SMark Phalan #elif	HAVE_VSPRINTF
454159d09a2SMark Phalan     vsprintf(cp, actual_format, ap);
455159d09a2SMark Phalan #else	/* HAVE_VSPRINTF */
456159d09a2SMark Phalan     sprintf(cp, actual_format, ((int *) ap)[0], ((int *) ap)[1],
457159d09a2SMark Phalan 	    ((int *) ap)[2], ((int *) ap)[3],
458159d09a2SMark Phalan 	    ((int *) ap)[4], ((int *) ap)[5]);
459159d09a2SMark Phalan #endif	/* HAVE_VSPRINTF */
460*55fea89dSDan Cross 
4617c478bd9Sstevel@tonic-gate     /*
4627c478bd9Sstevel@tonic-gate      * Now that we have the message formatted, perform the output to each
4637c478bd9Sstevel@tonic-gate      * logging specification.
4647c478bd9Sstevel@tonic-gate      */
4657c478bd9Sstevel@tonic-gate     for (lindex = 0; lindex < log_control.log_nentries; lindex++) {
4667c478bd9Sstevel@tonic-gate 	switch (log_control.log_entries[lindex].log_type) {
4677c478bd9Sstevel@tonic-gate 	case K_LOG_FILE:
4687c478bd9Sstevel@tonic-gate 
4697c478bd9Sstevel@tonic-gate 	    klog_rotate(&log_control.log_entries[lindex]);
4707c478bd9Sstevel@tonic-gate 	    /*FALLTHRU*/
4717c478bd9Sstevel@tonic-gate 	case K_LOG_STDERR:
4727c478bd9Sstevel@tonic-gate 	    /*
4737c478bd9Sstevel@tonic-gate 	     * Files/standard error.
4747c478bd9Sstevel@tonic-gate 	     */
475159d09a2SMark Phalan 	    if (fprintf(log_control.log_entries[lindex].lfu_filep, "%s\n",
4767c478bd9Sstevel@tonic-gate 			outbuf) < 0) {
4777c478bd9Sstevel@tonic-gate 		/* Attempt to report error */
4787c478bd9Sstevel@tonic-gate 		fprintf(stderr, krb5_log_error_table(LOG_FILE_ERR), whoami,
4797c478bd9Sstevel@tonic-gate 			log_control.log_entries[lindex].lfu_fname);
4807c478bd9Sstevel@tonic-gate 	    }
4817c478bd9Sstevel@tonic-gate 	    else {
4827c478bd9Sstevel@tonic-gate 		fflush(log_control.log_entries[lindex].lfu_filep);
4837c478bd9Sstevel@tonic-gate 	    }
4847c478bd9Sstevel@tonic-gate 	    break;
4857c478bd9Sstevel@tonic-gate 	case K_LOG_CONSOLE:
4867c478bd9Sstevel@tonic-gate 	case K_LOG_DEVICE:
4877c478bd9Sstevel@tonic-gate 	    /*
4887c478bd9Sstevel@tonic-gate 	     * Devices (may need special handling)
4897c478bd9Sstevel@tonic-gate 	     */
4907c478bd9Sstevel@tonic-gate 	    if (DEVICE_PRINT(log_control.log_entries[lindex].ldu_filep,
4917c478bd9Sstevel@tonic-gate 			     outbuf) < 0) {
4927c478bd9Sstevel@tonic-gate 		/* Attempt to report error */
4937c478bd9Sstevel@tonic-gate 		fprintf(stderr, krb5_log_error_table(LOG_DEVICE_ERR), whoami,
4947c478bd9Sstevel@tonic-gate 			log_control.log_entries[lindex].ldu_devname);
4957c478bd9Sstevel@tonic-gate 	    }
4967c478bd9Sstevel@tonic-gate 	    break;
497159d09a2SMark Phalan #ifdef	HAVE_SYSLOG
4987c478bd9Sstevel@tonic-gate 	case K_LOG_SYSLOG:
4997c478bd9Sstevel@tonic-gate 	    /*
5007c478bd9Sstevel@tonic-gate 	     * System log.
5017c478bd9Sstevel@tonic-gate 	     */
5027c478bd9Sstevel@tonic-gate 	    /*
5037c478bd9Sstevel@tonic-gate 	     * If we have specified a priority through our hackery, then
5047c478bd9Sstevel@tonic-gate 	     * use it, otherwise use the default.
5057c478bd9Sstevel@tonic-gate 	     */
5067c478bd9Sstevel@tonic-gate 	    if (log_pri >= 0)
5077c478bd9Sstevel@tonic-gate 		log_pri |= log_control.log_entries[lindex].lsu_facility;
5087c478bd9Sstevel@tonic-gate 	    else
5097c478bd9Sstevel@tonic-gate 		log_pri = log_control.log_entries[lindex].lsu_facility |
5107c478bd9Sstevel@tonic-gate 		    log_control.log_entries[lindex].lsu_severity;
511*55fea89dSDan Cross 
5127c478bd9Sstevel@tonic-gate 	    /* Log the message with our header trimmed off */
5137c478bd9Sstevel@tonic-gate 	    syslog(log_pri, syslogp);
5147c478bd9Sstevel@tonic-gate 	    break;
515159d09a2SMark Phalan #endif /* HAVE_SYSLOG */
5167c478bd9Sstevel@tonic-gate 	default:
5177c478bd9Sstevel@tonic-gate 	    break;
5187c478bd9Sstevel@tonic-gate 	}
5197c478bd9Sstevel@tonic-gate     }
5207c478bd9Sstevel@tonic-gate }
5217c478bd9Sstevel@tonic-gate 
5227c478bd9Sstevel@tonic-gate /*
5237c478bd9Sstevel@tonic-gate  * krb5_klog_init()	- Initialize logging.
5247c478bd9Sstevel@tonic-gate  *
5257c478bd9Sstevel@tonic-gate  * This routine parses the syntax described above to specify destinations for
5267c478bd9Sstevel@tonic-gate  * com_err(3) or krb5_klog_syslog() messages generated by the caller.
5277c478bd9Sstevel@tonic-gate  *
5287c478bd9Sstevel@tonic-gate  * Parameters:
5297c478bd9Sstevel@tonic-gate  *	kcontext	- Kerberos context.
5307c478bd9Sstevel@tonic-gate  *	ename		- Entity name as it is to appear in the profile.
5317c478bd9Sstevel@tonic-gate  *	whoami		- Entity name as it is to appear in error output.
5327c478bd9Sstevel@tonic-gate  *	do_com_err	- Take over com_err(3) processing.
5337c478bd9Sstevel@tonic-gate  *
5347c478bd9Sstevel@tonic-gate  * Implicit inputs:
5357c478bd9Sstevel@tonic-gate  *	stderr		- This is where STDERR output goes.
5367c478bd9Sstevel@tonic-gate  *
5377c478bd9Sstevel@tonic-gate  * Implicit outputs:
5387c478bd9Sstevel@tonic-gate  *	log_nentries	- Number of log entries, both valid and invalid.
5397c478bd9Sstevel@tonic-gate  *	log_control	- List of entries (log_nentries long) which contains
5407c478bd9Sstevel@tonic-gate  *			  data for klog_com_err_proc() to use to determine
5417c478bd9Sstevel@tonic-gate  *			  where/how to send output.
5427c478bd9Sstevel@tonic-gate  */
5437c478bd9Sstevel@tonic-gate krb5_error_code
krb5_klog_init(krb5_context kcontext,char * ename,char * whoami,krb5_boolean do_com_err)544159d09a2SMark Phalan krb5_klog_init(krb5_context kcontext, char *ename, char *whoami, krb5_boolean do_com_err)
5457c478bd9Sstevel@tonic-gate {
5467c478bd9Sstevel@tonic-gate     const char	*logging_profent[3];
5477c478bd9Sstevel@tonic-gate     const char	*logging_defent[3];
5487c478bd9Sstevel@tonic-gate     char	**logging_specs;
5497c478bd9Sstevel@tonic-gate     int		i, ngood;
5507c478bd9Sstevel@tonic-gate     char	*cp, *cp2;
551159d09a2SMark Phalan     char	savec = '\0';
5527c478bd9Sstevel@tonic-gate     int		error;
5537c478bd9Sstevel@tonic-gate     int		do_openlog, log_facility;
5547c478bd9Sstevel@tonic-gate     FILE	*f;
555159d09a2SMark Phalan     mode_t      old_umask;
5567c478bd9Sstevel@tonic-gate 
5577c478bd9Sstevel@tonic-gate     /* Initialize */
5587c478bd9Sstevel@tonic-gate     do_openlog = 0;
5597c478bd9Sstevel@tonic-gate     log_facility = 0;
5607c478bd9Sstevel@tonic-gate 
561159d09a2SMark Phalan     err_context = kcontext;
562159d09a2SMark Phalan 
5637c478bd9Sstevel@tonic-gate     /*
5647c478bd9Sstevel@tonic-gate      * Look up [logging]-><ename> in the profile.  If that doesn't
5657c478bd9Sstevel@tonic-gate      * succeed, then look for [logging]->default.
5667c478bd9Sstevel@tonic-gate      */
5677c478bd9Sstevel@tonic-gate     logging_profent[0] = "logging";
5687c478bd9Sstevel@tonic-gate     logging_profent[1] = ename;
5697c478bd9Sstevel@tonic-gate     logging_profent[2] = (char *) NULL;
5707c478bd9Sstevel@tonic-gate     logging_defent[0] = "logging";
5717c478bd9Sstevel@tonic-gate     logging_defent[1] = "default";
5727c478bd9Sstevel@tonic-gate     logging_defent[2] = (char *) NULL;
5737c478bd9Sstevel@tonic-gate     logging_specs = (char **) NULL;
5747c478bd9Sstevel@tonic-gate     ngood = 0;
5757c478bd9Sstevel@tonic-gate     log_control.log_nentries = 0;
5767c478bd9Sstevel@tonic-gate     if (!profile_get_values(kcontext->profile,
5777c478bd9Sstevel@tonic-gate 			    logging_profent,
5787c478bd9Sstevel@tonic-gate 			    &logging_specs) ||
5797c478bd9Sstevel@tonic-gate 	!profile_get_values(kcontext->profile,
5807c478bd9Sstevel@tonic-gate 			    logging_defent,
5817c478bd9Sstevel@tonic-gate 			    &logging_specs)) {
5827c478bd9Sstevel@tonic-gate 	/*
5837c478bd9Sstevel@tonic-gate 	 * We have a match, so we first count the number of elements
5847c478bd9Sstevel@tonic-gate 	 */
5857c478bd9Sstevel@tonic-gate 	for (log_control.log_nentries = 0;
5867c478bd9Sstevel@tonic-gate 	     logging_specs[log_control.log_nentries];
5877c478bd9Sstevel@tonic-gate 	     log_control.log_nentries++);
5887c478bd9Sstevel@tonic-gate 
5897c478bd9Sstevel@tonic-gate 	/*
5907c478bd9Sstevel@tonic-gate 	 * Now allocate our structure.
5917c478bd9Sstevel@tonic-gate 	 */
5927c478bd9Sstevel@tonic-gate 	log_control.log_entries = (struct log_entry *)
5937c478bd9Sstevel@tonic-gate 	    malloc(log_control.log_nentries * sizeof(struct log_entry));
5947c478bd9Sstevel@tonic-gate 	if (log_control.log_entries) {
5957c478bd9Sstevel@tonic-gate 	    /*
5967c478bd9Sstevel@tonic-gate 	     * Scan through the list.
5977c478bd9Sstevel@tonic-gate 	     */
5987c478bd9Sstevel@tonic-gate 	    for (i=0; i<log_control.log_nentries; i++) {
5997c478bd9Sstevel@tonic-gate 		log_control.log_entries[i].log_type = K_LOG_NONE;
6007c478bd9Sstevel@tonic-gate 		log_control.log_entries[i].log_2free = logging_specs[i];
6017c478bd9Sstevel@tonic-gate 		/*
6027c478bd9Sstevel@tonic-gate 		 * The format is:
6037c478bd9Sstevel@tonic-gate 		 *	<whitespace><data><whitespace>
6047c478bd9Sstevel@tonic-gate 		 * so, trim off the leading and trailing whitespace here.
6057c478bd9Sstevel@tonic-gate 		 */
606159d09a2SMark Phalan 		for (cp = logging_specs[i]; isspace((int) *cp); cp++);
6077c478bd9Sstevel@tonic-gate 		for (cp2 = &logging_specs[i][strlen(logging_specs[i])-1];
608159d09a2SMark Phalan 		     isspace((int) *cp2); cp2--);
6097c478bd9Sstevel@tonic-gate 		cp2++;
6107c478bd9Sstevel@tonic-gate 		*cp2 = '\0';
6117c478bd9Sstevel@tonic-gate 		/*
6127c478bd9Sstevel@tonic-gate 		 * Is this a file?
6137c478bd9Sstevel@tonic-gate 		 */
6147c478bd9Sstevel@tonic-gate 		if (!strncasecmp(cp, "FILE", 4)) {
6157c478bd9Sstevel@tonic-gate 		    /*
6167c478bd9Sstevel@tonic-gate 		     * Check for append/overwrite, then open the file.
6177c478bd9Sstevel@tonic-gate 		     */
6187c478bd9Sstevel@tonic-gate 		    if (cp[4] == ':' || cp[4] == '=') {
619*55fea89dSDan Cross 			log_control.log_entries[i].lfu_fopen_mode =
620004388ebScasper 				(cp[4] == ':') ? "a+F" : "wF";
621159d09a2SMark Phalan 			old_umask = umask(077);
6227c478bd9Sstevel@tonic-gate 			f = fopen(&cp[5],
6237c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lfu_fopen_mode);
624159d09a2SMark Phalan 			umask(old_umask);
6257c478bd9Sstevel@tonic-gate 			if (f) {
626159d09a2SMark Phalan                             char rotate_kw[128];
627159d09a2SMark Phalan 
6287c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lfu_filep = f;
6297c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].log_type = K_LOG_FILE;
6307c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lfu_fname = &cp[5];
631*55fea89dSDan Cross 			    log_control.log_entries[i].lfu_rotate_period =
6327c478bd9Sstevel@tonic-gate 				K_LOG_DEF_FILE_ROTATE_PERIOD;
6337c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lfu_rotate_versions =
6347c478bd9Sstevel@tonic-gate 				K_LOG_DEF_FILE_ROTATE_VERSIONS;
6357c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lfu_last_rotated =
6367c478bd9Sstevel@tonic-gate 				time(0);
637*55fea89dSDan Cross 
6387c478bd9Sstevel@tonic-gate 			/*
6397c478bd9Sstevel@tonic-gate 			 * Now parse for ename_"rotate" = {
6407c478bd9Sstevel@tonic-gate 			 *	period = XXX
6417c478bd9Sstevel@tonic-gate 			 * 	versions = 10
6427c478bd9Sstevel@tonic-gate 			 * }
6437c478bd9Sstevel@tonic-gate 			 */
6447c478bd9Sstevel@tonic-gate 			    if (strlen(ename) + strlen("_rotate") <
6457c478bd9Sstevel@tonic-gate 				sizeof (rotate_kw)) {
6467c478bd9Sstevel@tonic-gate 
6477c478bd9Sstevel@tonic-gate 				    char *time;
6487c478bd9Sstevel@tonic-gate 				    krb5_deltat	dt;
6497c478bd9Sstevel@tonic-gate 				    int vers;
6507c478bd9Sstevel@tonic-gate 
6517c478bd9Sstevel@tonic-gate 				    strcpy(rotate_kw, ename);
6527c478bd9Sstevel@tonic-gate 				    strcat(rotate_kw, "_rotate");
6537c478bd9Sstevel@tonic-gate 
6547c478bd9Sstevel@tonic-gate 				    if (!profile_get_string(kcontext->profile,
6557c478bd9Sstevel@tonic-gate 				        "logging", rotate_kw, "period",
6567c478bd9Sstevel@tonic-gate 					NULL, &time)) {
6577c478bd9Sstevel@tonic-gate 
6587c478bd9Sstevel@tonic-gate 					if (time != NULL) {
6597c478bd9Sstevel@tonic-gate 					    if (!krb5_string_to_deltat(time,
6607c478bd9Sstevel@tonic-gate 						&dt)) {
6617c478bd9Sstevel@tonic-gate 			log_control.log_entries[i].lfu_rotate_period =
6627c478bd9Sstevel@tonic-gate 							(time_t) dt;
6637c478bd9Sstevel@tonic-gate 					    }
6647c478bd9Sstevel@tonic-gate 					    free(time);
6657c478bd9Sstevel@tonic-gate 					}
6667c478bd9Sstevel@tonic-gate 				    }
667*55fea89dSDan Cross 
6687c478bd9Sstevel@tonic-gate 				    if (!profile_get_integer(
6697c478bd9Sstevel@tonic-gate 					kcontext->profile, "logging",
6707c478bd9Sstevel@tonic-gate 					rotate_kw, "versions",
6717c478bd9Sstevel@tonic-gate 					K_LOG_DEF_FILE_ROTATE_VERSIONS,
6727c478bd9Sstevel@tonic-gate 					&vers)) {
6737c478bd9Sstevel@tonic-gate 			log_control.log_entries[i].lfu_rotate_versions = vers;
6747c478bd9Sstevel@tonic-gate 				    }
675*55fea89dSDan Cross 
6767c478bd9Sstevel@tonic-gate 			   }
6777c478bd9Sstevel@tonic-gate 			} else {
678159d09a2SMark Phalan 			    fprintf(stderr, gettext("Couldn't open log file %s: %s\n"),
6797c478bd9Sstevel@tonic-gate 				    &cp[5], error_message(errno));
6807c478bd9Sstevel@tonic-gate 			    continue;
6817c478bd9Sstevel@tonic-gate 			}
6827c478bd9Sstevel@tonic-gate 		    }
6837c478bd9Sstevel@tonic-gate 		}
684159d09a2SMark Phalan #ifdef	HAVE_SYSLOG
6857c478bd9Sstevel@tonic-gate 		/*
6867c478bd9Sstevel@tonic-gate 		 * Is this a syslog?
6877c478bd9Sstevel@tonic-gate 		 */
6887c478bd9Sstevel@tonic-gate 		else if (!strncasecmp(cp, "SYSLOG", 6)) {
6897c478bd9Sstevel@tonic-gate 		    error = 0;
6907c478bd9Sstevel@tonic-gate 		    log_control.log_entries[i].lsu_facility = LOG_AUTH;
6917c478bd9Sstevel@tonic-gate 		    log_control.log_entries[i].lsu_severity = LOG_ERR;
6927c478bd9Sstevel@tonic-gate 		    /*
6937c478bd9Sstevel@tonic-gate 		     * Is there a severify specified?
6947c478bd9Sstevel@tonic-gate 		     */
6957c478bd9Sstevel@tonic-gate 		    if (cp[6] == ':') {
6967c478bd9Sstevel@tonic-gate 			/*
6977c478bd9Sstevel@tonic-gate 			 * Find the end of the severity.
6987c478bd9Sstevel@tonic-gate 			 */
699159d09a2SMark Phalan 			cp2 = strchr(&cp[7], ':');
700159d09a2SMark Phalan 			if (cp2) {
7017c478bd9Sstevel@tonic-gate 			    savec = *cp2;
7027c478bd9Sstevel@tonic-gate 			    *cp2 = '\0';
7037c478bd9Sstevel@tonic-gate 			    cp2++;
7047c478bd9Sstevel@tonic-gate 			}
7057c478bd9Sstevel@tonic-gate 
7067c478bd9Sstevel@tonic-gate 			/*
7077c478bd9Sstevel@tonic-gate 			 * Match a severity.
7087c478bd9Sstevel@tonic-gate 			 */
7097c478bd9Sstevel@tonic-gate 			if (!strcasecmp(&cp[7], "ERR")) {
7107c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lsu_severity = LOG_ERR;
7117c478bd9Sstevel@tonic-gate 			}
712159d09a2SMark Phalan #ifdef	LOG_EMERG
7137c478bd9Sstevel@tonic-gate 			else if (!strcasecmp(&cp[7], "EMERG")) {
7147c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lsu_severity =
7157c478bd9Sstevel@tonic-gate 				LOG_EMERG;
7167c478bd9Sstevel@tonic-gate 			}
717159d09a2SMark Phalan #endif	/* LOG_EMERG */
718159d09a2SMark Phalan #ifdef	LOG_ALERT
7197c478bd9Sstevel@tonic-gate 			else if (!strcasecmp(&cp[7], "ALERT")) {
7207c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lsu_severity =
7217c478bd9Sstevel@tonic-gate 				LOG_ALERT;
7227c478bd9Sstevel@tonic-gate 			}
723159d09a2SMark Phalan #endif	/* LOG_ALERT */
724159d09a2SMark Phalan #ifdef	LOG_CRIT
7257c478bd9Sstevel@tonic-gate 			else if (!strcasecmp(&cp[7], "CRIT")) {
7267c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lsu_severity = LOG_CRIT;
7277c478bd9Sstevel@tonic-gate 			}
728159d09a2SMark Phalan #endif	/* LOG_CRIT */
729159d09a2SMark Phalan #ifdef	LOG_WARNING
7307c478bd9Sstevel@tonic-gate 			else if (!strcasecmp(&cp[7], "WARNING")) {
7317c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lsu_severity =
7327c478bd9Sstevel@tonic-gate 				LOG_WARNING;
7337c478bd9Sstevel@tonic-gate 			}
734159d09a2SMark Phalan #endif	/* LOG_WARNING */
735159d09a2SMark Phalan #ifdef	LOG_NOTICE
7367c478bd9Sstevel@tonic-gate 			else if (!strcasecmp(&cp[7], "NOTICE")) {
7377c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lsu_severity =
7387c478bd9Sstevel@tonic-gate 				LOG_NOTICE;
7397c478bd9Sstevel@tonic-gate 			}
740159d09a2SMark Phalan #endif	/* LOG_NOTICE */
741159d09a2SMark Phalan #ifdef	LOG_INFO
7427c478bd9Sstevel@tonic-gate 			else if (!strcasecmp(&cp[7], "INFO")) {
7437c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lsu_severity = LOG_INFO;
7447c478bd9Sstevel@tonic-gate 			}
745159d09a2SMark Phalan #endif	/* LOG_INFO */
746159d09a2SMark Phalan #ifdef	LOG_DEBUG
7477c478bd9Sstevel@tonic-gate 			else if (!strcasecmp(&cp[7], "DEBUG")) {
7487c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].lsu_severity =
7497c478bd9Sstevel@tonic-gate 				LOG_DEBUG;
7507c478bd9Sstevel@tonic-gate 			}
751159d09a2SMark Phalan #endif	/* LOG_DEBUG */
7527c478bd9Sstevel@tonic-gate 			else
7537c478bd9Sstevel@tonic-gate 			    error = 1;
7547c478bd9Sstevel@tonic-gate 
7557c478bd9Sstevel@tonic-gate 			/*
7567c478bd9Sstevel@tonic-gate 			 * If there is a facility present, then parse that.
7577c478bd9Sstevel@tonic-gate 			 */
7587c478bd9Sstevel@tonic-gate 			if (cp2) {
7597c478bd9Sstevel@tonic-gate 			    if (!strcasecmp(cp2, "AUTH")) {
7607c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_AUTH;
7617c478bd9Sstevel@tonic-gate 			    }
7627c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "KERN")) {
7637c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_KERN;
7647c478bd9Sstevel@tonic-gate 			    }
7657c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "USER")) {
7667c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_USER;
7677c478bd9Sstevel@tonic-gate 			    }
7687c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "MAIL")) {
7697c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_MAIL;
7707c478bd9Sstevel@tonic-gate 			    }
7717c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "DAEMON")) {
7727c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_DAEMON;
7737c478bd9Sstevel@tonic-gate 			    }
7747c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "LPR")) {
7757c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_LPR;
7767c478bd9Sstevel@tonic-gate 			    }
7777c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "NEWS")) {
7787c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_NEWS;
7797c478bd9Sstevel@tonic-gate 			    }
7807c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "UUCP")) {
7817c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_UUCP;
7827c478bd9Sstevel@tonic-gate 			    }
7837c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "CRON")) {
7847c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_CRON;
7857c478bd9Sstevel@tonic-gate 			    }
7867c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "AUDIT")) {
7877c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_AUDIT;
7887c478bd9Sstevel@tonic-gate 			    }
7897c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "LOCAL0")) {
7907c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_LOCAL0;
7917c478bd9Sstevel@tonic-gate 			    }
7927c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "LOCAL1")) {
7937c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_LOCAL1;
7947c478bd9Sstevel@tonic-gate 			    }
7957c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "LOCAL2")) {
7967c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_LOCAL2;
7977c478bd9Sstevel@tonic-gate 			    }
7987c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "LOCAL3")) {
7997c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_LOCAL3;
8007c478bd9Sstevel@tonic-gate 			    }
8017c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "LOCAL4")) {
8027c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_LOCAL4;
8037c478bd9Sstevel@tonic-gate 			    }
8047c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "LOCAL5")) {
8057c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_LOCAL5;
8067c478bd9Sstevel@tonic-gate 			    }
8077c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "LOCAL6")) {
8087c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_LOCAL6;
8097c478bd9Sstevel@tonic-gate 			    }
8107c478bd9Sstevel@tonic-gate 			    else if (!strcasecmp(cp2, "LOCAL7")) {
8117c478bd9Sstevel@tonic-gate 				log_control.log_entries[i].lsu_facility = LOG_LOCAL7;
8127c478bd9Sstevel@tonic-gate 			    }
8137c478bd9Sstevel@tonic-gate 			    cp2--;
8147c478bd9Sstevel@tonic-gate 			    *cp2 = savec;
8157c478bd9Sstevel@tonic-gate 			}
8167c478bd9Sstevel@tonic-gate 		    }
8177c478bd9Sstevel@tonic-gate 		    if (!error) {
8187c478bd9Sstevel@tonic-gate 			log_control.log_entries[i].log_type = K_LOG_SYSLOG;
8197c478bd9Sstevel@tonic-gate 			do_openlog = 1;
8207c478bd9Sstevel@tonic-gate 			log_facility = log_control.log_entries[i].lsu_facility;
8217c478bd9Sstevel@tonic-gate 		    }
8227c478bd9Sstevel@tonic-gate 		}
823159d09a2SMark Phalan #endif	/* HAVE_SYSLOG */
8247c478bd9Sstevel@tonic-gate 		/*
8257c478bd9Sstevel@tonic-gate 		 * Is this a standard error specification?
8267c478bd9Sstevel@tonic-gate 		 */
8277c478bd9Sstevel@tonic-gate 		else if (!strcasecmp(cp, "STDERR")) {
828159d09a2SMark Phalan 		    log_control.log_entries[i].lfu_filep =
829159d09a2SMark Phalan 			fdopen(fileno(stderr), "a+F");
830159d09a2SMark Phalan 		    if (log_control.log_entries[i].lfu_filep) {
8317c478bd9Sstevel@tonic-gate 			log_control.log_entries[i].log_type = K_LOG_STDERR;
8327c478bd9Sstevel@tonic-gate 			log_control.log_entries[i].lfu_fname =
8337c478bd9Sstevel@tonic-gate 			    "standard error";
8347c478bd9Sstevel@tonic-gate 		    }
8357c478bd9Sstevel@tonic-gate 		}
8367c478bd9Sstevel@tonic-gate 		/*
8377c478bd9Sstevel@tonic-gate 		 * Is this a specification of the console?
8387c478bd9Sstevel@tonic-gate 		 */
8397c478bd9Sstevel@tonic-gate 		else if (!strcasecmp(cp, "CONSOLE")) {
840159d09a2SMark Phalan 		    log_control.log_entries[i].ldu_filep =
841159d09a2SMark Phalan 			CONSOLE_OPEN("a+F");
842159d09a2SMark Phalan 		    if (log_control.log_entries[i].ldu_filep) {
8437c478bd9Sstevel@tonic-gate 			log_control.log_entries[i].log_type = K_LOG_CONSOLE;
8447c478bd9Sstevel@tonic-gate 			log_control.log_entries[i].ldu_devname = "console";
8457c478bd9Sstevel@tonic-gate 		    }
8467c478bd9Sstevel@tonic-gate 		}
8477c478bd9Sstevel@tonic-gate 		/*
8487c478bd9Sstevel@tonic-gate 		 * Is this a specification of a device?
8497c478bd9Sstevel@tonic-gate 		 */
8507c478bd9Sstevel@tonic-gate 		else if (!strncasecmp(cp, "DEVICE", 6)) {
8517c478bd9Sstevel@tonic-gate 		    /*
8527c478bd9Sstevel@tonic-gate 		     * We handle devices very similarly to files.
8537c478bd9Sstevel@tonic-gate 		     */
8547c478bd9Sstevel@tonic-gate 		    if (cp[6] == '=') {
855*55fea89dSDan Cross 			log_control.log_entries[i].ldu_filep =
856159d09a2SMark Phalan 			    DEVICE_OPEN(&cp[7], "wF");
857159d09a2SMark Phalan 			if (log_control.log_entries[i].ldu_filep) {
8587c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].log_type = K_LOG_DEVICE;
8597c478bd9Sstevel@tonic-gate 			    log_control.log_entries[i].ldu_devname = &cp[7];
8607c478bd9Sstevel@tonic-gate 			}
8617c478bd9Sstevel@tonic-gate 		    }
8627c478bd9Sstevel@tonic-gate 		}
8637c478bd9Sstevel@tonic-gate 		/*
8647c478bd9Sstevel@tonic-gate 		 * See if we successfully parsed this specification.
8657c478bd9Sstevel@tonic-gate 		 */
8667c478bd9Sstevel@tonic-gate 		if (log_control.log_entries[i].log_type == K_LOG_NONE) {
8677c478bd9Sstevel@tonic-gate 		    fprintf(stderr, krb5_log_error_table(LSPEC_PARSE_ERR_1), whoami, cp);
8687c478bd9Sstevel@tonic-gate 		    fprintf(stderr, krb5_log_error_table(LSPEC_PARSE_ERR_2), whoami);
8697c478bd9Sstevel@tonic-gate 		}
8707c478bd9Sstevel@tonic-gate 		else
8717c478bd9Sstevel@tonic-gate 		    ngood++;
8727c478bd9Sstevel@tonic-gate 	    }
8737c478bd9Sstevel@tonic-gate 	}
8747c478bd9Sstevel@tonic-gate 	/*
8757c478bd9Sstevel@tonic-gate 	 * If we didn't find anything, then free our lists.
8767c478bd9Sstevel@tonic-gate 	 */
8777c478bd9Sstevel@tonic-gate 	if (ngood == 0) {
8787c478bd9Sstevel@tonic-gate 	    for (i=0; i<log_control.log_nentries; i++)
8797c478bd9Sstevel@tonic-gate 		free(logging_specs[i]);
8807c478bd9Sstevel@tonic-gate 	}
8817c478bd9Sstevel@tonic-gate 	free(logging_specs);
8827c478bd9Sstevel@tonic-gate     }
8837c478bd9Sstevel@tonic-gate     /*
8847c478bd9Sstevel@tonic-gate      * If we didn't find anything, go for the default which is to log to
8857c478bd9Sstevel@tonic-gate      * the system log.
8867c478bd9Sstevel@tonic-gate      */
8877c478bd9Sstevel@tonic-gate     if (ngood == 0) {
8887c478bd9Sstevel@tonic-gate 	if (log_control.log_entries)
8897c478bd9Sstevel@tonic-gate 	    free(log_control.log_entries);
8907c478bd9Sstevel@tonic-gate 	log_control.log_entries = &def_log_entry;
8917c478bd9Sstevel@tonic-gate 	log_control.log_entries->log_type = K_LOG_SYSLOG;
8927c478bd9Sstevel@tonic-gate 	log_control.log_entries->log_2free = (krb5_pointer) NULL;
8937c478bd9Sstevel@tonic-gate 	log_facility = log_control.log_entries->lsu_facility = LOG_AUTH;
8947c478bd9Sstevel@tonic-gate 	log_control.log_entries->lsu_severity = LOG_ERR;
8957c478bd9Sstevel@tonic-gate 	do_openlog = 1;
8967c478bd9Sstevel@tonic-gate 	log_control.log_nentries = 1;
8977c478bd9Sstevel@tonic-gate     }
8987c478bd9Sstevel@tonic-gate     if (log_control.log_nentries) {
899159d09a2SMark Phalan 	log_control.log_whoami = (char *) malloc(strlen(whoami)+1);
900159d09a2SMark Phalan 	if (log_control.log_whoami)
9017c478bd9Sstevel@tonic-gate 	    strcpy(log_control.log_whoami, whoami);
902159d09a2SMark Phalan 
903159d09a2SMark Phalan 	log_control.log_hostname = (char *) malloc(MAXHOSTNAMELEN + 1);
904159d09a2SMark Phalan 	if (log_control.log_hostname) {
9057c478bd9Sstevel@tonic-gate 	    gethostname(log_control.log_hostname, MAXHOSTNAMELEN);
906159d09a2SMark Phalan 	    log_control.log_hostname[MAXHOSTNAMELEN] = '\0';
907159d09a2SMark Phalan 	}
908159d09a2SMark Phalan #ifdef	HAVE_OPENLOG
9097c478bd9Sstevel@tonic-gate 	if (do_openlog) {
9107c478bd9Sstevel@tonic-gate 	    openlog(whoami, LOG_NDELAY|LOG_PID, log_facility);
9117c478bd9Sstevel@tonic-gate 	    log_control.log_opened = 1;
9127c478bd9Sstevel@tonic-gate 	}
913159d09a2SMark Phalan #endif /* HAVE_OPENLOG */
9147c478bd9Sstevel@tonic-gate 	if (do_com_err)
9157c478bd9Sstevel@tonic-gate 	    (void) set_com_err_hook(klog_com_err_proc);
9167c478bd9Sstevel@tonic-gate     }
9177c478bd9Sstevel@tonic-gate     return((log_control.log_nentries) ? 0 : ENOENT);
9187c478bd9Sstevel@tonic-gate }
9197c478bd9Sstevel@tonic-gate 
9207c478bd9Sstevel@tonic-gate /*
9217c478bd9Sstevel@tonic-gate  * krb5_klog_close()	- Close the logging context and free all data.
9227c478bd9Sstevel@tonic-gate  */
9237c478bd9Sstevel@tonic-gate void
krb5_klog_close(krb5_context kcontext)924159d09a2SMark Phalan krb5_klog_close(krb5_context kcontext)
9257c478bd9Sstevel@tonic-gate {
9267c478bd9Sstevel@tonic-gate     int lindex;
9277c478bd9Sstevel@tonic-gate     (void) reset_com_err_hook();
9287c478bd9Sstevel@tonic-gate     for (lindex = 0; lindex < log_control.log_nentries; lindex++) {
9297c478bd9Sstevel@tonic-gate 	switch (log_control.log_entries[lindex].log_type) {
9307c478bd9Sstevel@tonic-gate 	case K_LOG_FILE:
9317c478bd9Sstevel@tonic-gate 	case K_LOG_STDERR:
9327c478bd9Sstevel@tonic-gate 	    /*
9337c478bd9Sstevel@tonic-gate 	     * Files/standard error.
9347c478bd9Sstevel@tonic-gate 	     */
9357c478bd9Sstevel@tonic-gate 	    fclose(log_control.log_entries[lindex].lfu_filep);
9367c478bd9Sstevel@tonic-gate 	    break;
9377c478bd9Sstevel@tonic-gate 	case K_LOG_CONSOLE:
9387c478bd9Sstevel@tonic-gate 	case K_LOG_DEVICE:
9397c478bd9Sstevel@tonic-gate 	    /*
9407c478bd9Sstevel@tonic-gate 	     * Devices (may need special handling)
9417c478bd9Sstevel@tonic-gate 	     */
9427c478bd9Sstevel@tonic-gate 	    DEVICE_CLOSE(log_control.log_entries[lindex].ldu_filep);
9437c478bd9Sstevel@tonic-gate 	    break;
944159d09a2SMark Phalan #ifdef	HAVE_SYSLOG
9457c478bd9Sstevel@tonic-gate 	case K_LOG_SYSLOG:
9467c478bd9Sstevel@tonic-gate 	    /*
9477c478bd9Sstevel@tonic-gate 	     * System log.
9487c478bd9Sstevel@tonic-gate 	     */
9497c478bd9Sstevel@tonic-gate 	    break;
950159d09a2SMark Phalan #endif	/* HAVE_SYSLOG */
9517c478bd9Sstevel@tonic-gate 	default:
9527c478bd9Sstevel@tonic-gate 	    break;
9537c478bd9Sstevel@tonic-gate 	}
9547c478bd9Sstevel@tonic-gate 	if (log_control.log_entries[lindex].log_2free)
9557c478bd9Sstevel@tonic-gate 	    free(log_control.log_entries[lindex].log_2free);
9567c478bd9Sstevel@tonic-gate     }
9577c478bd9Sstevel@tonic-gate     if (log_control.log_entries != &def_log_entry)
9587c478bd9Sstevel@tonic-gate 	free(log_control.log_entries);
9597c478bd9Sstevel@tonic-gate     log_control.log_entries = (struct log_entry *) NULL;
9607c478bd9Sstevel@tonic-gate     log_control.log_nentries = 0;
9617c478bd9Sstevel@tonic-gate     if (log_control.log_whoami)
9627c478bd9Sstevel@tonic-gate 	free(log_control.log_whoami);
9637c478bd9Sstevel@tonic-gate     log_control.log_whoami = (char *) NULL;
9647c478bd9Sstevel@tonic-gate     if (log_control.log_hostname)
9657c478bd9Sstevel@tonic-gate 	free(log_control.log_hostname);
9667c478bd9Sstevel@tonic-gate     log_control.log_hostname = (char *) NULL;
967159d09a2SMark Phalan #ifdef	HAVE_CLOSELOG
9687c478bd9Sstevel@tonic-gate     if (log_control.log_opened)
9697c478bd9Sstevel@tonic-gate 	closelog();
970159d09a2SMark Phalan #endif	/* HAVE_CLOSELOG */
9717c478bd9Sstevel@tonic-gate }
9727c478bd9Sstevel@tonic-gate 
9737c478bd9Sstevel@tonic-gate /*
9747c478bd9Sstevel@tonic-gate  * severity2string()	- Convert a severity to a string.
9757c478bd9Sstevel@tonic-gate  */
976159d09a2SMark Phalan static const char *
severity2string(int severity)977159d09a2SMark Phalan severity2string(int severity)
9787c478bd9Sstevel@tonic-gate {
9797c478bd9Sstevel@tonic-gate     int s;
9807c478bd9Sstevel@tonic-gate     const char *ss;
9817c478bd9Sstevel@tonic-gate 
9827c478bd9Sstevel@tonic-gate     s = severity & LOG_PRIMASK;
9837c478bd9Sstevel@tonic-gate     ss = krb5_log_error_table(LOG_UFO_STRING);
9847c478bd9Sstevel@tonic-gate     switch (s) {
985159d09a2SMark Phalan #ifdef	LOG_EMERG
9867c478bd9Sstevel@tonic-gate     case LOG_EMERG:
9877c478bd9Sstevel@tonic-gate 	ss = krb5_log_error_table(LOG_EMERG_STRING);
9887c478bd9Sstevel@tonic-gate 	break;
989159d09a2SMark Phalan #endif	/* LOG_EMERG */
990159d09a2SMark Phalan #ifdef	LOG_ALERT
9917c478bd9Sstevel@tonic-gate     case LOG_ALERT:
9927c478bd9Sstevel@tonic-gate 	ss = krb5_log_error_table(LOG_ALERT_STRING);
9937c478bd9Sstevel@tonic-gate 	break;
994159d09a2SMark Phalan #endif	/* LOG_ALERT */
995159d09a2SMark Phalan #ifdef	LOG_CRIT
9967c478bd9Sstevel@tonic-gate     case LOG_CRIT:
9977c478bd9Sstevel@tonic-gate 	ss = krb5_log_error_table(LOG_CRIT_STRING);
9987c478bd9Sstevel@tonic-gate 	break;
999159d09a2SMark Phalan #endif	/* LOG_CRIT */
10007c478bd9Sstevel@tonic-gate     case LOG_ERR:
10017c478bd9Sstevel@tonic-gate 	ss = krb5_log_error_table(LOG_ERR_STRING);
10027c478bd9Sstevel@tonic-gate 	break;
1003159d09a2SMark Phalan #ifdef	LOG_WARNING
10047c478bd9Sstevel@tonic-gate     case LOG_WARNING:
10057c478bd9Sstevel@tonic-gate 	ss = krb5_log_error_table(LOG_WARNING_STRING);
10067c478bd9Sstevel@tonic-gate 	break;
1007159d09a2SMark Phalan #endif	/* LOG_WARNING */
1008159d09a2SMark Phalan #ifdef	LOG_NOTICE
10097c478bd9Sstevel@tonic-gate     case LOG_NOTICE:
10107c478bd9Sstevel@tonic-gate 	ss = krb5_log_error_table(LOG_NOTICE_STRING);
10117c478bd9Sstevel@tonic-gate 	break;
1012159d09a2SMark Phalan #endif	/* LOG_NOTICE */
1013159d09a2SMark Phalan #ifdef	LOG_INFO
10147c478bd9Sstevel@tonic-gate     case LOG_INFO:
10157c478bd9Sstevel@tonic-gate 	ss = krb5_log_error_table(LOG_INFO_STRING);
10167c478bd9Sstevel@tonic-gate 	break;
1017159d09a2SMark Phalan #endif	/* LOG_INFO */
1018159d09a2SMark Phalan #ifdef	LOG_DEBUG
10197c478bd9Sstevel@tonic-gate     case LOG_DEBUG:
10207c478bd9Sstevel@tonic-gate 	ss = krb5_log_error_table(LOG_DEBUG_STRING);
10217c478bd9Sstevel@tonic-gate 	break;
1022159d09a2SMark Phalan #endif	/* LOG_DEBUG */
10237c478bd9Sstevel@tonic-gate     }
10247c478bd9Sstevel@tonic-gate     return((char *) ss);
10257c478bd9Sstevel@tonic-gate }
10267c478bd9Sstevel@tonic-gate 
10277c478bd9Sstevel@tonic-gate /*
10287c478bd9Sstevel@tonic-gate  * krb5_klog_syslog()	- Simulate the calling sequence of syslog(3), while
10297c478bd9Sstevel@tonic-gate  *			  also performing the logging redirection as specified
10307c478bd9Sstevel@tonic-gate  *			  by krb5_klog_init().
10317c478bd9Sstevel@tonic-gate  */
10327c478bd9Sstevel@tonic-gate static int
klog_vsyslog(int priority,const char * format,va_list arglist)1033159d09a2SMark Phalan klog_vsyslog(int priority, const char *format, va_list arglist)
10347c478bd9Sstevel@tonic-gate {
10357c478bd9Sstevel@tonic-gate     char	outbuf[KRB5_KLOG_MAX_ERRMSG_SIZE];
10367c478bd9Sstevel@tonic-gate     int		lindex;
10377c478bd9Sstevel@tonic-gate     char	*syslogp;
10387c478bd9Sstevel@tonic-gate     char	*cp;
10397c478bd9Sstevel@tonic-gate     time_t	now;
1040159d09a2SMark Phalan #ifdef	HAVE_STRFTIME
10417c478bd9Sstevel@tonic-gate     size_t	soff;
1042159d09a2SMark Phalan #endif	/* HAVE_STRFTIME */
10437c478bd9Sstevel@tonic-gate 
10447c478bd9Sstevel@tonic-gate     /*
10457c478bd9Sstevel@tonic-gate      * Format a syslog-esque message of the format:
10467c478bd9Sstevel@tonic-gate      *
10477c478bd9Sstevel@tonic-gate      * (verbose form)
10487c478bd9Sstevel@tonic-gate      * 		<date> <hostname> <id>[<pid>](<priority>): <message>
10497c478bd9Sstevel@tonic-gate      *
10507c478bd9Sstevel@tonic-gate      * (short form)
10517c478bd9Sstevel@tonic-gate      *		<date> <message>
10527c478bd9Sstevel@tonic-gate      */
10537c478bd9Sstevel@tonic-gate     cp = outbuf;
10547c478bd9Sstevel@tonic-gate     (void) time(&now);
1055159d09a2SMark Phalan #ifdef	HAVE_STRFTIME
10567c478bd9Sstevel@tonic-gate     /*
10577c478bd9Sstevel@tonic-gate      * Format the date: mon dd hh:mm:ss
10587c478bd9Sstevel@tonic-gate      */
10597c478bd9Sstevel@tonic-gate     soff = strftime(outbuf, sizeof(outbuf), "%b %d %H:%M:%S", localtime(&now));
10607c478bd9Sstevel@tonic-gate     if (soff > 0)
10617c478bd9Sstevel@tonic-gate 	cp += soff;
10627c478bd9Sstevel@tonic-gate     else
10637c478bd9Sstevel@tonic-gate 	return(-1);
1064159d09a2SMark Phalan #else	/* HAVE_STRFTIME */
1065159d09a2SMark Phalan     /*
1066159d09a2SMark Phalan      * Format the date:
1067159d09a2SMark Phalan      * We ASSUME here that the output of ctime is of the format:
1068159d09a2SMark Phalan      *	dow mon dd hh:mm:ss tzs yyyy\n
1069159d09a2SMark Phalan      *  012345678901234567890123456789
1070159d09a2SMark Phalan      */
1071159d09a2SMark Phalan     strncpy(outbuf, ctime(&now) + 4, 15);
1072159d09a2SMark Phalan     cp += 15;
1073159d09a2SMark Phalan #endif	/* HAVE_STRFTIME */
10747c478bd9Sstevel@tonic-gate #ifdef VERBOSE_LOGS
1075159d09a2SMark Phalan     sprintf(cp, " %s %s[%ld](%s): ",
1076159d09a2SMark Phalan 	    log_control.log_hostname, log_control.log_whoami, (long) getpid(),
10777c478bd9Sstevel@tonic-gate 	    severity2string(priority));
10787c478bd9Sstevel@tonic-gate #else
10797c478bd9Sstevel@tonic-gate     sprintf(cp, " ");
10807c478bd9Sstevel@tonic-gate #endif
10817c478bd9Sstevel@tonic-gate     syslogp = &outbuf[strlen(outbuf)];
10827c478bd9Sstevel@tonic-gate 
10837c478bd9Sstevel@tonic-gate     /* Now format the actual message */
1084159d09a2SMark Phalan #ifdef	HAVE_VSNPRINTF
1085159d09a2SMark Phalan     vsnprintf(syslogp, sizeof(outbuf) - (syslogp - outbuf), format, arglist);
1086159d09a2SMark Phalan #elif	HAVE_VSPRINTF
1087159d09a2SMark Phalan     vsprintf(syslogp, format, arglist);
1088159d09a2SMark Phalan #else	/* HAVE_VSPRINTF */
1089159d09a2SMark Phalan     sprintf(syslogp, format, ((int *) arglist)[0], ((int *) arglist)[1],
1090159d09a2SMark Phalan 	    ((int *) arglist)[2], ((int *) arglist)[3],
1091159d09a2SMark Phalan 	    ((int *) arglist)[4], ((int *) arglist)[5]);
1092159d09a2SMark Phalan #endif	/* HAVE_VSPRINTF */
1093159d09a2SMark Phalan 
1094159d09a2SMark Phalan     /*
1095159d09a2SMark Phalan      * If the user did not use krb5_klog_init() instead of dropping
1096159d09a2SMark Phalan      * the request on the floor, syslog it - if it exists
1097159d09a2SMark Phalan      */
1098159d09a2SMark Phalan #ifdef HAVE_SYSLOG
1099159d09a2SMark Phalan     if (log_control.log_nentries == 0) {
1100159d09a2SMark Phalan 	/* Log the message with our header trimmed off */
1101159d09a2SMark Phalan 	syslog(priority, "%s", syslogp);
1102159d09a2SMark Phalan     }
1103159d09a2SMark Phalan #endif
11047c478bd9Sstevel@tonic-gate 
11057c478bd9Sstevel@tonic-gate     /*
11067c478bd9Sstevel@tonic-gate      * Now that we have the message formatted, perform the output to each
11077c478bd9Sstevel@tonic-gate      * logging specification.
11087c478bd9Sstevel@tonic-gate      */
11097c478bd9Sstevel@tonic-gate     for (lindex = 0; lindex < log_control.log_nentries; lindex++) {
11107c478bd9Sstevel@tonic-gate 	switch (log_control.log_entries[lindex].log_type) {
11117c478bd9Sstevel@tonic-gate 	case K_LOG_FILE:
11127c478bd9Sstevel@tonic-gate 
11137c478bd9Sstevel@tonic-gate 	    klog_rotate(&log_control.log_entries[lindex]);
11147c478bd9Sstevel@tonic-gate 	    /*FALLTHRU*/
11157c478bd9Sstevel@tonic-gate 	case K_LOG_STDERR:
11167c478bd9Sstevel@tonic-gate 	    /*
11177c478bd9Sstevel@tonic-gate 	     * Files/standard error.
11187c478bd9Sstevel@tonic-gate 	     */
1119159d09a2SMark Phalan 	    if (fprintf(log_control.log_entries[lindex].lfu_filep, "%s\n",
11207c478bd9Sstevel@tonic-gate 			outbuf) < 0) {
11217c478bd9Sstevel@tonic-gate 		/* Attempt to report error */
11227c478bd9Sstevel@tonic-gate 		fprintf(stderr, krb5_log_error_table(LOG_FILE_ERR),
1123159d09a2SMark Phalan 			log_control.log_whoami,
11247c478bd9Sstevel@tonic-gate 			log_control.log_entries[lindex].lfu_fname);
11257c478bd9Sstevel@tonic-gate 	    }
11267c478bd9Sstevel@tonic-gate 	    else {
11277c478bd9Sstevel@tonic-gate 		fflush(log_control.log_entries[lindex].lfu_filep);
11287c478bd9Sstevel@tonic-gate 	    }
11297c478bd9Sstevel@tonic-gate 	    break;
11307c478bd9Sstevel@tonic-gate 	case K_LOG_CONSOLE:
11317c478bd9Sstevel@tonic-gate 	case K_LOG_DEVICE:
11327c478bd9Sstevel@tonic-gate 	    /*
11337c478bd9Sstevel@tonic-gate 	     * Devices (may need special handling)
11347c478bd9Sstevel@tonic-gate 	     */
11357c478bd9Sstevel@tonic-gate 	    if (DEVICE_PRINT(log_control.log_entries[lindex].ldu_filep,
11367c478bd9Sstevel@tonic-gate 			     outbuf) < 0) {
11377c478bd9Sstevel@tonic-gate 		/* Attempt to report error */
11387c478bd9Sstevel@tonic-gate 		fprintf(stderr, krb5_log_error_table(LOG_DEVICE_ERR),
1139159d09a2SMark Phalan 			log_control.log_whoami,
11407c478bd9Sstevel@tonic-gate 			log_control.log_entries[lindex].ldu_devname);
11417c478bd9Sstevel@tonic-gate 	    }
11427c478bd9Sstevel@tonic-gate 	    break;
1143159d09a2SMark Phalan #ifdef	HAVE_SYSLOG
11447c478bd9Sstevel@tonic-gate 	case K_LOG_SYSLOG:
11457c478bd9Sstevel@tonic-gate 	    /*
11467c478bd9Sstevel@tonic-gate 	     * System log.
11477c478bd9Sstevel@tonic-gate 	     */
1148*55fea89dSDan Cross 
11497c478bd9Sstevel@tonic-gate 	    /* Log the message with our header trimmed off */
1150159d09a2SMark Phalan 	    syslog(priority, "%s", syslogp);
11517c478bd9Sstevel@tonic-gate 	    break;
1152159d09a2SMark Phalan #endif /* HAVE_SYSLOG */
11537c478bd9Sstevel@tonic-gate 	default:
11547c478bd9Sstevel@tonic-gate 	    break;
11557c478bd9Sstevel@tonic-gate 	}
11567c478bd9Sstevel@tonic-gate     }
11577c478bd9Sstevel@tonic-gate     return(0);
11587c478bd9Sstevel@tonic-gate }
11597c478bd9Sstevel@tonic-gate 
11607c478bd9Sstevel@tonic-gate int
krb5_klog_syslog(int priority,const char * format,...)11617c478bd9Sstevel@tonic-gate krb5_klog_syslog(int priority, const char *format, ...)
11627c478bd9Sstevel@tonic-gate {
11637c478bd9Sstevel@tonic-gate     int		retval;
11647c478bd9Sstevel@tonic-gate     va_list	pvar;
11657c478bd9Sstevel@tonic-gate 
11667c478bd9Sstevel@tonic-gate     va_start(pvar, format);
11677c478bd9Sstevel@tonic-gate     retval = klog_vsyslog(priority, format, pvar);
11687c478bd9Sstevel@tonic-gate     va_end(pvar);
11697c478bd9Sstevel@tonic-gate     return(retval);
11707c478bd9Sstevel@tonic-gate }
1171