1*0a6a1f1dSLionel Sambuc /* $NetBSD: log.c,v 1.1.1.2 2014/04/24 12:45:50 pettai Exp $ */
2ebfedea0SLionel Sambuc
3ebfedea0SLionel Sambuc /*
4ebfedea0SLionel Sambuc * Copyright (c) 1997-2006 Kungliga Tekniska Högskolan
5ebfedea0SLionel Sambuc * (Royal Institute of Technology, Stockholm, Sweden).
6ebfedea0SLionel Sambuc * All rights reserved.
7ebfedea0SLionel Sambuc *
8ebfedea0SLionel Sambuc * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
9ebfedea0SLionel Sambuc *
10ebfedea0SLionel Sambuc * Redistribution and use in source and binary forms, with or without
11ebfedea0SLionel Sambuc * modification, are permitted provided that the following conditions
12ebfedea0SLionel Sambuc * are met:
13ebfedea0SLionel Sambuc *
14ebfedea0SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
15ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer.
16ebfedea0SLionel Sambuc *
17ebfedea0SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
18ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer in the
19ebfedea0SLionel Sambuc * documentation and/or other materials provided with the distribution.
20ebfedea0SLionel Sambuc *
21ebfedea0SLionel Sambuc * 3. Neither the name of the Institute nor the names of its contributors
22ebfedea0SLionel Sambuc * may be used to endorse or promote products derived from this software
23ebfedea0SLionel Sambuc * without specific prior written permission.
24ebfedea0SLionel Sambuc *
25ebfedea0SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
26ebfedea0SLionel Sambuc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27ebfedea0SLionel Sambuc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28ebfedea0SLionel Sambuc * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
29ebfedea0SLionel Sambuc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30ebfedea0SLionel Sambuc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31ebfedea0SLionel Sambuc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32ebfedea0SLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33ebfedea0SLionel Sambuc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34ebfedea0SLionel Sambuc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35ebfedea0SLionel Sambuc * SUCH DAMAGE.
36ebfedea0SLionel Sambuc */
37ebfedea0SLionel Sambuc
38ebfedea0SLionel Sambuc #include "krb5_locl.h"
39ebfedea0SLionel Sambuc #include <vis.h>
40ebfedea0SLionel Sambuc
41ebfedea0SLionel Sambuc struct facility {
42ebfedea0SLionel Sambuc int min;
43ebfedea0SLionel Sambuc int max;
44ebfedea0SLionel Sambuc krb5_log_log_func_t log_func;
45ebfedea0SLionel Sambuc krb5_log_close_func_t close_func;
46ebfedea0SLionel Sambuc void *data;
47ebfedea0SLionel Sambuc };
48ebfedea0SLionel Sambuc
49ebfedea0SLionel Sambuc static struct facility*
log_realloc(krb5_log_facility * f)50ebfedea0SLionel Sambuc log_realloc(krb5_log_facility *f)
51ebfedea0SLionel Sambuc {
52ebfedea0SLionel Sambuc struct facility *fp;
53ebfedea0SLionel Sambuc fp = realloc(f->val, (f->len + 1) * sizeof(*f->val));
54ebfedea0SLionel Sambuc if(fp == NULL)
55ebfedea0SLionel Sambuc return NULL;
56ebfedea0SLionel Sambuc f->len++;
57ebfedea0SLionel Sambuc f->val = fp;
58ebfedea0SLionel Sambuc fp += f->len - 1;
59ebfedea0SLionel Sambuc return fp;
60ebfedea0SLionel Sambuc }
61ebfedea0SLionel Sambuc
62ebfedea0SLionel Sambuc struct s2i {
63ebfedea0SLionel Sambuc const char *s;
64ebfedea0SLionel Sambuc int val;
65ebfedea0SLionel Sambuc };
66ebfedea0SLionel Sambuc
67ebfedea0SLionel Sambuc #define L(X) { #X, LOG_ ## X }
68ebfedea0SLionel Sambuc
69ebfedea0SLionel Sambuc static struct s2i syslogvals[] = {
70ebfedea0SLionel Sambuc L(EMERG),
71ebfedea0SLionel Sambuc L(ALERT),
72ebfedea0SLionel Sambuc L(CRIT),
73ebfedea0SLionel Sambuc L(ERR),
74ebfedea0SLionel Sambuc L(WARNING),
75ebfedea0SLionel Sambuc L(NOTICE),
76ebfedea0SLionel Sambuc L(INFO),
77ebfedea0SLionel Sambuc L(DEBUG),
78ebfedea0SLionel Sambuc
79ebfedea0SLionel Sambuc L(AUTH),
80ebfedea0SLionel Sambuc #ifdef LOG_AUTHPRIV
81ebfedea0SLionel Sambuc L(AUTHPRIV),
82ebfedea0SLionel Sambuc #endif
83ebfedea0SLionel Sambuc #ifdef LOG_CRON
84ebfedea0SLionel Sambuc L(CRON),
85ebfedea0SLionel Sambuc #endif
86ebfedea0SLionel Sambuc L(DAEMON),
87ebfedea0SLionel Sambuc #ifdef LOG_FTP
88ebfedea0SLionel Sambuc L(FTP),
89ebfedea0SLionel Sambuc #endif
90ebfedea0SLionel Sambuc L(KERN),
91ebfedea0SLionel Sambuc L(LPR),
92ebfedea0SLionel Sambuc L(MAIL),
93ebfedea0SLionel Sambuc #ifdef LOG_NEWS
94ebfedea0SLionel Sambuc L(NEWS),
95ebfedea0SLionel Sambuc #endif
96ebfedea0SLionel Sambuc L(SYSLOG),
97ebfedea0SLionel Sambuc L(USER),
98ebfedea0SLionel Sambuc #ifdef LOG_UUCP
99ebfedea0SLionel Sambuc L(UUCP),
100ebfedea0SLionel Sambuc #endif
101ebfedea0SLionel Sambuc L(LOCAL0),
102ebfedea0SLionel Sambuc L(LOCAL1),
103ebfedea0SLionel Sambuc L(LOCAL2),
104ebfedea0SLionel Sambuc L(LOCAL3),
105ebfedea0SLionel Sambuc L(LOCAL4),
106ebfedea0SLionel Sambuc L(LOCAL5),
107ebfedea0SLionel Sambuc L(LOCAL6),
108ebfedea0SLionel Sambuc L(LOCAL7),
109ebfedea0SLionel Sambuc { NULL, -1 }
110ebfedea0SLionel Sambuc };
111ebfedea0SLionel Sambuc
112ebfedea0SLionel Sambuc static int
find_value(const char * s,struct s2i * table)113ebfedea0SLionel Sambuc find_value(const char *s, struct s2i *table)
114ebfedea0SLionel Sambuc {
115ebfedea0SLionel Sambuc while(table->s && strcasecmp(table->s, s))
116ebfedea0SLionel Sambuc table++;
117ebfedea0SLionel Sambuc return table->val;
118ebfedea0SLionel Sambuc }
119ebfedea0SLionel Sambuc
120ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_initlog(krb5_context context,const char * program,krb5_log_facility ** fac)121ebfedea0SLionel Sambuc krb5_initlog(krb5_context context,
122ebfedea0SLionel Sambuc const char *program,
123ebfedea0SLionel Sambuc krb5_log_facility **fac)
124ebfedea0SLionel Sambuc {
125ebfedea0SLionel Sambuc krb5_log_facility *f = calloc(1, sizeof(*f));
126ebfedea0SLionel Sambuc if(f == NULL) {
127ebfedea0SLionel Sambuc krb5_set_error_message(context, ENOMEM,
128ebfedea0SLionel Sambuc N_("malloc: out of memory", ""));
129ebfedea0SLionel Sambuc return ENOMEM;
130ebfedea0SLionel Sambuc }
131ebfedea0SLionel Sambuc f->program = strdup(program);
132ebfedea0SLionel Sambuc if(f->program == NULL){
133ebfedea0SLionel Sambuc free(f);
134ebfedea0SLionel Sambuc krb5_set_error_message(context, ENOMEM,
135ebfedea0SLionel Sambuc N_("malloc: out of memory", ""));
136ebfedea0SLionel Sambuc return ENOMEM;
137ebfedea0SLionel Sambuc }
138ebfedea0SLionel Sambuc *fac = f;
139ebfedea0SLionel Sambuc return 0;
140ebfedea0SLionel Sambuc }
141ebfedea0SLionel Sambuc
142ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_addlog_func(krb5_context context,krb5_log_facility * fac,int min,int max,krb5_log_log_func_t log_func,krb5_log_close_func_t close_func,void * data)143ebfedea0SLionel Sambuc krb5_addlog_func(krb5_context context,
144ebfedea0SLionel Sambuc krb5_log_facility *fac,
145ebfedea0SLionel Sambuc int min,
146ebfedea0SLionel Sambuc int max,
147ebfedea0SLionel Sambuc krb5_log_log_func_t log_func,
148ebfedea0SLionel Sambuc krb5_log_close_func_t close_func,
149ebfedea0SLionel Sambuc void *data)
150ebfedea0SLionel Sambuc {
151ebfedea0SLionel Sambuc struct facility *fp = log_realloc(fac);
152ebfedea0SLionel Sambuc if(fp == NULL) {
153ebfedea0SLionel Sambuc krb5_set_error_message(context, ENOMEM,
154ebfedea0SLionel Sambuc N_("malloc: out of memory", ""));
155ebfedea0SLionel Sambuc return ENOMEM;
156ebfedea0SLionel Sambuc }
157ebfedea0SLionel Sambuc fp->min = min;
158ebfedea0SLionel Sambuc fp->max = max;
159ebfedea0SLionel Sambuc fp->log_func = log_func;
160ebfedea0SLionel Sambuc fp->close_func = close_func;
161ebfedea0SLionel Sambuc fp->data = data;
162ebfedea0SLionel Sambuc return 0;
163ebfedea0SLionel Sambuc }
164ebfedea0SLionel Sambuc
165ebfedea0SLionel Sambuc
166ebfedea0SLionel Sambuc struct _heimdal_syslog_data{
167ebfedea0SLionel Sambuc int priority;
168ebfedea0SLionel Sambuc };
169ebfedea0SLionel Sambuc
170ebfedea0SLionel Sambuc static void KRB5_CALLCONV
log_syslog(const char * timestr,const char * msg,void * data)171ebfedea0SLionel Sambuc log_syslog(const char *timestr,
172ebfedea0SLionel Sambuc const char *msg,
173ebfedea0SLionel Sambuc void *data)
174ebfedea0SLionel Sambuc
175ebfedea0SLionel Sambuc {
176ebfedea0SLionel Sambuc struct _heimdal_syslog_data *s = data;
177ebfedea0SLionel Sambuc syslog(s->priority, "%s", msg);
178ebfedea0SLionel Sambuc }
179ebfedea0SLionel Sambuc
180ebfedea0SLionel Sambuc static void KRB5_CALLCONV
close_syslog(void * data)181ebfedea0SLionel Sambuc close_syslog(void *data)
182ebfedea0SLionel Sambuc {
183ebfedea0SLionel Sambuc free(data);
184ebfedea0SLionel Sambuc closelog();
185ebfedea0SLionel Sambuc }
186ebfedea0SLionel Sambuc
187ebfedea0SLionel Sambuc static krb5_error_code
open_syslog(krb5_context context,krb5_log_facility * facility,int min,int max,const char * sev,const char * fac)188ebfedea0SLionel Sambuc open_syslog(krb5_context context,
189ebfedea0SLionel Sambuc krb5_log_facility *facility, int min, int max,
190ebfedea0SLionel Sambuc const char *sev, const char *fac)
191ebfedea0SLionel Sambuc {
192ebfedea0SLionel Sambuc struct _heimdal_syslog_data *sd = malloc(sizeof(*sd));
193ebfedea0SLionel Sambuc int i;
194ebfedea0SLionel Sambuc
195ebfedea0SLionel Sambuc if(sd == NULL) {
196ebfedea0SLionel Sambuc krb5_set_error_message(context, ENOMEM,
197ebfedea0SLionel Sambuc N_("malloc: out of memory", ""));
198ebfedea0SLionel Sambuc return ENOMEM;
199ebfedea0SLionel Sambuc }
200ebfedea0SLionel Sambuc i = find_value(sev, syslogvals);
201ebfedea0SLionel Sambuc if(i == -1)
202ebfedea0SLionel Sambuc i = LOG_ERR;
203ebfedea0SLionel Sambuc sd->priority = i;
204ebfedea0SLionel Sambuc i = find_value(fac, syslogvals);
205ebfedea0SLionel Sambuc if(i == -1)
206ebfedea0SLionel Sambuc i = LOG_AUTH;
207ebfedea0SLionel Sambuc sd->priority |= i;
208ebfedea0SLionel Sambuc roken_openlog(facility->program, LOG_PID | LOG_NDELAY, i);
209ebfedea0SLionel Sambuc return krb5_addlog_func(context, facility, min, max,
210ebfedea0SLionel Sambuc log_syslog, close_syslog, sd);
211ebfedea0SLionel Sambuc }
212ebfedea0SLionel Sambuc
213ebfedea0SLionel Sambuc struct file_data{
214ebfedea0SLionel Sambuc const char *filename;
215ebfedea0SLionel Sambuc const char *mode;
216ebfedea0SLionel Sambuc FILE *fd;
217ebfedea0SLionel Sambuc int keep_open;
218ebfedea0SLionel Sambuc };
219ebfedea0SLionel Sambuc
220ebfedea0SLionel Sambuc static void KRB5_CALLCONV
log_file(const char * timestr,const char * msg,void * data)221ebfedea0SLionel Sambuc log_file(const char *timestr,
222ebfedea0SLionel Sambuc const char *msg,
223ebfedea0SLionel Sambuc void *data)
224ebfedea0SLionel Sambuc {
225ebfedea0SLionel Sambuc struct file_data *f = data;
226ebfedea0SLionel Sambuc char *msgclean;
227ebfedea0SLionel Sambuc size_t len = strlen(msg);
228ebfedea0SLionel Sambuc if(f->keep_open == 0)
229ebfedea0SLionel Sambuc f->fd = fopen(f->filename, f->mode);
230ebfedea0SLionel Sambuc if(f->fd == NULL)
231ebfedea0SLionel Sambuc return;
232ebfedea0SLionel Sambuc /* make sure the log doesn't contain special chars */
233ebfedea0SLionel Sambuc msgclean = malloc((len + 1) * 4);
234ebfedea0SLionel Sambuc if (msgclean == NULL)
235ebfedea0SLionel Sambuc goto out;
236ebfedea0SLionel Sambuc strvisx(msgclean, rk_UNCONST(msg), len, VIS_OCTAL);
237ebfedea0SLionel Sambuc fprintf(f->fd, "%s %s\n", timestr, msgclean);
238ebfedea0SLionel Sambuc free(msgclean);
239ebfedea0SLionel Sambuc out:
240ebfedea0SLionel Sambuc if(f->keep_open == 0) {
241ebfedea0SLionel Sambuc fclose(f->fd);
242ebfedea0SLionel Sambuc f->fd = NULL;
243ebfedea0SLionel Sambuc }
244ebfedea0SLionel Sambuc }
245ebfedea0SLionel Sambuc
246ebfedea0SLionel Sambuc static void KRB5_CALLCONV
close_file(void * data)247ebfedea0SLionel Sambuc close_file(void *data)
248ebfedea0SLionel Sambuc {
249ebfedea0SLionel Sambuc struct file_data *f = data;
250ebfedea0SLionel Sambuc if(f->keep_open && f->filename)
251ebfedea0SLionel Sambuc fclose(f->fd);
252ebfedea0SLionel Sambuc free(data);
253ebfedea0SLionel Sambuc }
254ebfedea0SLionel Sambuc
255ebfedea0SLionel Sambuc static krb5_error_code
open_file(krb5_context context,krb5_log_facility * fac,int min,int max,const char * filename,const char * mode,FILE * f,int keep_open)256ebfedea0SLionel Sambuc open_file(krb5_context context, krb5_log_facility *fac, int min, int max,
257ebfedea0SLionel Sambuc const char *filename, const char *mode, FILE *f, int keep_open)
258ebfedea0SLionel Sambuc {
259ebfedea0SLionel Sambuc struct file_data *fd = malloc(sizeof(*fd));
260ebfedea0SLionel Sambuc if(fd == NULL) {
261ebfedea0SLionel Sambuc krb5_set_error_message(context, ENOMEM,
262ebfedea0SLionel Sambuc N_("malloc: out of memory", ""));
263ebfedea0SLionel Sambuc return ENOMEM;
264ebfedea0SLionel Sambuc }
265ebfedea0SLionel Sambuc fd->filename = filename;
266ebfedea0SLionel Sambuc fd->mode = mode;
267ebfedea0SLionel Sambuc fd->fd = f;
268ebfedea0SLionel Sambuc fd->keep_open = keep_open;
269ebfedea0SLionel Sambuc
270ebfedea0SLionel Sambuc return krb5_addlog_func(context, fac, min, max, log_file, close_file, fd);
271ebfedea0SLionel Sambuc }
272ebfedea0SLionel Sambuc
273ebfedea0SLionel Sambuc
274ebfedea0SLionel Sambuc
275ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_addlog_dest(krb5_context context,krb5_log_facility * f,const char * orig)276ebfedea0SLionel Sambuc krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *orig)
277ebfedea0SLionel Sambuc {
278ebfedea0SLionel Sambuc krb5_error_code ret = 0;
279ebfedea0SLionel Sambuc int min = 0, max = -1, n;
280ebfedea0SLionel Sambuc char c;
281ebfedea0SLionel Sambuc const char *p = orig;
282ebfedea0SLionel Sambuc
283ebfedea0SLionel Sambuc n = sscanf(p, "%d%c%d/", &min, &c, &max);
284ebfedea0SLionel Sambuc if(n == 2){
285ebfedea0SLionel Sambuc if(c == '/') {
286ebfedea0SLionel Sambuc if(min < 0){
287ebfedea0SLionel Sambuc max = -min;
288ebfedea0SLionel Sambuc min = 0;
289ebfedea0SLionel Sambuc }else{
290ebfedea0SLionel Sambuc max = min;
291ebfedea0SLionel Sambuc }
292ebfedea0SLionel Sambuc }
293ebfedea0SLionel Sambuc }
294ebfedea0SLionel Sambuc if(n){
295ebfedea0SLionel Sambuc p = strchr(p, '/');
296ebfedea0SLionel Sambuc if(p == NULL) {
297ebfedea0SLionel Sambuc krb5_set_error_message(context, HEIM_ERR_LOG_PARSE,
298ebfedea0SLionel Sambuc N_("failed to parse \"%s\"", ""), orig);
299ebfedea0SLionel Sambuc return HEIM_ERR_LOG_PARSE;
300ebfedea0SLionel Sambuc }
301ebfedea0SLionel Sambuc p++;
302ebfedea0SLionel Sambuc }
303ebfedea0SLionel Sambuc if(strcmp(p, "STDERR") == 0){
304ebfedea0SLionel Sambuc ret = open_file(context, f, min, max, NULL, NULL, stderr, 1);
305ebfedea0SLionel Sambuc }else if(strcmp(p, "CONSOLE") == 0){
306ebfedea0SLionel Sambuc ret = open_file(context, f, min, max, "/dev/console", "w", NULL, 0);
307ebfedea0SLionel Sambuc }else if(strncmp(p, "FILE", 4) == 0 && (p[4] == ':' || p[4] == '=')){
308ebfedea0SLionel Sambuc char *fn;
309ebfedea0SLionel Sambuc FILE *file = NULL;
310ebfedea0SLionel Sambuc int keep_open = 0;
311ebfedea0SLionel Sambuc fn = strdup(p + 5);
312ebfedea0SLionel Sambuc if(fn == NULL) {
313ebfedea0SLionel Sambuc krb5_set_error_message(context, ENOMEM,
314ebfedea0SLionel Sambuc N_("malloc: out of memory", ""));
315ebfedea0SLionel Sambuc return ENOMEM;
316ebfedea0SLionel Sambuc }
317ebfedea0SLionel Sambuc if(p[4] == '='){
318ebfedea0SLionel Sambuc int i = open(fn, O_WRONLY | O_CREAT |
319ebfedea0SLionel Sambuc O_TRUNC | O_APPEND, 0666);
320ebfedea0SLionel Sambuc if(i < 0) {
321ebfedea0SLionel Sambuc ret = errno;
322ebfedea0SLionel Sambuc krb5_set_error_message(context, ret,
323ebfedea0SLionel Sambuc N_("open(%s) logile: %s", ""), fn,
324ebfedea0SLionel Sambuc strerror(ret));
325ebfedea0SLionel Sambuc free(fn);
326ebfedea0SLionel Sambuc return ret;
327ebfedea0SLionel Sambuc }
328ebfedea0SLionel Sambuc rk_cloexec(i);
329ebfedea0SLionel Sambuc file = fdopen(i, "a");
330ebfedea0SLionel Sambuc if(file == NULL){
331ebfedea0SLionel Sambuc ret = errno;
332ebfedea0SLionel Sambuc close(i);
333ebfedea0SLionel Sambuc krb5_set_error_message(context, ret,
334ebfedea0SLionel Sambuc N_("fdopen(%s) logfile: %s", ""),
335ebfedea0SLionel Sambuc fn, strerror(ret));
336ebfedea0SLionel Sambuc free(fn);
337ebfedea0SLionel Sambuc return ret;
338ebfedea0SLionel Sambuc }
339ebfedea0SLionel Sambuc keep_open = 1;
340ebfedea0SLionel Sambuc }
341ebfedea0SLionel Sambuc ret = open_file(context, f, min, max, fn, "a", file, keep_open);
342ebfedea0SLionel Sambuc }else if(strncmp(p, "DEVICE", 6) == 0 && (p[6] == ':' || p[6] == '=')){
343ebfedea0SLionel Sambuc ret = open_file(context, f, min, max, strdup(p + 7), "w", NULL, 0);
344ebfedea0SLionel Sambuc }else if(strncmp(p, "SYSLOG", 6) == 0 && (p[6] == '\0' || p[6] == ':')){
345ebfedea0SLionel Sambuc char severity[128] = "";
346ebfedea0SLionel Sambuc char facility[128] = "";
347ebfedea0SLionel Sambuc p += 6;
348ebfedea0SLionel Sambuc if(*p != '\0')
349ebfedea0SLionel Sambuc p++;
350ebfedea0SLionel Sambuc if(strsep_copy(&p, ":", severity, sizeof(severity)) != -1)
351ebfedea0SLionel Sambuc strsep_copy(&p, ":", facility, sizeof(facility));
352ebfedea0SLionel Sambuc if(*severity == '\0')
353ebfedea0SLionel Sambuc strlcpy(severity, "ERR", sizeof(severity));
354ebfedea0SLionel Sambuc if(*facility == '\0')
355ebfedea0SLionel Sambuc strlcpy(facility, "AUTH", sizeof(facility));
356ebfedea0SLionel Sambuc ret = open_syslog(context, f, min, max, severity, facility);
357ebfedea0SLionel Sambuc }else{
358ebfedea0SLionel Sambuc ret = HEIM_ERR_LOG_PARSE; /* XXX */
359ebfedea0SLionel Sambuc krb5_set_error_message (context, ret,
360ebfedea0SLionel Sambuc N_("unknown log type: %s", ""), p);
361ebfedea0SLionel Sambuc }
362ebfedea0SLionel Sambuc return ret;
363ebfedea0SLionel Sambuc }
364ebfedea0SLionel Sambuc
365ebfedea0SLionel Sambuc
366ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_openlog(krb5_context context,const char * program,krb5_log_facility ** fac)367ebfedea0SLionel Sambuc krb5_openlog(krb5_context context,
368ebfedea0SLionel Sambuc const char *program,
369ebfedea0SLionel Sambuc krb5_log_facility **fac)
370ebfedea0SLionel Sambuc {
371ebfedea0SLionel Sambuc krb5_error_code ret;
372ebfedea0SLionel Sambuc char **p, **q;
373ebfedea0SLionel Sambuc
374ebfedea0SLionel Sambuc ret = krb5_initlog(context, program, fac);
375ebfedea0SLionel Sambuc if(ret)
376ebfedea0SLionel Sambuc return ret;
377ebfedea0SLionel Sambuc
378ebfedea0SLionel Sambuc p = krb5_config_get_strings(context, NULL, "logging", program, NULL);
379ebfedea0SLionel Sambuc if(p == NULL)
380ebfedea0SLionel Sambuc p = krb5_config_get_strings(context, NULL, "logging", "default", NULL);
381ebfedea0SLionel Sambuc if(p){
382ebfedea0SLionel Sambuc for(q = p; *q && ret == 0; q++)
383ebfedea0SLionel Sambuc ret = krb5_addlog_dest(context, *fac, *q);
384ebfedea0SLionel Sambuc krb5_config_free_strings(p);
385ebfedea0SLionel Sambuc }else
386ebfedea0SLionel Sambuc ret = krb5_addlog_dest(context, *fac, "SYSLOG");
387ebfedea0SLionel Sambuc return ret;
388ebfedea0SLionel Sambuc }
389ebfedea0SLionel Sambuc
390ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_closelog(krb5_context context,krb5_log_facility * fac)391ebfedea0SLionel Sambuc krb5_closelog(krb5_context context,
392ebfedea0SLionel Sambuc krb5_log_facility *fac)
393ebfedea0SLionel Sambuc {
394ebfedea0SLionel Sambuc int i;
395ebfedea0SLionel Sambuc for(i = 0; i < fac->len; i++)
396ebfedea0SLionel Sambuc (*fac->val[i].close_func)(fac->val[i].data);
397ebfedea0SLionel Sambuc free(fac->val);
398ebfedea0SLionel Sambuc free(fac->program);
399ebfedea0SLionel Sambuc fac->val = NULL;
400ebfedea0SLionel Sambuc fac->len = 0;
401ebfedea0SLionel Sambuc fac->program = NULL;
402ebfedea0SLionel Sambuc free(fac);
403ebfedea0SLionel Sambuc return 0;
404ebfedea0SLionel Sambuc }
405ebfedea0SLionel Sambuc
406ebfedea0SLionel Sambuc #undef __attribute__
407ebfedea0SLionel Sambuc #define __attribute__(X)
408ebfedea0SLionel Sambuc
409ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_vlog_msg(krb5_context context,krb5_log_facility * fac,char ** reply,int level,const char * fmt,va_list ap)410ebfedea0SLionel Sambuc krb5_vlog_msg(krb5_context context,
411ebfedea0SLionel Sambuc krb5_log_facility *fac,
412ebfedea0SLionel Sambuc char **reply,
413ebfedea0SLionel Sambuc int level,
414ebfedea0SLionel Sambuc const char *fmt,
415ebfedea0SLionel Sambuc va_list ap)
416ebfedea0SLionel Sambuc __attribute__((format (printf, 5, 0)))
417ebfedea0SLionel Sambuc {
418ebfedea0SLionel Sambuc
419ebfedea0SLionel Sambuc char *msg = NULL;
420ebfedea0SLionel Sambuc const char *actual = NULL;
421ebfedea0SLionel Sambuc char buf[64];
422ebfedea0SLionel Sambuc time_t t = 0;
423ebfedea0SLionel Sambuc int i;
424ebfedea0SLionel Sambuc
425ebfedea0SLionel Sambuc for(i = 0; fac && i < fac->len; i++)
426ebfedea0SLionel Sambuc if(fac->val[i].min <= level &&
427ebfedea0SLionel Sambuc (fac->val[i].max < 0 || fac->val[i].max >= level)) {
428ebfedea0SLionel Sambuc if(t == 0) {
429ebfedea0SLionel Sambuc t = time(NULL);
430ebfedea0SLionel Sambuc krb5_format_time(context, t, buf, sizeof(buf), TRUE);
431ebfedea0SLionel Sambuc }
432ebfedea0SLionel Sambuc if(actual == NULL) {
433ebfedea0SLionel Sambuc int ret = vasprintf(&msg, fmt, ap);
434ebfedea0SLionel Sambuc if(ret < 0 || msg == NULL)
435ebfedea0SLionel Sambuc actual = fmt;
436ebfedea0SLionel Sambuc else
437ebfedea0SLionel Sambuc actual = msg;
438ebfedea0SLionel Sambuc }
439ebfedea0SLionel Sambuc (*fac->val[i].log_func)(buf, actual, fac->val[i].data);
440ebfedea0SLionel Sambuc }
441ebfedea0SLionel Sambuc if(reply == NULL)
442ebfedea0SLionel Sambuc free(msg);
443ebfedea0SLionel Sambuc else
444ebfedea0SLionel Sambuc *reply = msg;
445ebfedea0SLionel Sambuc return 0;
446ebfedea0SLionel Sambuc }
447ebfedea0SLionel Sambuc
448ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_vlog(krb5_context context,krb5_log_facility * fac,int level,const char * fmt,va_list ap)449ebfedea0SLionel Sambuc krb5_vlog(krb5_context context,
450ebfedea0SLionel Sambuc krb5_log_facility *fac,
451ebfedea0SLionel Sambuc int level,
452ebfedea0SLionel Sambuc const char *fmt,
453ebfedea0SLionel Sambuc va_list ap)
454ebfedea0SLionel Sambuc __attribute__((format (printf, 4, 0)))
455ebfedea0SLionel Sambuc {
456ebfedea0SLionel Sambuc return krb5_vlog_msg(context, fac, NULL, level, fmt, ap);
457ebfedea0SLionel Sambuc }
458ebfedea0SLionel Sambuc
459ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_log_msg(krb5_context context,krb5_log_facility * fac,int level,char ** reply,const char * fmt,...)460ebfedea0SLionel Sambuc krb5_log_msg(krb5_context context,
461ebfedea0SLionel Sambuc krb5_log_facility *fac,
462ebfedea0SLionel Sambuc int level,
463ebfedea0SLionel Sambuc char **reply,
464ebfedea0SLionel Sambuc const char *fmt,
465ebfedea0SLionel Sambuc ...)
466ebfedea0SLionel Sambuc __attribute__((format (printf, 5, 6)))
467ebfedea0SLionel Sambuc {
468ebfedea0SLionel Sambuc va_list ap;
469ebfedea0SLionel Sambuc krb5_error_code ret;
470ebfedea0SLionel Sambuc
471ebfedea0SLionel Sambuc va_start(ap, fmt);
472ebfedea0SLionel Sambuc ret = krb5_vlog_msg(context, fac, reply, level, fmt, ap);
473ebfedea0SLionel Sambuc va_end(ap);
474ebfedea0SLionel Sambuc return ret;
475ebfedea0SLionel Sambuc }
476ebfedea0SLionel Sambuc
477ebfedea0SLionel Sambuc
478ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_log(krb5_context context,krb5_log_facility * fac,int level,const char * fmt,...)479ebfedea0SLionel Sambuc krb5_log(krb5_context context,
480ebfedea0SLionel Sambuc krb5_log_facility *fac,
481ebfedea0SLionel Sambuc int level,
482ebfedea0SLionel Sambuc const char *fmt,
483ebfedea0SLionel Sambuc ...)
484ebfedea0SLionel Sambuc __attribute__((format (printf, 4, 5)))
485ebfedea0SLionel Sambuc {
486ebfedea0SLionel Sambuc va_list ap;
487ebfedea0SLionel Sambuc krb5_error_code ret;
488ebfedea0SLionel Sambuc
489ebfedea0SLionel Sambuc va_start(ap, fmt);
490ebfedea0SLionel Sambuc ret = krb5_vlog(context, fac, level, fmt, ap);
491ebfedea0SLionel Sambuc va_end(ap);
492ebfedea0SLionel Sambuc return ret;
493ebfedea0SLionel Sambuc }
494ebfedea0SLionel Sambuc
495ebfedea0SLionel Sambuc void KRB5_LIB_FUNCTION
_krb5_debug(krb5_context context,int level,const char * fmt,...)496ebfedea0SLionel Sambuc _krb5_debug(krb5_context context,
497ebfedea0SLionel Sambuc int level,
498ebfedea0SLionel Sambuc const char *fmt,
499ebfedea0SLionel Sambuc ...)
500ebfedea0SLionel Sambuc __attribute__((format (printf, 3, 4)))
501ebfedea0SLionel Sambuc {
502ebfedea0SLionel Sambuc va_list ap;
503ebfedea0SLionel Sambuc
504ebfedea0SLionel Sambuc if (context == NULL || context->debug_dest == NULL)
505ebfedea0SLionel Sambuc return;
506ebfedea0SLionel Sambuc
507ebfedea0SLionel Sambuc va_start(ap, fmt);
508ebfedea0SLionel Sambuc krb5_vlog(context, context->debug_dest, level, fmt, ap);
509ebfedea0SLionel Sambuc va_end(ap);
510ebfedea0SLionel Sambuc }
511ebfedea0SLionel Sambuc
512ebfedea0SLionel Sambuc krb5_boolean KRB5_LIB_FUNCTION
_krb5_have_debug(krb5_context context,int level)513ebfedea0SLionel Sambuc _krb5_have_debug(krb5_context context, int level)
514ebfedea0SLionel Sambuc {
515ebfedea0SLionel Sambuc if (context == NULL || context->debug_dest == NULL)
516ebfedea0SLionel Sambuc return 0 ;
517ebfedea0SLionel Sambuc return 1;
518ebfedea0SLionel Sambuc }
519