1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * lib/kadm/logger.c 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * Copyright 1995 by the Massachusetts Institute of Technology. 5*7c478bd9Sstevel@tonic-gate * All Rights Reserved. 6*7c478bd9Sstevel@tonic-gate * 7*7c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may 8*7c478bd9Sstevel@tonic-gate * require a specific license from the United States Government. 9*7c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating 10*7c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting. 11*7c478bd9Sstevel@tonic-gate * 12*7c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 13*7c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and 14*7c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright 15*7c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and 16*7c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that 17*7c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining 18*7c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior 19*7c478bd9Sstevel@tonic-gate * permission. M.I.T. makes no representations about the suitability of 20*7c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express 21*7c478bd9Sstevel@tonic-gate * or implied warranty. 22*7c478bd9Sstevel@tonic-gate * 23*7c478bd9Sstevel@tonic-gate */ 24*7c478bd9Sstevel@tonic-gate 25*7c478bd9Sstevel@tonic-gate /* 26*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 27*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 28*7c478bd9Sstevel@tonic-gate */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate /* KADM5 wants non-syslog log files to contain syslog-like entries */ 34*7c478bd9Sstevel@tonic-gate #define VERBOSE_LOGS 35*7c478bd9Sstevel@tonic-gate 36*7c478bd9Sstevel@tonic-gate /* 37*7c478bd9Sstevel@tonic-gate * logger.c - Handle logging functions for those who want it. 38*7c478bd9Sstevel@tonic-gate */ 39*7c478bd9Sstevel@tonic-gate #include "k5-int.h" 40*7c478bd9Sstevel@tonic-gate #include "adm_proto.h" 41*7c478bd9Sstevel@tonic-gate #include "com_err.h" 42*7c478bd9Sstevel@tonic-gate #include <stdio.h> 43*7c478bd9Sstevel@tonic-gate #include <ctype.h> 44*7c478bd9Sstevel@tonic-gate #include <syslog.h> 45*7c478bd9Sstevel@tonic-gate #include <stdarg.h> 46*7c478bd9Sstevel@tonic-gate #include <libintl.h> 47*7c478bd9Sstevel@tonic-gate 48*7c478bd9Sstevel@tonic-gate #define KRB5_KLOG_MAX_ERRMSG_SIZE 1024 49*7c478bd9Sstevel@tonic-gate #ifndef MAXHOSTNAMELEN 50*7c478bd9Sstevel@tonic-gate #define MAXHOSTNAMELEN 256 51*7c478bd9Sstevel@tonic-gate #endif /* MAXHOSTNAMELEN */ 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate #define LSPEC_PARSE_ERR_1 1 54*7c478bd9Sstevel@tonic-gate #define LSPEC_PARSE_ERR_2 2 55*7c478bd9Sstevel@tonic-gate #define LOG_FILE_ERR 3 56*7c478bd9Sstevel@tonic-gate #define LOG_DEVICE_ERR 4 57*7c478bd9Sstevel@tonic-gate #define LOG_UFO_STRING 5 58*7c478bd9Sstevel@tonic-gate #define LOG_EMERG_STRING 6 59*7c478bd9Sstevel@tonic-gate #define LOG_ALERT_STRING 7 60*7c478bd9Sstevel@tonic-gate #define LOG_CRIT_STRING 8 61*7c478bd9Sstevel@tonic-gate #define LOG_ERR_STRING 9 62*7c478bd9Sstevel@tonic-gate #define LOG_WARNING_STRING 10 63*7c478bd9Sstevel@tonic-gate #define LOG_NOTICE_STRING 11 64*7c478bd9Sstevel@tonic-gate #define LOG_INFO_STRING 12 65*7c478bd9Sstevel@tonic-gate #define LOG_DEBUG_STRING 13 66*7c478bd9Sstevel@tonic-gate /* This is to assure that we have at least one match in the syslog stuff */ 67*7c478bd9Sstevel@tonic-gate /* 68*7c478bd9Sstevel@tonic-gate static const char LSPEC_PARSE_ERR_1[] = "%s: cannot parse <%s>\n"; 69*7c478bd9Sstevel@tonic-gate static const char LSPEC_PARSE_ERR_2[] = "%s: warning - logging entry syntax error\n"; 70*7c478bd9Sstevel@tonic-gate static const char LOG_FILE_ERR[] = "%s: error writing to %s\n"; 71*7c478bd9Sstevel@tonic-gate static const char LOG_DEVICE_ERR[] = "%s: error writing to %s device\n"; 72*7c478bd9Sstevel@tonic-gate static const char LOG_UFO_STRING[] = "???"; 73*7c478bd9Sstevel@tonic-gate static const char LOG_EMERG_STRING[] = "EMERGENCY"; 74*7c478bd9Sstevel@tonic-gate static const char LOG_ALERT_STRING[] = "ALERT"; 75*7c478bd9Sstevel@tonic-gate static const char LOG_CRIT_STRING[] = "CRITICAL"; 76*7c478bd9Sstevel@tonic-gate static const char LOG_ERR_STRING[] = "Error"; 77*7c478bd9Sstevel@tonic-gate static const char LOG_WARNING_STRING[] = "Warning"; 78*7c478bd9Sstevel@tonic-gate static const char LOG_NOTICE_STRING[] = "Notice"; 79*7c478bd9Sstevel@tonic-gate static const char LOG_INFO_STRING[] = "info"; 80*7c478bd9Sstevel@tonic-gate static const char LOG_DEBUG_STRING[] = "debug"; 81*7c478bd9Sstevel@tonic-gate */ 82*7c478bd9Sstevel@tonic-gate 83*7c478bd9Sstevel@tonic-gate 84*7c478bd9Sstevel@tonic-gate const char * 85*7c478bd9Sstevel@tonic-gate krb5_log_error_table(long errorno) { 86*7c478bd9Sstevel@tonic-gate switch (errorno) { 87*7c478bd9Sstevel@tonic-gate case LSPEC_PARSE_ERR_1: 88*7c478bd9Sstevel@tonic-gate return(gettext("%s: cannot parse <%s>\n")); 89*7c478bd9Sstevel@tonic-gate case LSPEC_PARSE_ERR_2: 90*7c478bd9Sstevel@tonic-gate return(gettext("%s: warning - logging entry syntax error\n")); 91*7c478bd9Sstevel@tonic-gate case LOG_FILE_ERR: 92*7c478bd9Sstevel@tonic-gate return(gettext("%s: error writing to %s\n")); 93*7c478bd9Sstevel@tonic-gate case LOG_DEVICE_ERR: 94*7c478bd9Sstevel@tonic-gate return(gettext("%s: error writing to %s device\n")); 95*7c478bd9Sstevel@tonic-gate case LOG_UFO_STRING: 96*7c478bd9Sstevel@tonic-gate return(gettext("???")); 97*7c478bd9Sstevel@tonic-gate case LOG_EMERG_STRING: 98*7c478bd9Sstevel@tonic-gate return(gettext("EMERGENCY")); 99*7c478bd9Sstevel@tonic-gate case LOG_ALERT_STRING: 100*7c478bd9Sstevel@tonic-gate return(gettext("ALERT")); 101*7c478bd9Sstevel@tonic-gate case LOG_CRIT_STRING: 102*7c478bd9Sstevel@tonic-gate return(gettext("CRITICAL")); 103*7c478bd9Sstevel@tonic-gate case LOG_ERR_STRING: 104*7c478bd9Sstevel@tonic-gate return(gettext("Error")); 105*7c478bd9Sstevel@tonic-gate case LOG_WARNING_STRING: 106*7c478bd9Sstevel@tonic-gate return(gettext("Warning")); 107*7c478bd9Sstevel@tonic-gate case LOG_NOTICE_STRING: 108*7c478bd9Sstevel@tonic-gate return(gettext("Notice")); 109*7c478bd9Sstevel@tonic-gate case LOG_INFO_STRING: 110*7c478bd9Sstevel@tonic-gate case LOG_DEBUG_STRING: 111*7c478bd9Sstevel@tonic-gate default: 112*7c478bd9Sstevel@tonic-gate return(gettext("info")); 113*7c478bd9Sstevel@tonic-gate } 114*7c478bd9Sstevel@tonic-gate } 115*7c478bd9Sstevel@tonic-gate 116*7c478bd9Sstevel@tonic-gate /* 117*7c478bd9Sstevel@tonic-gate * Output logging. 118*7c478bd9Sstevel@tonic-gate * 119*7c478bd9Sstevel@tonic-gate * Output logging is now controlled by the configuration file. We can specify 120*7c478bd9Sstevel@tonic-gate * the following syntaxes under the [logging]->entity specification. 121*7c478bd9Sstevel@tonic-gate * FILE<opentype><pathname> 122*7c478bd9Sstevel@tonic-gate * SYSLOG[=<severity>[:<facility>]] 123*7c478bd9Sstevel@tonic-gate * STDERR 124*7c478bd9Sstevel@tonic-gate * CONSOLE 125*7c478bd9Sstevel@tonic-gate * DEVICE=<device-spec> 126*7c478bd9Sstevel@tonic-gate * 127*7c478bd9Sstevel@tonic-gate * Where: 128*7c478bd9Sstevel@tonic-gate * <opentype> is ":" for open/append, "=" for open/create. 129*7c478bd9Sstevel@tonic-gate * <pathname> is a valid path name. 130*7c478bd9Sstevel@tonic-gate * <severity> is one of: (default = ERR) 131*7c478bd9Sstevel@tonic-gate * EMERG 132*7c478bd9Sstevel@tonic-gate * ALERT 133*7c478bd9Sstevel@tonic-gate * CRIT 134*7c478bd9Sstevel@tonic-gate * ERR 135*7c478bd9Sstevel@tonic-gate * WARNING 136*7c478bd9Sstevel@tonic-gate * NOTICE 137*7c478bd9Sstevel@tonic-gate * INFO 138*7c478bd9Sstevel@tonic-gate * DEBUG 139*7c478bd9Sstevel@tonic-gate * <facility> is one of: (default = AUTH) 140*7c478bd9Sstevel@tonic-gate * KERN 141*7c478bd9Sstevel@tonic-gate * USER 142*7c478bd9Sstevel@tonic-gate * MAIL 143*7c478bd9Sstevel@tonic-gate * DAEMON 144*7c478bd9Sstevel@tonic-gate * AUTH 145*7c478bd9Sstevel@tonic-gate * LPR 146*7c478bd9Sstevel@tonic-gate * NEWS 147*7c478bd9Sstevel@tonic-gate * UUCP 148*7c478bd9Sstevel@tonic-gate * AUDIT 149*7c478bd9Sstevel@tonic-gate * CRON 150*7c478bd9Sstevel@tonic-gate * LOCAL0..LOCAL7 151*7c478bd9Sstevel@tonic-gate * <device-spec> is a valid device specification. 152*7c478bd9Sstevel@tonic-gate */ 153*7c478bd9Sstevel@tonic-gate struct log_entry { 154*7c478bd9Sstevel@tonic-gate enum log_type { K_LOG_FILE, 155*7c478bd9Sstevel@tonic-gate K_LOG_SYSLOG, 156*7c478bd9Sstevel@tonic-gate K_LOG_STDERR, 157*7c478bd9Sstevel@tonic-gate K_LOG_CONSOLE, 158*7c478bd9Sstevel@tonic-gate K_LOG_DEVICE, 159*7c478bd9Sstevel@tonic-gate K_LOG_NONE } log_type; 160*7c478bd9Sstevel@tonic-gate krb5_pointer log_2free; 161*7c478bd9Sstevel@tonic-gate union log_union { 162*7c478bd9Sstevel@tonic-gate struct log_file { 163*7c478bd9Sstevel@tonic-gate FILE *lf_filep; 164*7c478bd9Sstevel@tonic-gate char *lf_fname; 165*7c478bd9Sstevel@tonic-gate char *lf_fopen_mode; /* "a+" or "w" */ 166*7c478bd9Sstevel@tonic-gate #define K_LOG_DEF_FILE_ROTATE_PERIOD -1 /* never */ 167*7c478bd9Sstevel@tonic-gate #define K_LOG_DEF_FILE_ROTATE_VERSIONS 0 /* no versions */ 168*7c478bd9Sstevel@tonic-gate time_t lf_rotate_period; 169*7c478bd9Sstevel@tonic-gate time_t lf_last_rotated; 170*7c478bd9Sstevel@tonic-gate int lf_rotate_versions; 171*7c478bd9Sstevel@tonic-gate } log_file; 172*7c478bd9Sstevel@tonic-gate struct log_syslog { 173*7c478bd9Sstevel@tonic-gate int ls_facility; 174*7c478bd9Sstevel@tonic-gate int ls_severity; 175*7c478bd9Sstevel@tonic-gate } log_syslog; 176*7c478bd9Sstevel@tonic-gate struct log_device { 177*7c478bd9Sstevel@tonic-gate FILE *ld_filep; 178*7c478bd9Sstevel@tonic-gate char *ld_devname; 179*7c478bd9Sstevel@tonic-gate } log_device; 180*7c478bd9Sstevel@tonic-gate } log_union; 181*7c478bd9Sstevel@tonic-gate }; 182*7c478bd9Sstevel@tonic-gate #define lfu_filep log_union.log_file.lf_filep 183*7c478bd9Sstevel@tonic-gate #define lfu_fname log_union.log_file.lf_fname 184*7c478bd9Sstevel@tonic-gate #define lfu_fopen_mode log_union.log_file.lf_fopen_mode 185*7c478bd9Sstevel@tonic-gate #define lfu_rotate_period log_union.log_file.lf_rotate_period 186*7c478bd9Sstevel@tonic-gate #define lfu_last_rotated log_union.log_file.lf_last_rotated 187*7c478bd9Sstevel@tonic-gate #define lfu_rotate_versions log_union.log_file.lf_rotate_versions 188*7c478bd9Sstevel@tonic-gate #define lsu_facility log_union.log_syslog.ls_facility 189*7c478bd9Sstevel@tonic-gate #define lsu_severity log_union.log_syslog.ls_severity 190*7c478bd9Sstevel@tonic-gate #define ldu_filep log_union.log_device.ld_filep 191*7c478bd9Sstevel@tonic-gate #define ldu_devname log_union.log_device.ld_devname 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate struct log_control { 194*7c478bd9Sstevel@tonic-gate struct log_entry *log_entries; 195*7c478bd9Sstevel@tonic-gate int log_nentries; 196*7c478bd9Sstevel@tonic-gate char *log_whoami; 197*7c478bd9Sstevel@tonic-gate char *log_hostname; 198*7c478bd9Sstevel@tonic-gate krb5_boolean log_opened; 199*7c478bd9Sstevel@tonic-gate 200*7c478bd9Sstevel@tonic-gate }; 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate static struct log_control log_control = { 203*7c478bd9Sstevel@tonic-gate (struct log_entry *) NULL, 204*7c478bd9Sstevel@tonic-gate 0, 205*7c478bd9Sstevel@tonic-gate (char *) NULL, 206*7c478bd9Sstevel@tonic-gate (char *) NULL, 207*7c478bd9Sstevel@tonic-gate 0 208*7c478bd9Sstevel@tonic-gate }; 209*7c478bd9Sstevel@tonic-gate static struct log_entry def_log_entry; 210*7c478bd9Sstevel@tonic-gate 211*7c478bd9Sstevel@tonic-gate /* 212*7c478bd9Sstevel@tonic-gate * These macros define any special processing that needs to happen for 213*7c478bd9Sstevel@tonic-gate * devices. For unix, of course, this is hardly anything. 214*7c478bd9Sstevel@tonic-gate */ 215*7c478bd9Sstevel@tonic-gate #define DEVICE_OPEN(d, m) fopen(d, m) 216*7c478bd9Sstevel@tonic-gate #define CONSOLE_OPEN(m) fopen("/dev/console", m) 217*7c478bd9Sstevel@tonic-gate #define DEVICE_PRINT(f, m) ((fprintf(f, m) >= 0) ? \ 218*7c478bd9Sstevel@tonic-gate (fprintf(f, "\r\n"), fflush(f), 0) : \ 219*7c478bd9Sstevel@tonic-gate -1) 220*7c478bd9Sstevel@tonic-gate #define DEVICE_CLOSE(d) fclose(d) 221*7c478bd9Sstevel@tonic-gate 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate /* 224*7c478bd9Sstevel@tonic-gate * klog_rotate() - roate a log file if we have specified rotation 225*7c478bd9Sstevel@tonic-gate * parameters in krb5.conf. 226*7c478bd9Sstevel@tonic-gate */ 227*7c478bd9Sstevel@tonic-gate static void 228*7c478bd9Sstevel@tonic-gate klog_rotate(struct log_entry *le) 229*7c478bd9Sstevel@tonic-gate { 230*7c478bd9Sstevel@tonic-gate time_t t; 231*7c478bd9Sstevel@tonic-gate int i; 232*7c478bd9Sstevel@tonic-gate char *name_buf1; 233*7c478bd9Sstevel@tonic-gate char *name_buf2; 234*7c478bd9Sstevel@tonic-gate char *old_name; 235*7c478bd9Sstevel@tonic-gate char *new_name; 236*7c478bd9Sstevel@tonic-gate char *tmp; 237*7c478bd9Sstevel@tonic-gate FILE *fp; 238*7c478bd9Sstevel@tonic-gate int num_vers; 239*7c478bd9Sstevel@tonic-gate 240*7c478bd9Sstevel@tonic-gate /* 241*7c478bd9Sstevel@tonic-gate * By default we don't rotate. 242*7c478bd9Sstevel@tonic-gate */ 243*7c478bd9Sstevel@tonic-gate if (le->lfu_rotate_period == K_LOG_DEF_FILE_ROTATE_PERIOD) 244*7c478bd9Sstevel@tonic-gate return; 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate t = time(0); 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate if (t >= le->lfu_last_rotated + le->lfu_rotate_period) { 249*7c478bd9Sstevel@tonic-gate /* 250*7c478bd9Sstevel@tonic-gate * The N log file versions will be renamed X.N-1 X.N-2, ... X.0. 251*7c478bd9Sstevel@tonic-gate * So the allocate file name buffers that can the version 252*7c478bd9Sstevel@tonic-gate * number extensions. 253*7c478bd9Sstevel@tonic-gate * 32 extra bytes is plenty. 254*7c478bd9Sstevel@tonic-gate */ 255*7c478bd9Sstevel@tonic-gate name_buf1 = malloc(strlen(le->lfu_fname) + 32); 256*7c478bd9Sstevel@tonic-gate 257*7c478bd9Sstevel@tonic-gate if (name_buf1 == NULL) 258*7c478bd9Sstevel@tonic-gate return; 259*7c478bd9Sstevel@tonic-gate 260*7c478bd9Sstevel@tonic-gate name_buf2 = malloc(strlen(le->lfu_fname) + 32); 261*7c478bd9Sstevel@tonic-gate 262*7c478bd9Sstevel@tonic-gate if (name_buf2 == NULL) { 263*7c478bd9Sstevel@tonic-gate free(name_buf1); 264*7c478bd9Sstevel@tonic-gate return; 265*7c478bd9Sstevel@tonic-gate } 266*7c478bd9Sstevel@tonic-gate 267*7c478bd9Sstevel@tonic-gate old_name = name_buf1; 268*7c478bd9Sstevel@tonic-gate new_name = name_buf2; 269*7c478bd9Sstevel@tonic-gate 270*7c478bd9Sstevel@tonic-gate /* 271*7c478bd9Sstevel@tonic-gate * If there N versions, then the first one has file extension 272*7c478bd9Sstevel@tonic-gate * of N-1. 273*7c478bd9Sstevel@tonic-gate */ 274*7c478bd9Sstevel@tonic-gate (void) sprintf(new_name, "%s.%d", le->lfu_fname, 275*7c478bd9Sstevel@tonic-gate le->lfu_rotate_versions - 1); 276*7c478bd9Sstevel@tonic-gate 277*7c478bd9Sstevel@tonic-gate /* 278*7c478bd9Sstevel@tonic-gate * Rename file.N-2 to file.N-1, file.N-3 to file.N-2, ... 279*7c478bd9Sstevel@tonic-gate * file.0 to file.1 280*7c478bd9Sstevel@tonic-gate */ 281*7c478bd9Sstevel@tonic-gate for (i = le->lfu_rotate_versions - 1; i > 0; i--) { 282*7c478bd9Sstevel@tonic-gate (void) sprintf(old_name, "%s.%d", le->lfu_fname, i - 1); 283*7c478bd9Sstevel@tonic-gate (void) rename(old_name, new_name); 284*7c478bd9Sstevel@tonic-gate 285*7c478bd9Sstevel@tonic-gate /* 286*7c478bd9Sstevel@tonic-gate * swap old name and new name. This way, 287*7c478bd9Sstevel@tonic-gate * on the next iteration, new_name.X 288*7c478bd9Sstevel@tonic-gate * becomes new_name.X-1. 289*7c478bd9Sstevel@tonic-gate */ 290*7c478bd9Sstevel@tonic-gate tmp = old_name; 291*7c478bd9Sstevel@tonic-gate old_name = new_name; 292*7c478bd9Sstevel@tonic-gate new_name = tmp; 293*7c478bd9Sstevel@tonic-gate } 294*7c478bd9Sstevel@tonic-gate old_name = le->lfu_fname; 295*7c478bd9Sstevel@tonic-gate 296*7c478bd9Sstevel@tonic-gate (void) rename(old_name, new_name); 297*7c478bd9Sstevel@tonic-gate 298*7c478bd9Sstevel@tonic-gate /* 299*7c478bd9Sstevel@tonic-gate * Even though we don't know yet if the fopen() 300*7c478bd9Sstevel@tonic-gate * of the log file will succeed, we mark the log 301*7c478bd9Sstevel@tonic-gate * as rotated. This is so we don't repeatably 302*7c478bd9Sstevel@tonic-gate * rotate file.N-2 to file.N-1 ... etc without 303*7c478bd9Sstevel@tonic-gate * waiting for the rotate period to elapse. 304*7c478bd9Sstevel@tonic-gate */ 305*7c478bd9Sstevel@tonic-gate le->lfu_last_rotated = t; 306*7c478bd9Sstevel@tonic-gate 307*7c478bd9Sstevel@tonic-gate fp = fopen(old_name, le->lfu_fopen_mode); 308*7c478bd9Sstevel@tonic-gate 309*7c478bd9Sstevel@tonic-gate if (fp != NULL) { 310*7c478bd9Sstevel@tonic-gate 311*7c478bd9Sstevel@tonic-gate /* Set the permissions to 644 */ 312*7c478bd9Sstevel@tonic-gate if (fchmod(fileno(fp), 313*7c478bd9Sstevel@tonic-gate S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) == -1) { 314*7c478bd9Sstevel@tonic-gate fprintf(stderr, 315*7c478bd9Sstevel@tonic-gate gettext("During rotate, couldn't set permissions for log file %s: %s\n"), 316*7c478bd9Sstevel@tonic-gate old_name, error_message(errno)); 317*7c478bd9Sstevel@tonic-gate } 318*7c478bd9Sstevel@tonic-gate 319*7c478bd9Sstevel@tonic-gate (void) fclose(le->lfu_filep); 320*7c478bd9Sstevel@tonic-gate le->lfu_filep = fp; 321*7c478bd9Sstevel@tonic-gate 322*7c478bd9Sstevel@tonic-gate /* 323*7c478bd9Sstevel@tonic-gate * If the version parameter in krb5.conf was 324*7c478bd9Sstevel@tonic-gate * 0, then we take this to mean that rotating the 325*7c478bd9Sstevel@tonic-gate * log file will cause us to dispose of the 326*7c478bd9Sstevel@tonic-gate * old one, and created a new one. We have just 327*7c478bd9Sstevel@tonic-gate * renamed the old one to file.-1, so remove it. 328*7c478bd9Sstevel@tonic-gate */ 329*7c478bd9Sstevel@tonic-gate if (le->lfu_rotate_versions <= 0) 330*7c478bd9Sstevel@tonic-gate (void) unlink(new_name); 331*7c478bd9Sstevel@tonic-gate 332*7c478bd9Sstevel@tonic-gate } else { 333*7c478bd9Sstevel@tonic-gate fprintf(stderr, 334*7c478bd9Sstevel@tonic-gate gettext("During rotate, couldn't open log file %s: %s\n"), 335*7c478bd9Sstevel@tonic-gate old_name, error_message(errno)); 336*7c478bd9Sstevel@tonic-gate /* 337*7c478bd9Sstevel@tonic-gate * Put it back. 338*7c478bd9Sstevel@tonic-gate */ 339*7c478bd9Sstevel@tonic-gate (void) rename(new_name, old_name); 340*7c478bd9Sstevel@tonic-gate } 341*7c478bd9Sstevel@tonic-gate free(name_buf1); 342*7c478bd9Sstevel@tonic-gate free(name_buf2); 343*7c478bd9Sstevel@tonic-gate } 344*7c478bd9Sstevel@tonic-gate } 345*7c478bd9Sstevel@tonic-gate 346*7c478bd9Sstevel@tonic-gate /* 347*7c478bd9Sstevel@tonic-gate * klog_com_err_proc() - Handle com_err(3) messages as specified by the 348*7c478bd9Sstevel@tonic-gate * profile. 349*7c478bd9Sstevel@tonic-gate */ 350*7c478bd9Sstevel@tonic-gate static void 351*7c478bd9Sstevel@tonic-gate klog_com_err_proc(whoami, code, format, ap) 352*7c478bd9Sstevel@tonic-gate const char *whoami; 353*7c478bd9Sstevel@tonic-gate long code; 354*7c478bd9Sstevel@tonic-gate const char *format; 355*7c478bd9Sstevel@tonic-gate va_list ap; 356*7c478bd9Sstevel@tonic-gate { 357*7c478bd9Sstevel@tonic-gate char outbuf[KRB5_KLOG_MAX_ERRMSG_SIZE]; 358*7c478bd9Sstevel@tonic-gate int lindex; 359*7c478bd9Sstevel@tonic-gate char *actual_format; 360*7c478bd9Sstevel@tonic-gate int log_pri = -1; 361*7c478bd9Sstevel@tonic-gate char *cp; 362*7c478bd9Sstevel@tonic-gate char *syslogp; 363*7c478bd9Sstevel@tonic-gate 364*7c478bd9Sstevel@tonic-gate /* Make the header */ 365*7c478bd9Sstevel@tonic-gate sprintf(outbuf, "%s: ", whoami); 366*7c478bd9Sstevel@tonic-gate /* 367*7c478bd9Sstevel@tonic-gate * Squirrel away address after header for syslog since syslog makes 368*7c478bd9Sstevel@tonic-gate * a header 369*7c478bd9Sstevel@tonic-gate */ 370*7c478bd9Sstevel@tonic-gate syslogp = &outbuf[strlen(outbuf)]; 371*7c478bd9Sstevel@tonic-gate 372*7c478bd9Sstevel@tonic-gate /* If reporting an error message, separate it. */ 373*7c478bd9Sstevel@tonic-gate if (code) { 374*7c478bd9Sstevel@tonic-gate strcat(outbuf, error_message(code)); 375*7c478bd9Sstevel@tonic-gate strcat(outbuf, " - "); 376*7c478bd9Sstevel@tonic-gate } 377*7c478bd9Sstevel@tonic-gate cp = &outbuf[strlen(outbuf)]; 378*7c478bd9Sstevel@tonic-gate 379*7c478bd9Sstevel@tonic-gate actual_format = (char *) format; 380*7c478bd9Sstevel@tonic-gate /* 381*7c478bd9Sstevel@tonic-gate * This is an unpleasant hack. If the first character is less than 382*7c478bd9Sstevel@tonic-gate * 8, then we assume that it is a priority. 383*7c478bd9Sstevel@tonic-gate * 384*7c478bd9Sstevel@tonic-gate * Since it is not guaranteed that there is a direct mapping between 385*7c478bd9Sstevel@tonic-gate * syslog priorities (e.g. Ultrix and old BSD), we resort to this 386*7c478bd9Sstevel@tonic-gate * intermediate representation. 387*7c478bd9Sstevel@tonic-gate */ 388*7c478bd9Sstevel@tonic-gate if ((((unsigned char) *format) > 0) && (((unsigned char) *format) <= 8)) { 389*7c478bd9Sstevel@tonic-gate actual_format = (char *) (format + 1); 390*7c478bd9Sstevel@tonic-gate switch ((unsigned char) *format) { 391*7c478bd9Sstevel@tonic-gate case 1: 392*7c478bd9Sstevel@tonic-gate log_pri = LOG_EMERG; 393*7c478bd9Sstevel@tonic-gate break; 394*7c478bd9Sstevel@tonic-gate case 2: 395*7c478bd9Sstevel@tonic-gate log_pri = LOG_ALERT; 396*7c478bd9Sstevel@tonic-gate break; 397*7c478bd9Sstevel@tonic-gate case 3: 398*7c478bd9Sstevel@tonic-gate log_pri = LOG_CRIT; 399*7c478bd9Sstevel@tonic-gate break; 400*7c478bd9Sstevel@tonic-gate default: 401*7c478bd9Sstevel@tonic-gate case 4: 402*7c478bd9Sstevel@tonic-gate log_pri = LOG_ERR; 403*7c478bd9Sstevel@tonic-gate break; 404*7c478bd9Sstevel@tonic-gate case 5: 405*7c478bd9Sstevel@tonic-gate log_pri = LOG_WARNING; 406*7c478bd9Sstevel@tonic-gate break; 407*7c478bd9Sstevel@tonic-gate case 6: 408*7c478bd9Sstevel@tonic-gate log_pri = LOG_NOTICE; 409*7c478bd9Sstevel@tonic-gate break; 410*7c478bd9Sstevel@tonic-gate case 7: 411*7c478bd9Sstevel@tonic-gate log_pri = LOG_INFO; 412*7c478bd9Sstevel@tonic-gate break; 413*7c478bd9Sstevel@tonic-gate case 8: 414*7c478bd9Sstevel@tonic-gate log_pri = LOG_DEBUG; 415*7c478bd9Sstevel@tonic-gate break; 416*7c478bd9Sstevel@tonic-gate } 417*7c478bd9Sstevel@tonic-gate } 418*7c478bd9Sstevel@tonic-gate 419*7c478bd9Sstevel@tonic-gate /* Now format the actual message */ 420*7c478bd9Sstevel@tonic-gate vsprintf(cp, actual_format, ap); 421*7c478bd9Sstevel@tonic-gate 422*7c478bd9Sstevel@tonic-gate /* 423*7c478bd9Sstevel@tonic-gate * Now that we have the message formatted, perform the output to each 424*7c478bd9Sstevel@tonic-gate * logging specification. 425*7c478bd9Sstevel@tonic-gate */ 426*7c478bd9Sstevel@tonic-gate for (lindex = 0; lindex < log_control.log_nentries; lindex++) { 427*7c478bd9Sstevel@tonic-gate switch (log_control.log_entries[lindex].log_type) { 428*7c478bd9Sstevel@tonic-gate case K_LOG_FILE: 429*7c478bd9Sstevel@tonic-gate 430*7c478bd9Sstevel@tonic-gate klog_rotate(&log_control.log_entries[lindex]); 431*7c478bd9Sstevel@tonic-gate /*FALLTHRU*/ 432*7c478bd9Sstevel@tonic-gate case K_LOG_STDERR: 433*7c478bd9Sstevel@tonic-gate /* 434*7c478bd9Sstevel@tonic-gate * Files/standard error. 435*7c478bd9Sstevel@tonic-gate */ 436*7c478bd9Sstevel@tonic-gate if (fprintf(log_control.log_entries[lindex].lfu_filep, 437*7c478bd9Sstevel@tonic-gate outbuf) < 0) { 438*7c478bd9Sstevel@tonic-gate /* Attempt to report error */ 439*7c478bd9Sstevel@tonic-gate fprintf(stderr, krb5_log_error_table(LOG_FILE_ERR), whoami, 440*7c478bd9Sstevel@tonic-gate log_control.log_entries[lindex].lfu_fname); 441*7c478bd9Sstevel@tonic-gate } 442*7c478bd9Sstevel@tonic-gate else { 443*7c478bd9Sstevel@tonic-gate fprintf(log_control.log_entries[lindex].lfu_filep, "\n"); 444*7c478bd9Sstevel@tonic-gate fflush(log_control.log_entries[lindex].lfu_filep); 445*7c478bd9Sstevel@tonic-gate } 446*7c478bd9Sstevel@tonic-gate break; 447*7c478bd9Sstevel@tonic-gate case K_LOG_CONSOLE: 448*7c478bd9Sstevel@tonic-gate case K_LOG_DEVICE: 449*7c478bd9Sstevel@tonic-gate /* 450*7c478bd9Sstevel@tonic-gate * Devices (may need special handling) 451*7c478bd9Sstevel@tonic-gate */ 452*7c478bd9Sstevel@tonic-gate if (DEVICE_PRINT(log_control.log_entries[lindex].ldu_filep, 453*7c478bd9Sstevel@tonic-gate outbuf) < 0) { 454*7c478bd9Sstevel@tonic-gate /* Attempt to report error */ 455*7c478bd9Sstevel@tonic-gate fprintf(stderr, krb5_log_error_table(LOG_DEVICE_ERR), whoami, 456*7c478bd9Sstevel@tonic-gate log_control.log_entries[lindex].ldu_devname); 457*7c478bd9Sstevel@tonic-gate } 458*7c478bd9Sstevel@tonic-gate break; 459*7c478bd9Sstevel@tonic-gate case K_LOG_SYSLOG: 460*7c478bd9Sstevel@tonic-gate /* 461*7c478bd9Sstevel@tonic-gate * System log. 462*7c478bd9Sstevel@tonic-gate */ 463*7c478bd9Sstevel@tonic-gate /* 464*7c478bd9Sstevel@tonic-gate * If we have specified a priority through our hackery, then 465*7c478bd9Sstevel@tonic-gate * use it, otherwise use the default. 466*7c478bd9Sstevel@tonic-gate */ 467*7c478bd9Sstevel@tonic-gate if (log_pri >= 0) 468*7c478bd9Sstevel@tonic-gate log_pri |= log_control.log_entries[lindex].lsu_facility; 469*7c478bd9Sstevel@tonic-gate else 470*7c478bd9Sstevel@tonic-gate log_pri = log_control.log_entries[lindex].lsu_facility | 471*7c478bd9Sstevel@tonic-gate log_control.log_entries[lindex].lsu_severity; 472*7c478bd9Sstevel@tonic-gate 473*7c478bd9Sstevel@tonic-gate /* Log the message with our header trimmed off */ 474*7c478bd9Sstevel@tonic-gate syslog(log_pri, syslogp); 475*7c478bd9Sstevel@tonic-gate break; 476*7c478bd9Sstevel@tonic-gate default: 477*7c478bd9Sstevel@tonic-gate break; 478*7c478bd9Sstevel@tonic-gate } 479*7c478bd9Sstevel@tonic-gate } 480*7c478bd9Sstevel@tonic-gate } 481*7c478bd9Sstevel@tonic-gate 482*7c478bd9Sstevel@tonic-gate /* 483*7c478bd9Sstevel@tonic-gate * krb5_klog_init() - Initialize logging. 484*7c478bd9Sstevel@tonic-gate * 485*7c478bd9Sstevel@tonic-gate * This routine parses the syntax described above to specify destinations for 486*7c478bd9Sstevel@tonic-gate * com_err(3) or krb5_klog_syslog() messages generated by the caller. 487*7c478bd9Sstevel@tonic-gate * 488*7c478bd9Sstevel@tonic-gate * Parameters: 489*7c478bd9Sstevel@tonic-gate * kcontext - Kerberos context. 490*7c478bd9Sstevel@tonic-gate * ename - Entity name as it is to appear in the profile. 491*7c478bd9Sstevel@tonic-gate * whoami - Entity name as it is to appear in error output. 492*7c478bd9Sstevel@tonic-gate * do_com_err - Take over com_err(3) processing. 493*7c478bd9Sstevel@tonic-gate * 494*7c478bd9Sstevel@tonic-gate * Implicit inputs: 495*7c478bd9Sstevel@tonic-gate * stderr - This is where STDERR output goes. 496*7c478bd9Sstevel@tonic-gate * 497*7c478bd9Sstevel@tonic-gate * Implicit outputs: 498*7c478bd9Sstevel@tonic-gate * log_nentries - Number of log entries, both valid and invalid. 499*7c478bd9Sstevel@tonic-gate * log_control - List of entries (log_nentries long) which contains 500*7c478bd9Sstevel@tonic-gate * data for klog_com_err_proc() to use to determine 501*7c478bd9Sstevel@tonic-gate * where/how to send output. 502*7c478bd9Sstevel@tonic-gate */ 503*7c478bd9Sstevel@tonic-gate krb5_error_code 504*7c478bd9Sstevel@tonic-gate krb5_klog_init(kcontext, ename, whoami, do_com_err) 505*7c478bd9Sstevel@tonic-gate krb5_context kcontext; 506*7c478bd9Sstevel@tonic-gate char *ename; 507*7c478bd9Sstevel@tonic-gate char *whoami; 508*7c478bd9Sstevel@tonic-gate krb5_boolean do_com_err; 509*7c478bd9Sstevel@tonic-gate { 510*7c478bd9Sstevel@tonic-gate const char *logging_profent[3]; 511*7c478bd9Sstevel@tonic-gate const char *logging_defent[3]; 512*7c478bd9Sstevel@tonic-gate char **logging_specs; 513*7c478bd9Sstevel@tonic-gate int i, ngood; 514*7c478bd9Sstevel@tonic-gate char *cp, *cp2; 515*7c478bd9Sstevel@tonic-gate char savec; 516*7c478bd9Sstevel@tonic-gate int error; 517*7c478bd9Sstevel@tonic-gate int do_openlog, log_facility; 518*7c478bd9Sstevel@tonic-gate FILE *f; 519*7c478bd9Sstevel@tonic-gate 520*7c478bd9Sstevel@tonic-gate /* Initialize */ 521*7c478bd9Sstevel@tonic-gate do_openlog = 0; 522*7c478bd9Sstevel@tonic-gate log_facility = 0; 523*7c478bd9Sstevel@tonic-gate 524*7c478bd9Sstevel@tonic-gate /* 525*7c478bd9Sstevel@tonic-gate * Look up [logging]-><ename> in the profile. If that doesn't 526*7c478bd9Sstevel@tonic-gate * succeed, then look for [logging]->default. 527*7c478bd9Sstevel@tonic-gate */ 528*7c478bd9Sstevel@tonic-gate logging_profent[0] = "logging"; 529*7c478bd9Sstevel@tonic-gate logging_profent[1] = ename; 530*7c478bd9Sstevel@tonic-gate logging_profent[2] = (char *) NULL; 531*7c478bd9Sstevel@tonic-gate logging_defent[0] = "logging"; 532*7c478bd9Sstevel@tonic-gate logging_defent[1] = "default"; 533*7c478bd9Sstevel@tonic-gate logging_defent[2] = (char *) NULL; 534*7c478bd9Sstevel@tonic-gate logging_specs = (char **) NULL; 535*7c478bd9Sstevel@tonic-gate ngood = 0; 536*7c478bd9Sstevel@tonic-gate log_control.log_nentries = 0; 537*7c478bd9Sstevel@tonic-gate if (!profile_get_values(kcontext->profile, 538*7c478bd9Sstevel@tonic-gate logging_profent, 539*7c478bd9Sstevel@tonic-gate &logging_specs) || 540*7c478bd9Sstevel@tonic-gate !profile_get_values(kcontext->profile, 541*7c478bd9Sstevel@tonic-gate logging_defent, 542*7c478bd9Sstevel@tonic-gate &logging_specs)) { 543*7c478bd9Sstevel@tonic-gate /* 544*7c478bd9Sstevel@tonic-gate * We have a match, so we first count the number of elements 545*7c478bd9Sstevel@tonic-gate */ 546*7c478bd9Sstevel@tonic-gate for (log_control.log_nentries = 0; 547*7c478bd9Sstevel@tonic-gate logging_specs[log_control.log_nentries]; 548*7c478bd9Sstevel@tonic-gate log_control.log_nentries++); 549*7c478bd9Sstevel@tonic-gate 550*7c478bd9Sstevel@tonic-gate /* 551*7c478bd9Sstevel@tonic-gate * Now allocate our structure. 552*7c478bd9Sstevel@tonic-gate */ 553*7c478bd9Sstevel@tonic-gate log_control.log_entries = (struct log_entry *) 554*7c478bd9Sstevel@tonic-gate malloc(log_control.log_nentries * sizeof(struct log_entry)); 555*7c478bd9Sstevel@tonic-gate if (log_control.log_entries) { 556*7c478bd9Sstevel@tonic-gate /* 557*7c478bd9Sstevel@tonic-gate * Scan through the list. 558*7c478bd9Sstevel@tonic-gate */ 559*7c478bd9Sstevel@tonic-gate for (i=0; i<log_control.log_nentries; i++) { 560*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].log_type = K_LOG_NONE; 561*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].log_2free = logging_specs[i]; 562*7c478bd9Sstevel@tonic-gate /* 563*7c478bd9Sstevel@tonic-gate * The format is: 564*7c478bd9Sstevel@tonic-gate * <whitespace><data><whitespace> 565*7c478bd9Sstevel@tonic-gate * so, trim off the leading and trailing whitespace here. 566*7c478bd9Sstevel@tonic-gate */ 567*7c478bd9Sstevel@tonic-gate for (cp = logging_specs[i]; isspace(*cp); cp++); 568*7c478bd9Sstevel@tonic-gate for (cp2 = &logging_specs[i][strlen(logging_specs[i])-1]; 569*7c478bd9Sstevel@tonic-gate isspace(*cp2); cp2--); 570*7c478bd9Sstevel@tonic-gate cp2++; 571*7c478bd9Sstevel@tonic-gate *cp2 = '\0'; 572*7c478bd9Sstevel@tonic-gate /* 573*7c478bd9Sstevel@tonic-gate * Is this a file? 574*7c478bd9Sstevel@tonic-gate */ 575*7c478bd9Sstevel@tonic-gate if (!strncasecmp(cp, "FILE", 4)) { 576*7c478bd9Sstevel@tonic-gate /* 577*7c478bd9Sstevel@tonic-gate * Check for append/overwrite, then open the file. 578*7c478bd9Sstevel@tonic-gate */ 579*7c478bd9Sstevel@tonic-gate if (cp[4] == ':' || cp[4] == '=') { 580*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lfu_fopen_mode = 581*7c478bd9Sstevel@tonic-gate (cp[4] == ':') ? "a+" : "w"; 582*7c478bd9Sstevel@tonic-gate f = fopen(&cp[5], 583*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lfu_fopen_mode); 584*7c478bd9Sstevel@tonic-gate if (f) { 585*7c478bd9Sstevel@tonic-gate char rotate_kw[128]; 586*7c478bd9Sstevel@tonic-gate /* Set the permissions to 644 */ 587*7c478bd9Sstevel@tonic-gate if (fchmod(fileno(f), 588*7c478bd9Sstevel@tonic-gate S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) == -1) { 589*7c478bd9Sstevel@tonic-gate fprintf(stderr,gettext("Couldn't set permissions for log file %s: %s\n"), 590*7c478bd9Sstevel@tonic-gate &cp[5], error_message(errno)); 591*7c478bd9Sstevel@tonic-gate } 592*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lfu_filep = f; 593*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].log_type = K_LOG_FILE; 594*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lfu_fname = &cp[5]; 595*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lfu_rotate_period = 596*7c478bd9Sstevel@tonic-gate K_LOG_DEF_FILE_ROTATE_PERIOD; 597*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lfu_rotate_versions = 598*7c478bd9Sstevel@tonic-gate K_LOG_DEF_FILE_ROTATE_VERSIONS; 599*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lfu_last_rotated = 600*7c478bd9Sstevel@tonic-gate time(0); 601*7c478bd9Sstevel@tonic-gate 602*7c478bd9Sstevel@tonic-gate /* 603*7c478bd9Sstevel@tonic-gate * Now parse for ename_"rotate" = { 604*7c478bd9Sstevel@tonic-gate * period = XXX 605*7c478bd9Sstevel@tonic-gate * versions = 10 606*7c478bd9Sstevel@tonic-gate * } 607*7c478bd9Sstevel@tonic-gate */ 608*7c478bd9Sstevel@tonic-gate if (strlen(ename) + strlen("_rotate") < 609*7c478bd9Sstevel@tonic-gate sizeof (rotate_kw)) { 610*7c478bd9Sstevel@tonic-gate 611*7c478bd9Sstevel@tonic-gate char *time; 612*7c478bd9Sstevel@tonic-gate krb5_deltat dt; 613*7c478bd9Sstevel@tonic-gate int vers; 614*7c478bd9Sstevel@tonic-gate 615*7c478bd9Sstevel@tonic-gate strcpy(rotate_kw, ename); 616*7c478bd9Sstevel@tonic-gate strcat(rotate_kw, "_rotate"); 617*7c478bd9Sstevel@tonic-gate 618*7c478bd9Sstevel@tonic-gate if (!profile_get_string(kcontext->profile, 619*7c478bd9Sstevel@tonic-gate "logging", rotate_kw, "period", 620*7c478bd9Sstevel@tonic-gate NULL, &time)) { 621*7c478bd9Sstevel@tonic-gate 622*7c478bd9Sstevel@tonic-gate if (time != NULL) { 623*7c478bd9Sstevel@tonic-gate if (!krb5_string_to_deltat(time, 624*7c478bd9Sstevel@tonic-gate &dt)) { 625*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lfu_rotate_period = 626*7c478bd9Sstevel@tonic-gate (time_t) dt; 627*7c478bd9Sstevel@tonic-gate } 628*7c478bd9Sstevel@tonic-gate free(time); 629*7c478bd9Sstevel@tonic-gate } 630*7c478bd9Sstevel@tonic-gate } 631*7c478bd9Sstevel@tonic-gate 632*7c478bd9Sstevel@tonic-gate if (!profile_get_integer( 633*7c478bd9Sstevel@tonic-gate kcontext->profile, "logging", 634*7c478bd9Sstevel@tonic-gate rotate_kw, "versions", 635*7c478bd9Sstevel@tonic-gate K_LOG_DEF_FILE_ROTATE_VERSIONS, 636*7c478bd9Sstevel@tonic-gate &vers)) { 637*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lfu_rotate_versions = vers; 638*7c478bd9Sstevel@tonic-gate } 639*7c478bd9Sstevel@tonic-gate 640*7c478bd9Sstevel@tonic-gate } 641*7c478bd9Sstevel@tonic-gate } else { 642*7c478bd9Sstevel@tonic-gate fprintf(stderr,gettext("Couldn't open log file %s: %s\n"), 643*7c478bd9Sstevel@tonic-gate &cp[5], error_message(errno)); 644*7c478bd9Sstevel@tonic-gate continue; 645*7c478bd9Sstevel@tonic-gate } 646*7c478bd9Sstevel@tonic-gate } 647*7c478bd9Sstevel@tonic-gate } 648*7c478bd9Sstevel@tonic-gate /* 649*7c478bd9Sstevel@tonic-gate * Is this a syslog? 650*7c478bd9Sstevel@tonic-gate */ 651*7c478bd9Sstevel@tonic-gate else if (!strncasecmp(cp, "SYSLOG", 6)) { 652*7c478bd9Sstevel@tonic-gate error = 0; 653*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_facility = LOG_AUTH; 654*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_severity = LOG_ERR; 655*7c478bd9Sstevel@tonic-gate /* 656*7c478bd9Sstevel@tonic-gate * Is there a severify specified? 657*7c478bd9Sstevel@tonic-gate */ 658*7c478bd9Sstevel@tonic-gate if (cp[6] == ':') { 659*7c478bd9Sstevel@tonic-gate /* 660*7c478bd9Sstevel@tonic-gate * Find the end of the severity. 661*7c478bd9Sstevel@tonic-gate */ 662*7c478bd9Sstevel@tonic-gate if (cp2 = strchr(&cp[7], ':')) { 663*7c478bd9Sstevel@tonic-gate savec = *cp2; 664*7c478bd9Sstevel@tonic-gate *cp2 = '\0'; 665*7c478bd9Sstevel@tonic-gate cp2++; 666*7c478bd9Sstevel@tonic-gate } 667*7c478bd9Sstevel@tonic-gate 668*7c478bd9Sstevel@tonic-gate /* 669*7c478bd9Sstevel@tonic-gate * Match a severity. 670*7c478bd9Sstevel@tonic-gate */ 671*7c478bd9Sstevel@tonic-gate if (!strcasecmp(&cp[7], "ERR")) { 672*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_severity = LOG_ERR; 673*7c478bd9Sstevel@tonic-gate } 674*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(&cp[7], "EMERG")) { 675*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_severity = 676*7c478bd9Sstevel@tonic-gate LOG_EMERG; 677*7c478bd9Sstevel@tonic-gate } 678*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(&cp[7], "ALERT")) { 679*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_severity = 680*7c478bd9Sstevel@tonic-gate LOG_ALERT; 681*7c478bd9Sstevel@tonic-gate } 682*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(&cp[7], "CRIT")) { 683*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_severity = LOG_CRIT; 684*7c478bd9Sstevel@tonic-gate } 685*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(&cp[7], "WARNING")) { 686*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_severity = 687*7c478bd9Sstevel@tonic-gate LOG_WARNING; 688*7c478bd9Sstevel@tonic-gate } 689*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(&cp[7], "NOTICE")) { 690*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_severity = 691*7c478bd9Sstevel@tonic-gate LOG_NOTICE; 692*7c478bd9Sstevel@tonic-gate } 693*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(&cp[7], "INFO")) { 694*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_severity = LOG_INFO; 695*7c478bd9Sstevel@tonic-gate } 696*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(&cp[7], "DEBUG")) { 697*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_severity = 698*7c478bd9Sstevel@tonic-gate LOG_DEBUG; 699*7c478bd9Sstevel@tonic-gate } 700*7c478bd9Sstevel@tonic-gate else 701*7c478bd9Sstevel@tonic-gate error = 1; 702*7c478bd9Sstevel@tonic-gate 703*7c478bd9Sstevel@tonic-gate /* 704*7c478bd9Sstevel@tonic-gate * If there is a facility present, then parse that. 705*7c478bd9Sstevel@tonic-gate */ 706*7c478bd9Sstevel@tonic-gate if (cp2) { 707*7c478bd9Sstevel@tonic-gate if (!strcasecmp(cp2, "AUTH")) { 708*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_facility = LOG_AUTH; 709*7c478bd9Sstevel@tonic-gate } 710*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(cp2, "KERN")) { 711*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_facility = LOG_KERN; 712*7c478bd9Sstevel@tonic-gate } 713*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(cp2, "USER")) { 714*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_facility = LOG_USER; 715*7c478bd9Sstevel@tonic-gate } 716*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(cp2, "MAIL")) { 717*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_facility = LOG_MAIL; 718*7c478bd9Sstevel@tonic-gate } 719*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(cp2, "DAEMON")) { 720*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_facility = LOG_DAEMON; 721*7c478bd9Sstevel@tonic-gate } 722*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(cp2, "LPR")) { 723*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_facility = LOG_LPR; 724*7c478bd9Sstevel@tonic-gate } 725*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(cp2, "NEWS")) { 726*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_facility = LOG_NEWS; 727*7c478bd9Sstevel@tonic-gate } 728*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(cp2, "UUCP")) { 729*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_facility = LOG_UUCP; 730*7c478bd9Sstevel@tonic-gate } 731*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(cp2, "CRON")) { 732*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_facility = LOG_CRON; 733*7c478bd9Sstevel@tonic-gate } 734*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(cp2, "AUDIT")) { 735*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_facility = LOG_AUDIT; 736*7c478bd9Sstevel@tonic-gate } 737*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(cp2, "LOCAL0")) { 738*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_facility = LOG_LOCAL0; 739*7c478bd9Sstevel@tonic-gate } 740*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(cp2, "LOCAL1")) { 741*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_facility = LOG_LOCAL1; 742*7c478bd9Sstevel@tonic-gate } 743*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(cp2, "LOCAL2")) { 744*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_facility = LOG_LOCAL2; 745*7c478bd9Sstevel@tonic-gate } 746*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(cp2, "LOCAL3")) { 747*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_facility = LOG_LOCAL3; 748*7c478bd9Sstevel@tonic-gate } 749*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(cp2, "LOCAL4")) { 750*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_facility = LOG_LOCAL4; 751*7c478bd9Sstevel@tonic-gate } 752*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(cp2, "LOCAL5")) { 753*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_facility = LOG_LOCAL5; 754*7c478bd9Sstevel@tonic-gate } 755*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(cp2, "LOCAL6")) { 756*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_facility = LOG_LOCAL6; 757*7c478bd9Sstevel@tonic-gate } 758*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(cp2, "LOCAL7")) { 759*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lsu_facility = LOG_LOCAL7; 760*7c478bd9Sstevel@tonic-gate } 761*7c478bd9Sstevel@tonic-gate cp2--; 762*7c478bd9Sstevel@tonic-gate *cp2 = savec; 763*7c478bd9Sstevel@tonic-gate } 764*7c478bd9Sstevel@tonic-gate } 765*7c478bd9Sstevel@tonic-gate if (!error) { 766*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].log_type = K_LOG_SYSLOG; 767*7c478bd9Sstevel@tonic-gate do_openlog = 1; 768*7c478bd9Sstevel@tonic-gate log_facility = log_control.log_entries[i].lsu_facility; 769*7c478bd9Sstevel@tonic-gate } 770*7c478bd9Sstevel@tonic-gate } 771*7c478bd9Sstevel@tonic-gate /* 772*7c478bd9Sstevel@tonic-gate * Is this a standard error specification? 773*7c478bd9Sstevel@tonic-gate */ 774*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(cp, "STDERR")) { 775*7c478bd9Sstevel@tonic-gate if (log_control.log_entries[i].lfu_filep = 776*7c478bd9Sstevel@tonic-gate fdopen(fileno(stderr), "a+")) { 777*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].log_type = K_LOG_STDERR; 778*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].lfu_fname = 779*7c478bd9Sstevel@tonic-gate "standard error"; 780*7c478bd9Sstevel@tonic-gate } 781*7c478bd9Sstevel@tonic-gate } 782*7c478bd9Sstevel@tonic-gate /* 783*7c478bd9Sstevel@tonic-gate * Is this a specification of the console? 784*7c478bd9Sstevel@tonic-gate */ 785*7c478bd9Sstevel@tonic-gate else if (!strcasecmp(cp, "CONSOLE")) { 786*7c478bd9Sstevel@tonic-gate if (log_control.log_entries[i].ldu_filep = 787*7c478bd9Sstevel@tonic-gate CONSOLE_OPEN("a+")) { 788*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].log_type = K_LOG_CONSOLE; 789*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].ldu_devname = "console"; 790*7c478bd9Sstevel@tonic-gate } 791*7c478bd9Sstevel@tonic-gate } 792*7c478bd9Sstevel@tonic-gate /* 793*7c478bd9Sstevel@tonic-gate * Is this a specification of a device? 794*7c478bd9Sstevel@tonic-gate */ 795*7c478bd9Sstevel@tonic-gate else if (!strncasecmp(cp, "DEVICE", 6)) { 796*7c478bd9Sstevel@tonic-gate /* 797*7c478bd9Sstevel@tonic-gate * We handle devices very similarly to files. 798*7c478bd9Sstevel@tonic-gate */ 799*7c478bd9Sstevel@tonic-gate if (cp[6] == '=') { 800*7c478bd9Sstevel@tonic-gate if (log_control.log_entries[i].ldu_filep = 801*7c478bd9Sstevel@tonic-gate DEVICE_OPEN(&cp[7], "w")) { 802*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].log_type = K_LOG_DEVICE; 803*7c478bd9Sstevel@tonic-gate log_control.log_entries[i].ldu_devname = &cp[7]; 804*7c478bd9Sstevel@tonic-gate } 805*7c478bd9Sstevel@tonic-gate } 806*7c478bd9Sstevel@tonic-gate } 807*7c478bd9Sstevel@tonic-gate /* 808*7c478bd9Sstevel@tonic-gate * See if we successfully parsed this specification. 809*7c478bd9Sstevel@tonic-gate */ 810*7c478bd9Sstevel@tonic-gate if (log_control.log_entries[i].log_type == K_LOG_NONE) { 811*7c478bd9Sstevel@tonic-gate fprintf(stderr, krb5_log_error_table(LSPEC_PARSE_ERR_1), whoami, cp); 812*7c478bd9Sstevel@tonic-gate fprintf(stderr, krb5_log_error_table(LSPEC_PARSE_ERR_2), whoami); 813*7c478bd9Sstevel@tonic-gate } 814*7c478bd9Sstevel@tonic-gate else 815*7c478bd9Sstevel@tonic-gate ngood++; 816*7c478bd9Sstevel@tonic-gate } 817*7c478bd9Sstevel@tonic-gate } 818*7c478bd9Sstevel@tonic-gate /* 819*7c478bd9Sstevel@tonic-gate * If we didn't find anything, then free our lists. 820*7c478bd9Sstevel@tonic-gate */ 821*7c478bd9Sstevel@tonic-gate if (ngood == 0) { 822*7c478bd9Sstevel@tonic-gate for (i=0; i<log_control.log_nentries; i++) 823*7c478bd9Sstevel@tonic-gate free(logging_specs[i]); 824*7c478bd9Sstevel@tonic-gate } 825*7c478bd9Sstevel@tonic-gate free(logging_specs); 826*7c478bd9Sstevel@tonic-gate } 827*7c478bd9Sstevel@tonic-gate /* 828*7c478bd9Sstevel@tonic-gate * If we didn't find anything, go for the default which is to log to 829*7c478bd9Sstevel@tonic-gate * the system log. 830*7c478bd9Sstevel@tonic-gate */ 831*7c478bd9Sstevel@tonic-gate if (ngood == 0) { 832*7c478bd9Sstevel@tonic-gate if (log_control.log_entries) 833*7c478bd9Sstevel@tonic-gate free(log_control.log_entries); 834*7c478bd9Sstevel@tonic-gate log_control.log_entries = &def_log_entry; 835*7c478bd9Sstevel@tonic-gate log_control.log_entries->log_type = K_LOG_SYSLOG; 836*7c478bd9Sstevel@tonic-gate log_control.log_entries->log_2free = (krb5_pointer) NULL; 837*7c478bd9Sstevel@tonic-gate log_facility = log_control.log_entries->lsu_facility = LOG_AUTH; 838*7c478bd9Sstevel@tonic-gate log_control.log_entries->lsu_severity = LOG_ERR; 839*7c478bd9Sstevel@tonic-gate do_openlog = 1; 840*7c478bd9Sstevel@tonic-gate log_control.log_nentries = 1; 841*7c478bd9Sstevel@tonic-gate } 842*7c478bd9Sstevel@tonic-gate if (log_control.log_nentries) { 843*7c478bd9Sstevel@tonic-gate if (log_control.log_whoami = (char *) malloc(strlen(whoami)+1)) 844*7c478bd9Sstevel@tonic-gate strcpy(log_control.log_whoami, whoami); 845*7c478bd9Sstevel@tonic-gate if (log_control.log_hostname = (char *) malloc(MAXHOSTNAMELEN)) 846*7c478bd9Sstevel@tonic-gate gethostname(log_control.log_hostname, MAXHOSTNAMELEN); 847*7c478bd9Sstevel@tonic-gate if (do_openlog) { 848*7c478bd9Sstevel@tonic-gate openlog(whoami, LOG_NDELAY|LOG_PID, log_facility); 849*7c478bd9Sstevel@tonic-gate log_control.log_opened = 1; 850*7c478bd9Sstevel@tonic-gate } 851*7c478bd9Sstevel@tonic-gate if (do_com_err) 852*7c478bd9Sstevel@tonic-gate (void) set_com_err_hook(klog_com_err_proc); 853*7c478bd9Sstevel@tonic-gate } 854*7c478bd9Sstevel@tonic-gate return((log_control.log_nentries) ? 0 : ENOENT); 855*7c478bd9Sstevel@tonic-gate } 856*7c478bd9Sstevel@tonic-gate 857*7c478bd9Sstevel@tonic-gate /* 858*7c478bd9Sstevel@tonic-gate * krb5_klog_close() - Close the logging context and free all data. 859*7c478bd9Sstevel@tonic-gate */ 860*7c478bd9Sstevel@tonic-gate void 861*7c478bd9Sstevel@tonic-gate krb5_klog_close(kcontext) 862*7c478bd9Sstevel@tonic-gate krb5_context kcontext; 863*7c478bd9Sstevel@tonic-gate { 864*7c478bd9Sstevel@tonic-gate int lindex; 865*7c478bd9Sstevel@tonic-gate (void) reset_com_err_hook(); 866*7c478bd9Sstevel@tonic-gate for (lindex = 0; lindex < log_control.log_nentries; lindex++) { 867*7c478bd9Sstevel@tonic-gate switch (log_control.log_entries[lindex].log_type) { 868*7c478bd9Sstevel@tonic-gate case K_LOG_FILE: 869*7c478bd9Sstevel@tonic-gate case K_LOG_STDERR: 870*7c478bd9Sstevel@tonic-gate /* 871*7c478bd9Sstevel@tonic-gate * Files/standard error. 872*7c478bd9Sstevel@tonic-gate */ 873*7c478bd9Sstevel@tonic-gate fclose(log_control.log_entries[lindex].lfu_filep); 874*7c478bd9Sstevel@tonic-gate break; 875*7c478bd9Sstevel@tonic-gate case K_LOG_CONSOLE: 876*7c478bd9Sstevel@tonic-gate case K_LOG_DEVICE: 877*7c478bd9Sstevel@tonic-gate /* 878*7c478bd9Sstevel@tonic-gate * Devices (may need special handling) 879*7c478bd9Sstevel@tonic-gate */ 880*7c478bd9Sstevel@tonic-gate DEVICE_CLOSE(log_control.log_entries[lindex].ldu_filep); 881*7c478bd9Sstevel@tonic-gate break; 882*7c478bd9Sstevel@tonic-gate case K_LOG_SYSLOG: 883*7c478bd9Sstevel@tonic-gate /* 884*7c478bd9Sstevel@tonic-gate * System log. 885*7c478bd9Sstevel@tonic-gate */ 886*7c478bd9Sstevel@tonic-gate break; 887*7c478bd9Sstevel@tonic-gate default: 888*7c478bd9Sstevel@tonic-gate break; 889*7c478bd9Sstevel@tonic-gate } 890*7c478bd9Sstevel@tonic-gate if (log_control.log_entries[lindex].log_2free) 891*7c478bd9Sstevel@tonic-gate free(log_control.log_entries[lindex].log_2free); 892*7c478bd9Sstevel@tonic-gate } 893*7c478bd9Sstevel@tonic-gate if (log_control.log_entries != &def_log_entry) 894*7c478bd9Sstevel@tonic-gate free(log_control.log_entries); 895*7c478bd9Sstevel@tonic-gate log_control.log_entries = (struct log_entry *) NULL; 896*7c478bd9Sstevel@tonic-gate log_control.log_nentries = 0; 897*7c478bd9Sstevel@tonic-gate if (log_control.log_whoami) 898*7c478bd9Sstevel@tonic-gate free(log_control.log_whoami); 899*7c478bd9Sstevel@tonic-gate log_control.log_whoami = (char *) NULL; 900*7c478bd9Sstevel@tonic-gate if (log_control.log_hostname) 901*7c478bd9Sstevel@tonic-gate free(log_control.log_hostname); 902*7c478bd9Sstevel@tonic-gate log_control.log_hostname = (char *) NULL; 903*7c478bd9Sstevel@tonic-gate if (log_control.log_opened) 904*7c478bd9Sstevel@tonic-gate closelog(); 905*7c478bd9Sstevel@tonic-gate } 906*7c478bd9Sstevel@tonic-gate 907*7c478bd9Sstevel@tonic-gate /* 908*7c478bd9Sstevel@tonic-gate * severity2string() - Convert a severity to a string. 909*7c478bd9Sstevel@tonic-gate */ 910*7c478bd9Sstevel@tonic-gate static char * 911*7c478bd9Sstevel@tonic-gate severity2string(severity) 912*7c478bd9Sstevel@tonic-gate int severity; 913*7c478bd9Sstevel@tonic-gate { 914*7c478bd9Sstevel@tonic-gate int s; 915*7c478bd9Sstevel@tonic-gate const char *ss; 916*7c478bd9Sstevel@tonic-gate 917*7c478bd9Sstevel@tonic-gate s = severity & LOG_PRIMASK; 918*7c478bd9Sstevel@tonic-gate ss = krb5_log_error_table(LOG_UFO_STRING); 919*7c478bd9Sstevel@tonic-gate switch (s) { 920*7c478bd9Sstevel@tonic-gate case LOG_EMERG: 921*7c478bd9Sstevel@tonic-gate ss = krb5_log_error_table(LOG_EMERG_STRING); 922*7c478bd9Sstevel@tonic-gate break; 923*7c478bd9Sstevel@tonic-gate case LOG_ALERT: 924*7c478bd9Sstevel@tonic-gate ss = krb5_log_error_table(LOG_ALERT_STRING); 925*7c478bd9Sstevel@tonic-gate break; 926*7c478bd9Sstevel@tonic-gate case LOG_CRIT: 927*7c478bd9Sstevel@tonic-gate ss = krb5_log_error_table(LOG_CRIT_STRING); 928*7c478bd9Sstevel@tonic-gate break; 929*7c478bd9Sstevel@tonic-gate case LOG_ERR: 930*7c478bd9Sstevel@tonic-gate ss = krb5_log_error_table(LOG_ERR_STRING); 931*7c478bd9Sstevel@tonic-gate break; 932*7c478bd9Sstevel@tonic-gate case LOG_WARNING: 933*7c478bd9Sstevel@tonic-gate ss = krb5_log_error_table(LOG_WARNING_STRING); 934*7c478bd9Sstevel@tonic-gate break; 935*7c478bd9Sstevel@tonic-gate case LOG_NOTICE: 936*7c478bd9Sstevel@tonic-gate ss = krb5_log_error_table(LOG_NOTICE_STRING); 937*7c478bd9Sstevel@tonic-gate break; 938*7c478bd9Sstevel@tonic-gate case LOG_INFO: 939*7c478bd9Sstevel@tonic-gate ss = krb5_log_error_table(LOG_INFO_STRING); 940*7c478bd9Sstevel@tonic-gate break; 941*7c478bd9Sstevel@tonic-gate case LOG_DEBUG: 942*7c478bd9Sstevel@tonic-gate ss = krb5_log_error_table(LOG_DEBUG_STRING); 943*7c478bd9Sstevel@tonic-gate break; 944*7c478bd9Sstevel@tonic-gate } 945*7c478bd9Sstevel@tonic-gate return((char *) ss); 946*7c478bd9Sstevel@tonic-gate } 947*7c478bd9Sstevel@tonic-gate 948*7c478bd9Sstevel@tonic-gate /* 949*7c478bd9Sstevel@tonic-gate * krb5_klog_syslog() - Simulate the calling sequence of syslog(3), while 950*7c478bd9Sstevel@tonic-gate * also performing the logging redirection as specified 951*7c478bd9Sstevel@tonic-gate * by krb5_klog_init(). 952*7c478bd9Sstevel@tonic-gate */ 953*7c478bd9Sstevel@tonic-gate static int 954*7c478bd9Sstevel@tonic-gate klog_vsyslog(priority, format, arglist) 955*7c478bd9Sstevel@tonic-gate int priority; 956*7c478bd9Sstevel@tonic-gate const char *format; 957*7c478bd9Sstevel@tonic-gate va_list arglist; 958*7c478bd9Sstevel@tonic-gate { 959*7c478bd9Sstevel@tonic-gate char outbuf[KRB5_KLOG_MAX_ERRMSG_SIZE]; 960*7c478bd9Sstevel@tonic-gate int lindex; 961*7c478bd9Sstevel@tonic-gate char *syslogp; 962*7c478bd9Sstevel@tonic-gate char *cp; 963*7c478bd9Sstevel@tonic-gate time_t now; 964*7c478bd9Sstevel@tonic-gate size_t soff; 965*7c478bd9Sstevel@tonic-gate 966*7c478bd9Sstevel@tonic-gate /* 967*7c478bd9Sstevel@tonic-gate * Format a syslog-esque message of the format: 968*7c478bd9Sstevel@tonic-gate * 969*7c478bd9Sstevel@tonic-gate * (verbose form) 970*7c478bd9Sstevel@tonic-gate * <date> <hostname> <id>[<pid>](<priority>): <message> 971*7c478bd9Sstevel@tonic-gate * 972*7c478bd9Sstevel@tonic-gate * (short form) 973*7c478bd9Sstevel@tonic-gate * <date> <message> 974*7c478bd9Sstevel@tonic-gate */ 975*7c478bd9Sstevel@tonic-gate cp = outbuf; 976*7c478bd9Sstevel@tonic-gate (void) time(&now); 977*7c478bd9Sstevel@tonic-gate /* 978*7c478bd9Sstevel@tonic-gate * Format the date: mon dd hh:mm:ss 979*7c478bd9Sstevel@tonic-gate */ 980*7c478bd9Sstevel@tonic-gate soff = strftime(outbuf, sizeof(outbuf), "%b %d %H:%M:%S", localtime(&now)); 981*7c478bd9Sstevel@tonic-gate if (soff > 0) 982*7c478bd9Sstevel@tonic-gate cp += soff; 983*7c478bd9Sstevel@tonic-gate else 984*7c478bd9Sstevel@tonic-gate return(-1); 985*7c478bd9Sstevel@tonic-gate #ifdef VERBOSE_LOGS 986*7c478bd9Sstevel@tonic-gate sprintf(cp, " %s %s[%d](%s): ", 987*7c478bd9Sstevel@tonic-gate log_control.log_hostname, log_control.log_whoami, getpid(), 988*7c478bd9Sstevel@tonic-gate severity2string(priority)); 989*7c478bd9Sstevel@tonic-gate #else 990*7c478bd9Sstevel@tonic-gate sprintf(cp, " "); 991*7c478bd9Sstevel@tonic-gate #endif 992*7c478bd9Sstevel@tonic-gate syslogp = &outbuf[strlen(outbuf)]; 993*7c478bd9Sstevel@tonic-gate 994*7c478bd9Sstevel@tonic-gate /* Now format the actual message */ 995*7c478bd9Sstevel@tonic-gate vsprintf(syslogp, format, arglist); 996*7c478bd9Sstevel@tonic-gate 997*7c478bd9Sstevel@tonic-gate /* 998*7c478bd9Sstevel@tonic-gate * Now that we have the message formatted, perform the output to each 999*7c478bd9Sstevel@tonic-gate * logging specification. 1000*7c478bd9Sstevel@tonic-gate */ 1001*7c478bd9Sstevel@tonic-gate for (lindex = 0; lindex < log_control.log_nentries; lindex++) { 1002*7c478bd9Sstevel@tonic-gate switch (log_control.log_entries[lindex].log_type) { 1003*7c478bd9Sstevel@tonic-gate case K_LOG_FILE: 1004*7c478bd9Sstevel@tonic-gate 1005*7c478bd9Sstevel@tonic-gate klog_rotate(&log_control.log_entries[lindex]); 1006*7c478bd9Sstevel@tonic-gate /*FALLTHRU*/ 1007*7c478bd9Sstevel@tonic-gate case K_LOG_STDERR: 1008*7c478bd9Sstevel@tonic-gate /* 1009*7c478bd9Sstevel@tonic-gate * Files/standard error. 1010*7c478bd9Sstevel@tonic-gate */ 1011*7c478bd9Sstevel@tonic-gate if (fprintf(log_control.log_entries[lindex].lfu_filep, 1012*7c478bd9Sstevel@tonic-gate outbuf) < 0) { 1013*7c478bd9Sstevel@tonic-gate /* Attempt to report error */ 1014*7c478bd9Sstevel@tonic-gate fprintf(stderr, krb5_log_error_table(LOG_FILE_ERR), 1015*7c478bd9Sstevel@tonic-gate log_control.log_entries[lindex].lfu_fname); 1016*7c478bd9Sstevel@tonic-gate } 1017*7c478bd9Sstevel@tonic-gate else { 1018*7c478bd9Sstevel@tonic-gate fprintf(log_control.log_entries[lindex].lfu_filep, "\n"); 1019*7c478bd9Sstevel@tonic-gate fflush(log_control.log_entries[lindex].lfu_filep); 1020*7c478bd9Sstevel@tonic-gate } 1021*7c478bd9Sstevel@tonic-gate break; 1022*7c478bd9Sstevel@tonic-gate case K_LOG_CONSOLE: 1023*7c478bd9Sstevel@tonic-gate case K_LOG_DEVICE: 1024*7c478bd9Sstevel@tonic-gate /* 1025*7c478bd9Sstevel@tonic-gate * Devices (may need special handling) 1026*7c478bd9Sstevel@tonic-gate */ 1027*7c478bd9Sstevel@tonic-gate if (DEVICE_PRINT(log_control.log_entries[lindex].ldu_filep, 1028*7c478bd9Sstevel@tonic-gate outbuf) < 0) { 1029*7c478bd9Sstevel@tonic-gate /* Attempt to report error */ 1030*7c478bd9Sstevel@tonic-gate fprintf(stderr, krb5_log_error_table(LOG_DEVICE_ERR), 1031*7c478bd9Sstevel@tonic-gate log_control.log_entries[lindex].ldu_devname); 1032*7c478bd9Sstevel@tonic-gate } 1033*7c478bd9Sstevel@tonic-gate break; 1034*7c478bd9Sstevel@tonic-gate case K_LOG_SYSLOG: 1035*7c478bd9Sstevel@tonic-gate /* 1036*7c478bd9Sstevel@tonic-gate * System log. 1037*7c478bd9Sstevel@tonic-gate */ 1038*7c478bd9Sstevel@tonic-gate 1039*7c478bd9Sstevel@tonic-gate /* Log the message with our header trimmed off */ 1040*7c478bd9Sstevel@tonic-gate syslog(priority, syslogp); 1041*7c478bd9Sstevel@tonic-gate break; 1042*7c478bd9Sstevel@tonic-gate default: 1043*7c478bd9Sstevel@tonic-gate break; 1044*7c478bd9Sstevel@tonic-gate } 1045*7c478bd9Sstevel@tonic-gate } 1046*7c478bd9Sstevel@tonic-gate return(0); 1047*7c478bd9Sstevel@tonic-gate } 1048*7c478bd9Sstevel@tonic-gate 1049*7c478bd9Sstevel@tonic-gate int 1050*7c478bd9Sstevel@tonic-gate krb5_klog_syslog(int priority, const char *format, ...) 1051*7c478bd9Sstevel@tonic-gate { 1052*7c478bd9Sstevel@tonic-gate int retval; 1053*7c478bd9Sstevel@tonic-gate va_list pvar; 1054*7c478bd9Sstevel@tonic-gate 1055*7c478bd9Sstevel@tonic-gate va_start(pvar, format); 1056*7c478bd9Sstevel@tonic-gate retval = klog_vsyslog(priority, format, pvar); 1057*7c478bd9Sstevel@tonic-gate va_end(pvar); 1058*7c478bd9Sstevel@tonic-gate return(retval); 1059*7c478bd9Sstevel@tonic-gate } 1060