Allow better control of destinations of logging (like passing explicit
destinations, and log-functions). git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@2772 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
157
lib/krb5/log.c
157
lib/krb5/log.c
@@ -43,8 +43,8 @@ RCSID("$Id$");
|
|||||||
struct facility {
|
struct facility {
|
||||||
int min;
|
int min;
|
||||||
int max;
|
int max;
|
||||||
void (*log)(struct facility *, const char *, const char *);
|
krb5_log_log_func_t log;
|
||||||
void (*close)(struct facility*);
|
krb5_log_close_func_t close;
|
||||||
void *data;
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -119,6 +119,42 @@ find_value(const char *s, struct s2i *table)
|
|||||||
return table->val;
|
return table->val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
krb5_error_code
|
||||||
|
krb5_initlog(krb5_context context,
|
||||||
|
const char *program,
|
||||||
|
krb5_log_facility **fac)
|
||||||
|
{
|
||||||
|
krb5_log_facility *f = calloc(1, sizeof(*f));
|
||||||
|
if(f == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
f->program = strdup(program);
|
||||||
|
if(f->program == NULL){
|
||||||
|
free(f);
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
*fac = f;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
krb5_error_code
|
||||||
|
krb5_addlog_func(krb5_context context,
|
||||||
|
krb5_log_facility *fac,
|
||||||
|
int min,
|
||||||
|
int max,
|
||||||
|
krb5_log_log_func_t log,
|
||||||
|
krb5_log_close_func_t close,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
struct facility *fp = log_realloc(fac);
|
||||||
|
if(fp == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
fp->min = min;
|
||||||
|
fp->max = max;
|
||||||
|
fp->log = log;
|
||||||
|
fp->close = close;
|
||||||
|
fp->data = data;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct syslog_data{
|
struct syslog_data{
|
||||||
@@ -126,28 +162,31 @@ struct syslog_data{
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
log_syslog(struct facility *fac,
|
log_syslog(const char *time,
|
||||||
const char *time,
|
const char *msg,
|
||||||
const char *msg)
|
void *data)
|
||||||
|
|
||||||
{
|
{
|
||||||
struct syslog_data *s = fac->data;
|
struct syslog_data *s = data;
|
||||||
syslog(s->priority, "%s", msg);
|
syslog(s->priority, "%s", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
close_syslog(struct facility *fac)
|
close_syslog(void *data)
|
||||||
{
|
{
|
||||||
free(fac->data);
|
free(data);
|
||||||
closelog();
|
closelog();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static krb5_error_code
|
||||||
open_syslog(const char *id, const char *sev, const char *fac,
|
open_syslog(krb5_context context, krb5_log_facility *facility, int min, int max,
|
||||||
struct facility *f)
|
const char *sev, const char *fac)
|
||||||
{
|
{
|
||||||
struct syslog_data *sd = malloc(sizeof(*sd));
|
struct syslog_data *sd = malloc(sizeof(*sd));
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if(sd == NULL)
|
||||||
|
return ENOMEM;
|
||||||
i = find_value(sev, syslogvals);
|
i = find_value(sev, syslogvals);
|
||||||
if(i == -1)
|
if(i == -1)
|
||||||
i = LOG_ERR;
|
i = LOG_ERR;
|
||||||
@@ -156,10 +195,8 @@ open_syslog(const char *id, const char *sev, const char *fac,
|
|||||||
if(i == -1)
|
if(i == -1)
|
||||||
i = LOG_AUTH;
|
i = LOG_AUTH;
|
||||||
sd->priority |= i;
|
sd->priority |= i;
|
||||||
openlog(id, LOG_PID | LOG_NDELAY, i);
|
openlog(facility->program, LOG_PID | LOG_NDELAY, i);
|
||||||
f->log = log_syslog;
|
return krb5_addlog_func(context, facility, min, max, log_syslog, close_syslog, sd);
|
||||||
f->close = close_syslog;
|
|
||||||
f->data = sd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct file_data{
|
struct file_data{
|
||||||
@@ -170,11 +207,11 @@ struct file_data{
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
log_file(struct facility *fac,
|
log_file(const char *time,
|
||||||
const char *time,
|
const char *msg,
|
||||||
const char *msg)
|
void *data)
|
||||||
{
|
{
|
||||||
struct file_data *f = fac->data;
|
struct file_data *f = data;
|
||||||
if(f->keep_open == 0)
|
if(f->keep_open == 0)
|
||||||
f->fd = fopen(f->filename, f->mode);
|
f->fd = fopen(f->filename, f->mode);
|
||||||
fprintf(f->fd, "%s %s\n", time, msg);
|
fprintf(f->fd, "%s %s\n", time, msg);
|
||||||
@@ -183,33 +220,35 @@ log_file(struct facility *fac,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
close_file(struct facility *fac)
|
close_file(void *data)
|
||||||
{
|
{
|
||||||
struct file_data *f = fac->data;
|
struct file_data *f = data;
|
||||||
if(f->keep_open && f->filename)
|
if(f->keep_open && f->filename)
|
||||||
fclose(f->fd);
|
fclose(f->fd);
|
||||||
free(fac->data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static krb5_error_code
|
||||||
open_file(struct facility *fac, char *filename, char *mode,
|
open_file(krb5_context context, krb5_log_facility *fac, int min, int max,
|
||||||
FILE *f, int keep_open)
|
char *filename, char *mode, FILE *f, int keep_open)
|
||||||
{
|
{
|
||||||
struct file_data *fd = malloc(sizeof(*fd));
|
struct file_data *fd = malloc(sizeof(*fd));
|
||||||
fac->log = log_file;
|
if(fd == NULL)
|
||||||
fac->close = close_file;
|
return ENOMEM;
|
||||||
fd->filename = filename;
|
fd->filename = filename;
|
||||||
fd->mode = mode;
|
fd->mode = mode;
|
||||||
fd->fd = f;
|
fd->fd = f;
|
||||||
fd->keep_open = keep_open;
|
fd->keep_open = keep_open;
|
||||||
fac->data = fd;
|
|
||||||
|
return krb5_addlog_func(context, fac, min, max, log_file, close_file, fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
openlog_int(krb5_context context, const char *program,
|
|
||||||
krb5_log_facility *f, const char *p)
|
krb5_error_code
|
||||||
|
krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *p)
|
||||||
{
|
{
|
||||||
struct facility *fp = NULL;
|
krb5_error_code ret = 0;
|
||||||
int min = 0, max = -1, n;
|
int min = 0, max = -1, n;
|
||||||
char c;
|
char c;
|
||||||
n = sscanf(p, "%d%c%d/", &min, &c, &max);
|
n = sscanf(p, "%d%c%d/", &min, &c, &max);
|
||||||
@@ -224,31 +263,35 @@ openlog_int(krb5_context context, const char *program,
|
|||||||
}
|
}
|
||||||
if(n){
|
if(n){
|
||||||
p = strchr(p, '/');
|
p = strchr(p, '/');
|
||||||
if(p == NULL) return 0;
|
if(p == NULL) return HEIM_ERR_LOG_PARSE;
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
if(strcmp(p, "STDERR") == 0){
|
if(strcmp(p, "STDERR") == 0){
|
||||||
fp = log_realloc(f);
|
ret = open_file(context, f, min, max, NULL, NULL, stderr, 1);
|
||||||
open_file(fp, NULL, NULL, stderr, 1);
|
|
||||||
}else if(strcmp(p, "CONSOLE") == 0){
|
}else if(strcmp(p, "CONSOLE") == 0){
|
||||||
fp = log_realloc(f);
|
ret = open_file(context, f, min, max, "/dev/console", "w", NULL, 0);
|
||||||
open_file(fp, "/dev/console", "w", NULL, 0);
|
|
||||||
}else if(strncmp(p, "FILE:", 4) == 0 && (p[4] == ':' || p[4] == '=')){
|
}else if(strncmp(p, "FILE:", 4) == 0 && (p[4] == ':' || p[4] == '=')){
|
||||||
char *fn;
|
char *fn;
|
||||||
FILE *file = NULL;
|
FILE *file = NULL;
|
||||||
int keep_open = 0;
|
int keep_open = 0;
|
||||||
fp = log_realloc(f);
|
|
||||||
fn = strdup(p + 5);
|
fn = strdup(p + 5);
|
||||||
|
if(fn == NULL)
|
||||||
|
return ENOMEM;
|
||||||
if(p[4] == '='){
|
if(p[4] == '='){
|
||||||
int i = open(fn, O_WRONLY | O_CREAT |
|
int i = open(fn, O_WRONLY | O_CREAT |
|
||||||
O_TRUNC | O_APPEND, 0666);
|
O_TRUNC | O_APPEND, 0666);
|
||||||
|
if(i < 0)
|
||||||
|
return errno;
|
||||||
file = fdopen(i, "a");
|
file = fdopen(i, "a");
|
||||||
|
if(file == NULL){
|
||||||
|
close(i);
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
keep_open = 1;
|
keep_open = 1;
|
||||||
}
|
}
|
||||||
open_file(fp, fn, "a", file, keep_open);
|
ret = open_file(context, f, min, max, fn, "a", file, keep_open);
|
||||||
}else if(strncmp(p, "DEVICE=", 6) == 0){
|
}else if(strncmp(p, "DEVICE=", 6) == 0){
|
||||||
fp = log_realloc(f);
|
ret = open_file(context, f, min, max, strdup(p + 7), "w", NULL, 0);
|
||||||
open_file(fp, strdup(p + 7), "w", NULL, 0);
|
|
||||||
}else if(strncmp(p, "SYSLOG", 6) == 0){
|
}else if(strncmp(p, "SYSLOG", 6) == 0){
|
||||||
char *severity;
|
char *severity;
|
||||||
char *facility;
|
char *facility;
|
||||||
@@ -258,30 +301,34 @@ openlog_int(krb5_context context, const char *program,
|
|||||||
facility = strchr(severity, ':');
|
facility = strchr(severity, ':');
|
||||||
if(facility == NULL)
|
if(facility == NULL)
|
||||||
facility = "AUTH";
|
facility = "AUTH";
|
||||||
fp = log_realloc(f);
|
ret = open_syslog(context, f, min, max, severity, facility);
|
||||||
open_syslog(program, severity, facility, fp);
|
}else{
|
||||||
|
ret = HEIM_ERR_LOG_PARSE; /* XXX */
|
||||||
}
|
}
|
||||||
if(fp){
|
return ret;
|
||||||
fp->min = min;
|
|
||||||
fp->max = max;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
krb5_error_code
|
krb5_error_code
|
||||||
krb5_openlog(krb5_context context,
|
krb5_openlog(krb5_context context,
|
||||||
const char *program,
|
const char *program,
|
||||||
krb5_log_facility **fac)
|
krb5_log_facility **fac)
|
||||||
{
|
{
|
||||||
|
krb5_error_code ret;
|
||||||
const char *p;
|
const char *p;
|
||||||
krb5_log_facility *f = calloc(1, sizeof(*f));
|
|
||||||
krb5_config_binding *binding = NULL;
|
krb5_config_binding *binding = NULL;
|
||||||
int done = 0;
|
int done = 0;
|
||||||
|
|
||||||
|
ret = krb5_initlog(context, program, fac);
|
||||||
|
if(ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
|
||||||
while(p = krb5_config_get_next(context->cf, &binding, STRING,
|
while(p = krb5_config_get_next(context->cf, &binding, STRING,
|
||||||
"logging",
|
"logging",
|
||||||
program,
|
program,
|
||||||
NULL)){
|
NULL)){
|
||||||
openlog_int(context, program, f, p);
|
ret = krb5_addlog_dest(context, *fac, p);
|
||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
if(!done){
|
if(!done){
|
||||||
@@ -289,13 +336,12 @@ krb5_openlog(krb5_context context,
|
|||||||
"logging",
|
"logging",
|
||||||
"default",
|
"default",
|
||||||
NULL)){
|
NULL)){
|
||||||
openlog_int(context, program, f, p);
|
ret = krb5_addlog_dest(context, *fac, p);
|
||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!done)
|
if(!done)
|
||||||
openlog_int(context, program, f, "SYSLOG");
|
ret = krb5_addlog_dest(context, *fac, "SYSLOG");
|
||||||
*fac = f;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,10 +351,11 @@ krb5_closelog(krb5_context context,
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < fac->len; i++)
|
for(i = 0; i < fac->len; i++)
|
||||||
(*fac->val[i].close)(&fac->val[i]);
|
(*fac->val[i].close)(&fac->val[i].data);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
krb5_error_code
|
krb5_error_code
|
||||||
krb5_vlog_msg(krb5_context context,
|
krb5_vlog_msg(krb5_context context,
|
||||||
krb5_log_facility *fac,
|
krb5_log_facility *fac,
|
||||||
@@ -328,7 +375,7 @@ krb5_vlog_msg(krb5_context context,
|
|||||||
for(i = 0; i < fac->len; i++)
|
for(i = 0; i < fac->len; i++)
|
||||||
if(fac->val[i].min <= level &&
|
if(fac->val[i].min <= level &&
|
||||||
(fac->val[i].max < 0 || fac->val[i].max >= level))
|
(fac->val[i].max < 0 || fac->val[i].max >= level))
|
||||||
(*fac->val[i].log)(&fac->val[i], buf, msg);
|
(*fac->val[i].log)(buf, msg, fac->val[i].data);
|
||||||
*reply = msg;
|
*reply = msg;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user