~ubuntu-branches/ubuntu/precise/nss-pam-ldapd/precise-security

« back to all changes in this revision

Viewing changes to nslcd/log.c

  • Committer: Package Import Robot
  • Author(s): Arthur de Jong
  • Date: 2011-09-04 21:00:00 UTC
  • mfrom: (14.1.4 experimental)
  • Revision ID: package-import@ubuntu.com-20110904210000-pe3u91iga88vtr16
Tags: 0.8.4
* Upload to unstable
* switch to using the member attribute by default instead of
  uniqueMember (backwards incompatible change)
* only return "x" as a password hash when the object has the shadowAccount
  objectClass and nsswitch.conf is configured to do shadow lookups using
  LDAP (this avoids some problems with pam_unix)
* fix problem with partial attribute name matches in DN (thanks Timothy
  White)
* fix a problem with objectSid mappings with recent versions of OpenLDAP
  (patch by Wesley Mason)
* set the socket timeout in a connection callback to avoid timeout
  issues during the SSL handshake (patch by Stefan Völkel)
* check for unknown variables in pam_authz_search
* only check password expiration when authenticating, only check account
  expiration when doing authorisation
* make buffer sizes consistent and grow all buffers holding string
  representations of numbers to be able to hold 64-bit numbers
* update AX_PTHREAD from autoconf-archive
* support querying DNS SRV records from a different domain than the current
  one (based on a patch by James M. Leddy)
* fix a problem with uninitialised memory while parsing the tls_ciphers
  option (closes: #638872) (but doesn't work yet due to #640384)
* implement bounds checking of numeric values read from LDAP (patch by
  Jakub Hrozek)
* correctly support large uid and gid values from LDAP (patch by Jakub
  Hrozek)
* improvements to the configure script (patch by Jakub Hrozek)
* switch to dh for debian/rules and bump debhelper compatibility to 8
* build Debian packages with multiarch support
* ship shlibs (but still no symbol files) for libnss-ldapd since that was
  the easiest way to support multiarch
* fix output in init script when restarting nslcd (closes: #637132)
* correctly handle leading and trailing spaces in preseeded debconf uri
  option (patch by Andreas B. Mundt) (closes: #637863)
* support spaces around database names in /etc/nsswitch.conf while
  configuring package (closes: #640185)
* updated Russian debconf translation by Yuri Kozlov (closes: #637751)
* updated French debconf translation by Christian Perrier (closes: #637756)
* added Slovak debconf translation by Slavko (closes: #637759)
* updated Danish debconf translation by Joe Hansen (closes :#637763)
* updated Brazilian Portuguese debconf translation by Denis Doria
* updated Portuguese debconf translation by Américo Monteiro
* updated Japanese debconf translation by Kenshi Muto (closes: #638195)
* updated Czech debconf translation by Miroslav Kure (closes: #639026)
* updated German debconf translation by Chris Leick (closes: #639107)
* updated Spanish debconf translation by Francisco Javier Cuadrado
  (closes: #639236)
* updated Dutch debconf translation by Arthur de Jong with help from Paul
  Gevers and Jeroen Schot

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
   log.c - logging funtions
3
3
 
4
 
   Copyright (C) 2002, 2003, 2008 Arthur de Jong
 
4
   Copyright (C) 2002, 2003, 2008, 2010, 2011 Arthur de Jong
5
5
 
6
6
   This library is free software; you can redistribute it and/or
7
7
   modify it under the terms of the GNU Lesser General Public
19
19
   02110-1301 USA
20
20
*/
21
21
 
22
 
 
23
22
#include "config.h"
24
23
 
25
24
#include <stdio.h>
34
33
 
35
34
#include "log.h"
36
35
 
37
 
 
38
36
/* set the logname */
39
37
#undef PACKAGE
40
38
#define PACKAGE "nslcd"
41
39
 
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
40
/* default loglevel when no logging is configured */
52
41
static int prelogging_loglevel=LOG_INFO;
53
42
 
 
43
/* loglevel to use before logging to syslog */
 
44
static int loglevel=LOG_INFO;
54
45
 
55
46
/* the session id that is set for this thread */
56
47
static __thread char *sessionid=NULL;
57
48
 
 
49
/* the request identifier that is set for this thread */
 
50
static __thread char *requestid=NULL;
 
51
#define MAX_REQUESTID_LENGTH 40
58
52
 
59
53
/* 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
 
 
 
54
void log_setdefaultloglevel(int pri)
 
55
{
 
56
  prelogging_loglevel=pri;
 
57
}
121
58
 
122
59
/* start the logging with the configured logging methods
123
60
   if no method is configured yet, logging is done to syslog */
124
61
void log_startlogging(void)
125
62
{
126
 
  if (cvsd_loglist==NULL)
127
 
    log_addlogging_syslog(LOG_INFO);
 
63
  openlog(PACKAGE,LOG_PID,LOG_DAEMON);
128
64
  prelogging_loglevel=-1;
129
65
}
130
66
 
 
67
/* indicate that we should clear any session identifiers set by
 
68
   log_newsession */
 
69
void log_clearsession(void)
 
70
{
 
71
  /* set the session id to empty */
 
72
  if (sessionid!=NULL)
 
73
    sessionid[0]='\0';
 
74
  /* set the request id to empty */
 
75
  if (requestid!=NULL)
 
76
    requestid[0]='\0';
 
77
}
131
78
 
132
79
/* indicate that a session id should be included in the output
133
80
   and set it to a new value */
144
91
    }
145
92
  }
146
93
  sprintf(sessionid,"%06x",(int)(rand()&0xffffff));
 
94
  /* set the request id to empty */
 
95
  if (requestid!=NULL)
 
96
    requestid[0]='\0';
147
97
}
148
98
 
 
99
/* indicate that a request identifier should be included in the output
 
100
   from this point on, until log_newsession() is called */
 
101
void log_setrequest(const char *format, ...)
 
102
{
 
103
  va_list ap;
 
104
  /* ensure that requestid can hold a string */
 
105
  if (requestid==NULL)
 
106
  {
 
107
    requestid=(char *)malloc(MAX_REQUESTID_LENGTH);
 
108
    if (requestid==NULL)
 
109
    {
 
110
      fprintf(stderr,"malloc() failed: %s",strerror(errno));
 
111
      return; /* silently fail */
 
112
    }
 
113
  }
 
114
  /* make the message */
 
115
  va_start(ap,format);
 
116
  vsnprintf(requestid,MAX_REQUESTID_LENGTH,format,ap);
 
117
  requestid[MAX_REQUESTID_LENGTH-1]='\0';
 
118
  va_end(ap);
 
119
}
149
120
 
150
121
/* log the given message using the configured logging method */
151
122
void log_log(int pri,const char *format, ...)
152
123
{
153
124
  int res;
154
 
  struct cvsd_log *lst;
155
 
  /* TODO: make this something better */
156
 
  #define maxbufferlen 200
157
 
  char buffer[maxbufferlen];
 
125
  char buffer[200];
158
126
  va_list ap;
159
127
  /* make the message */
160
128
  va_start(ap,format);
161
 
  res=vsnprintf(buffer,maxbufferlen,format,ap);
162
 
  if ((res<0)||(res>=maxbufferlen))
 
129
  res=vsnprintf(buffer,sizeof(buffer),format,ap);
 
130
  if ((res<0)||(res>=(int)sizeof(buffer)))
163
131
  {
164
132
    /* truncate with "..." */
165
 
    buffer[maxbufferlen-2]='.';
166
 
    buffer[maxbufferlen-3]='.';
167
 
    buffer[maxbufferlen-4]='.';
 
133
    buffer[sizeof(buffer)-2]='.';
 
134
    buffer[sizeof(buffer)-3]='.';
 
135
    buffer[sizeof(buffer)-4]='.';
168
136
  }
169
 
  buffer[maxbufferlen-1]='\0';
 
137
  buffer[sizeof(buffer)-1]='\0';
170
138
  va_end(ap);
171
139
  /* do the logging */
172
140
  if (prelogging_loglevel>=0)
174
142
    /* if logging is not yet defined, log to stderr */
175
143
    if (pri<=prelogging_loglevel)
176
144
    {
177
 
      if (sessionid)
 
145
      if ((requestid!=NULL)&&(requestid[0]!='\0'))
 
146
        fprintf(stderr,"%s: [%s] <%s> %s%s\n",PACKAGE,sessionid,requestid,pri==LOG_DEBUG?"DEBUG: ":"",buffer);
 
147
      else if ((sessionid!=NULL)&&(sessionid[0]!='\0'))
178
148
        fprintf(stderr,"%s: [%s] %s%s\n",PACKAGE,sessionid,pri==LOG_DEBUG?"DEBUG: ":"",buffer);
179
149
      else
180
150
        fprintf(stderr,"%s: %s%s\n",PACKAGE,pri==LOG_DEBUG?"DEBUG: ":"",buffer);
182
152
  }
183
153
  else
184
154
  {
185
 
    for (lst=cvsd_loglist;lst!=NULL;lst=lst->next)
 
155
    if (pri<=loglevel)
186
156
    {
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
 
      }
 
157
      if ((requestid!=NULL)&&(requestid[0]!='\0'))
 
158
        syslog(pri,"[%s] <%s> %s",sessionid,requestid,buffer);
 
159
      else if ((sessionid!=NULL)&&(sessionid[0]!='\0'))
 
160
        syslog(pri,"[%s] %s",sessionid,buffer);
 
161
      else
 
162
        syslog(pri,"%s",buffer);
205
163
    }
206
164
  }
207
165
}
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
 
}