~ubuntu-branches/ubuntu/utopic/nss-pam-ldapd/utopic-proposed

« back to all changes in this revision

Viewing changes to nslcd/log.c

  • Committer: Bazaar Package Importer
  • Author(s): Arthur de Jong
  • Date: 2009-09-01 17:00:00 UTC
  • Revision ID: james.westby@ubuntu.com-20090901170000-54hqcpmbxk32rzer
Tags: 0.7.0
* rename software to nss-pam-ldapd to indicate that PAM module is now a
  standard part of the software
* split into the binary packages libnss-ldapd, libpam-ldapd and nslcd
  (libpam-ldapd packaging used a patch for libpam-ldap by Steve Langasek)
  (closes: #535505)
* the configuration file name has been changed to /etc/nslcd.conf (package
  upgrade should migrate the configuration)
* updated Galician debconf translation by Marce Villarino (closes: #537424)
* patch by Petter Reinholdtsen to fix init script to start before autofs
  (closes: #544093)
* the default values for bind_timelimit and reconnect_maxsleeptime were
  lowered from 30 to 10 seconds (closes: #532874)
* upgrade to standards-version 3.8.3 (no changes needed)
* password hashes are no longer returned to non-root users (based on a patch
  by Alexander V. Chernikov)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   log.c - logging funtions
 
3
 
 
4
   Copyright (C) 2002, 2003, 2008 Arthur de Jong
 
5
 
 
6
   This library is free software; you can redistribute it and/or
 
7
   modify it under the terms of the GNU Lesser General Public
 
8
   License as published by the Free Software Foundation; either
 
9
   version 2.1 of the License, or (at your option) any later version.
 
10
 
 
11
   This library is distributed in the hope that it will be useful,
 
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
   Lesser General Public License for more details.
 
15
 
 
16
   You should have received a copy of the GNU Lesser General Public
 
17
   License along with this library; if not, write to the Free Software
 
18
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
19
   02110-1301 USA
 
20
*/
 
21
 
 
22
 
 
23
#include "config.h"
 
24
 
 
25
#include <stdio.h>
 
26
#include <stdlib.h>
 
27
#include <sys/types.h>
 
28
#include <unistd.h>
 
29
#include <syslog.h>
 
30
#include <stdarg.h>
 
31
#include <errno.h>
 
32
#include <string.h>
 
33
#include <time.h>
 
34
 
 
35
#include "log.h"
 
36
 
 
37
 
 
38
/* set the logname */
 
39
#undef PACKAGE
 
40
#define PACKAGE "nslcd"
 
41
 
 
42
 
 
43
/* storage for logging modes */
 
44
static struct cvsd_log {
 
45
  FILE *fp; /* NULL==syslog */
 
46
  int loglevel;
 
47
  struct cvsd_log *next;
 
48
} *cvsd_loglist=NULL;
 
49
 
 
50
 
 
51
/* default loglevel when no logging is configured */
 
52
static int prelogging_loglevel=LOG_INFO;
 
53
 
 
54
 
 
55
/* the session id that is set for this thread */
 
56
static __thread char *sessionid=NULL;
 
57
 
 
58
 
 
59
/* set loglevel when no logging is configured */
 
60
void log_setdefaultloglevel(int loglevel)
 
61
{
 
62
  prelogging_loglevel=loglevel;
 
63
}
 
64
 
 
65
 
 
66
/* add logging method to configuration list */
 
67
static void log_addlogging_fp(FILE *fp,int loglevel)
 
68
{
 
69
  struct cvsd_log *tmp,*lst;
 
70
  /* create new logstruct */
 
71
  tmp=(struct cvsd_log *)malloc(sizeof(struct cvsd_log));
 
72
  if (tmp==NULL)
 
73
  {
 
74
    fprintf(stderr,"malloc() failed: %s",strerror(errno));
 
75
    /* since this is done during initialisation it's best to bail out */
 
76
    exit(EXIT_FAILURE);
 
77
  }
 
78
  tmp->fp=fp;
 
79
  tmp->loglevel=loglevel;
 
80
  tmp->next=NULL;
 
81
  /* save the struct in the list */
 
82
  if (cvsd_loglist==NULL)
 
83
    cvsd_loglist=tmp;
 
84
  else
 
85
  {
 
86
    for (lst=cvsd_loglist;lst->next!=NULL;lst=lst->next);
 
87
    lst->next=tmp;
 
88
  }
 
89
}
 
90
 
 
91
 
 
92
/* configure logging to a file */
 
93
void log_addlogging_file(const char *filename,int loglevel)
 
94
{
 
95
  FILE *fp;
 
96
  fp=fopen(filename,"a");
 
97
  if (fp==NULL)
 
98
  {
 
99
    log_log(LOG_ERR,"cannot open logfile (%s) for appending: %s",filename,strerror(errno));
 
100
    exit(EXIT_FAILURE);
 
101
  }
 
102
  log_addlogging_fp(fp,loglevel);
 
103
}
 
104
 
 
105
 
 
106
/* configure logging to syslog */
 
107
void log_addlogging_syslog(int loglevel)
 
108
{
 
109
  openlog(PACKAGE,LOG_PID,LOG_DAEMON);
 
110
  log_addlogging_fp(NULL,loglevel);
 
111
}
 
112
 
 
113
 
 
114
/* configure a null logging mode (no logging) */
 
115
void log_addlogging_none()
 
116
{
 
117
  /* this is a hack, but it's so easy */
 
118
  log_addlogging_fp(NULL,LOG_EMERG);
 
119
}
 
120
 
 
121
 
 
122
/* start the logging with the configured logging methods
 
123
   if no method is configured yet, logging is done to syslog */
 
124
void log_startlogging(void)
 
125
{
 
126
  if (cvsd_loglist==NULL)
 
127
    log_addlogging_syslog(LOG_INFO);
 
128
  prelogging_loglevel=-1;
 
129
}
 
130
 
 
131
 
 
132
/* indicate that a session id should be included in the output
 
133
   and set it to a new value */
 
134
void log_newsession(void)
 
135
{
 
136
  /* ensure that sessionid can hold a string */
 
137
  if (sessionid==NULL)
 
138
  {
 
139
    sessionid=(char *)malloc(7);
 
140
    if (sessionid==NULL)
 
141
    {
 
142
      fprintf(stderr,"malloc() failed: %s",strerror(errno));
 
143
      return; /* silently fail */
 
144
    }
 
145
  }
 
146
  sprintf(sessionid,"%06x",(int)(rand()&0xffffff));
 
147
}
 
148
 
 
149
 
 
150
/* log the given message using the configured logging method */
 
151
void log_log(int pri,const char *format, ...)
 
152
{
 
153
  int res;
 
154
  struct cvsd_log *lst;
 
155
  /* TODO: make this something better */
 
156
  #define maxbufferlen 200
 
157
  char buffer[maxbufferlen];
 
158
  va_list ap;
 
159
  /* make the message */
 
160
  va_start(ap,format);
 
161
  res=vsnprintf(buffer,maxbufferlen,format,ap);
 
162
  if ((res<0)||(res>=maxbufferlen))
 
163
  {
 
164
    /* truncate with "..." */
 
165
    buffer[maxbufferlen-2]='.';
 
166
    buffer[maxbufferlen-3]='.';
 
167
    buffer[maxbufferlen-4]='.';
 
168
  }
 
169
  buffer[maxbufferlen-1]='\0';
 
170
  va_end(ap);
 
171
  /* do the logging */
 
172
  if (prelogging_loglevel>=0)
 
173
  {
 
174
    /* if logging is not yet defined, log to stderr */
 
175
    if (pri<=prelogging_loglevel)
 
176
    {
 
177
      if (sessionid)
 
178
        fprintf(stderr,"%s: [%s] %s%s\n",PACKAGE,sessionid,pri==LOG_DEBUG?"DEBUG: ":"",buffer);
 
179
      else
 
180
        fprintf(stderr,"%s: %s%s\n",PACKAGE,pri==LOG_DEBUG?"DEBUG: ":"",buffer);
 
181
    }
 
182
  }
 
183
  else
 
184
  {
 
185
    for (lst=cvsd_loglist;lst!=NULL;lst=lst->next)
 
186
    {
 
187
      if (pri<=lst->loglevel)
 
188
      {
 
189
        if (lst->fp==NULL) /* syslog */
 
190
        {
 
191
          if (sessionid)
 
192
            syslog(pri,"[%s] %s",sessionid,buffer);
 
193
          else
 
194
            syslog(pri,"%s",buffer);
 
195
        }
 
196
        else /* file */
 
197
        {
 
198
          if (sessionid)
 
199
            fprintf(lst->fp,"%s: [%s] %s\n",sessionid,PACKAGE,buffer);
 
200
          else
 
201
            fprintf(lst->fp,"%s: %s\n",PACKAGE,buffer);
 
202
          fflush(lst->fp);
 
203
        }
 
204
      }
 
205
    }
 
206
  }
 
207
}
 
208
 
 
209
 
 
210
/* return the syslog loglevel represented by the string
 
211
   return -1 on unknown */
 
212
int log_getloglevel(const char *lvl)
 
213
{
 
214
  if ( strcmp(lvl,"crit")==0 )
 
215
    return LOG_CRIT;
 
216
  else if ( (strcmp(lvl,"error")==0) ||
 
217
            (strcmp(lvl,"err")==0) )
 
218
    return LOG_ERR;
 
219
  else if ( strcmp(lvl,"warning")==0 )
 
220
    return LOG_WARNING;
 
221
  else if ( strcmp(lvl,"notice")==0 )
 
222
    return LOG_NOTICE;
 
223
  else if ( strcmp(lvl,"info")==0 )
 
224
    return LOG_INFO;
 
225
  else if ( strcmp(lvl,"debug")==0 )
 
226
    return LOG_DEBUG;
 
227
  else
 
228
    return -1; /* unknown */
 
229
}