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

« back to all changes in this revision

Viewing changes to nss/hosts.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:
2
2
   hosts.c - NSS lookup functions for hosts database
3
3
 
4
4
   Copyright (C) 2006 West Consulting
5
 
   Copyright (C) 2006, 2007, 2008 Arthur de Jong
 
5
   Copyright (C) 2006, 2007, 2008, 2010 Arthur de Jong
 
6
   Copyright (C) 2010 Symas Corporation
6
7
 
7
8
   This library is free software; you can redistribute it and/or
8
9
   modify it under the terms of the GNU Lesser General Public
24
25
 
25
26
#include <string.h>
26
27
#include <errno.h>
 
28
#include <sys/socket.h>
 
29
#include <netinet/in.h>
 
30
#include <arpa/inet.h>
27
31
 
28
32
#include "prototypes.h"
29
33
#include "common.h"
30
34
#include "compat/attrs.h"
31
35
 
32
 
/* Redifine some ERROR_OUT macros as we also want to set h_errnop. */
 
36
/* Redefine some ERROR_OUT macros as we also want to set h_errnop. */
33
37
 
34
38
#undef ERROR_OUT_OPENERROR
35
39
#define ERROR_OUT_OPENERROR \
61
65
   specified address family, result is stored in result
62
66
   it will an empty entry if no addresses in the address family
63
67
   were available */
64
 
static enum nss_status read_hostent(
 
68
static nss_status_t read_hostent(
65
69
        TFILE *fp,int af,struct hostent *result,
66
70
        char *buffer,size_t buflen,int *errnop,int *h_errnop)
67
71
{
108
112
/* this is a wrapper around read_hostent() that does error handling
109
113
   if the read address list does not contain any addresses for the
110
114
   specified address familiy */
111
 
static enum nss_status read_hostent_erronempty(
 
115
static nss_status_t read_hostent_erronempty(
112
116
        TFILE *fp,int af,struct hostent *result,
113
117
        char *buffer,size_t buflen,int *errnop,int *h_errnop)
114
118
{
115
 
  enum nss_status retv;
 
119
  nss_status_t retv;
116
120
  retv=read_hostent(fp,af,result,buffer,buflen,errnop,h_errnop);
117
121
  /* check result */
118
122
  if (retv!=NSS_STATUS_SUCCESS)
135
139
/* this is a wrapper around read_hostent() that skips to the
136
140
   next address if the address list does not contain any addresses for the
137
141
   specified address familiy */
138
 
static enum nss_status read_hostent_nextonempty(
 
142
static nss_status_t read_hostent_nextonempty(
139
143
        TFILE *fp,int af,struct hostent *result,
140
144
        char *buffer,size_t buflen,int *errnop,int *h_errnop)
141
145
{
142
146
  int32_t tmpint32;
143
 
  enum nss_status retv;
 
147
  nss_status_t retv;
144
148
  /* check until we read an non-empty entry */
145
149
  do
146
150
  {
161
165
  return NSS_STATUS_SUCCESS;
162
166
}
163
167
 
 
168
/* write an address value */
 
169
#define WRITE_ADDRESS(fp,af,len,addr) \
 
170
  WRITE_INT32(fp,af); \
 
171
  WRITE_INT32(fp,len); \
 
172
  WRITE(fp,addr,len);
 
173
 
 
174
#ifdef NSS_FLAVOUR_GLIBC
 
175
 
164
176
/* this function looks up a single host entry and returns all the addresses
165
177
   associated with the host in a single address familiy
166
178
   name            - IN  - hostname to lookup
168
180
   result          - OUT - entry found
169
181
   buffer,buflen   - OUT - buffer to store allocated stuff on
170
182
   errnop,h_errnop - OUT - for reporting errors */
171
 
enum nss_status _nss_ldap_gethostbyname2_r(
 
183
nss_status_t _nss_ldap_gethostbyname2_r(
172
184
        const char *name,int af,struct hostent *result,
173
185
        char *buffer,size_t buflen,int *errnop,int *h_errnop)
174
186
{
179
191
 
180
192
/* this function just calls the gethostbyname2() variant with the address
181
193
   familiy set */
182
 
enum nss_status _nss_ldap_gethostbyname_r(
 
194
nss_status_t _nss_ldap_gethostbyname_r(
183
195
        const char *name,struct hostent *result,
184
196
        char *buffer,size_t buflen,int *errnop,int *h_errnop)
185
197
{
186
198
  return _nss_ldap_gethostbyname2_r(name,AF_INET,result,buffer,buflen,errnop,h_errnop);
187
199
}
188
200
 
189
 
/* write an address value */
190
 
#define WRITE_ADDRESS(fp,af,len,addr) \
191
 
  WRITE_INT32(fp,af); \
192
 
  WRITE_INT32(fp,len); \
193
 
  WRITE(fp,addr,len);
194
 
 
195
201
/* this function looks up a single host entry and returns all the addresses
196
202
   associated with the host in a single address familiy
197
203
   addr            - IN  - the address to look up
200
206
   result          - OUT - entry found
201
207
   buffer,buflen   - OUT - buffer to store allocated stuff on
202
208
   errnop,h_errnop - OUT - for reporting errors */
203
 
enum nss_status _nss_ldap_gethostbyaddr_r(
 
209
nss_status_t _nss_ldap_gethostbyaddr_r(
204
210
        const void *addr,socklen_t len,int af,struct hostent *result,
205
211
        char *buffer,size_t buflen,int *errnop,int *h_errnop)
206
212
{
212
218
/* thread-local file pointer to an ongoing request */
213
219
static __thread TFILE *hostentfp;
214
220
 
215
 
enum nss_status _nss_ldap_sethostent(int UNUSED(stayopen))
 
221
nss_status_t _nss_ldap_sethostent(int UNUSED(stayopen))
216
222
{
217
223
  NSS_SETENT(hostentfp);
218
224
}
219
225
 
220
226
/* this function only returns addresses of the AF_INET address family */
221
 
enum nss_status _nss_ldap_gethostent_r(
 
227
nss_status_t _nss_ldap_gethostent_r(
222
228
        struct hostent *result,
223
229
        char *buffer,size_t buflen,int *errnop,int *h_errnop)
224
230
{
226
232
             read_hostent_nextonempty(hostentfp,AF_INET,result,buffer,buflen,errnop,h_errnop));
227
233
}
228
234
 
229
 
enum nss_status _nss_ldap_endhostent(void)
 
235
/* close the stream opened with sethostent() above */
 
236
nss_status_t _nss_ldap_endhostent(void)
230
237
{
231
238
  NSS_ENDENT(hostentfp);
232
239
}
 
240
 
 
241
#endif /* NSS_FLAVOUR_GLIBC */
 
242
 
 
243
#ifdef NSS_FLAVOUR_SOLARIS
 
244
 
 
245
struct nss_ldap_hosts_backend
 
246
{
 
247
  nss_backend_op_t *ops;
 
248
  int n_ops;
 
249
  TFILE *fp;
 
250
};
 
251
 
 
252
#ifdef HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN
 
253
 
 
254
static nss_status_t read_hoststring(TFILE *fp,nss_XbyY_args_t *args,int erronempty)
 
255
{
 
256
  struct hostent result;
 
257
  nss_status_t retv;
 
258
  char *buffer;
 
259
  size_t buflen;
 
260
  int i;
 
261
  /* read the hostent */
 
262
  if (erronempty)
 
263
    retv=read_hostent_erronempty(fp,NSS_ARGS(args)->key.hostaddr.type,&result,NSS_ARGS(args)->buf.buffer,args->buf.buflen,&errno,&(NSS_ARGS(args)->h_errno));
 
264
  else
 
265
    retv=read_hostent_nextonempty(fp,NSS_ARGS(args)->key.hostaddr.type,&result,NSS_ARGS(args)->buf.buffer,args->buf.buflen,&errno,&(NSS_ARGS(args)->h_errno));
 
266
  if (retv!=NSS_STATUS_SUCCESS)
 
267
    return retv;
 
268
  /* allocate a temporary buffer */
 
269
  buflen=args->buf.buflen;
 
270
  buffer=(char *)malloc(buflen);
 
271
  /* build the formatted string */
 
272
  /* FIXME: implement proper buffer size checking */
 
273
  if (result.h_addr_list)
 
274
  {
 
275
    struct in_addr in;
 
276
    (void)memcpy(&in.s_addr,result.h_addr_list[0],sizeof(in.s_addr));
 
277
    sprintf(buffer,"%s %s",inet_ntoa(in),result.h_name);
 
278
    if (result.h_aliases)
 
279
    {
 
280
      int j;
 
281
      for (j=0;result.h_aliases[j];j++)
 
282
      {
 
283
        strcat(buffer,"  ");
 
284
        strcat(buffer,result.h_aliases[j]);
 
285
      }
 
286
    }
 
287
    for (i=1;result.h_addr_list[i];i++)
 
288
    {
 
289
      (void)memcpy(&in.s_addr,result.h_addr_list[i],sizeof(in.s_addr));
 
290
      strcat(buffer,"\n");
 
291
      strcat(buffer,inet_ntoa(in));
 
292
      strcat(buffer," ");
 
293
      strcat(buffer,result.h_name);
 
294
      /* TODO: aliases only supplied to the first address */
 
295
      /* need review */
 
296
    }
 
297
  }
 
298
  /* copy the result back to the result buffer and free the temporary one */
 
299
  strcpy(NSS_ARGS(args)->buf.buffer,buffer);
 
300
  free(buffer);
 
301
  NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.buffer;
 
302
  NSS_ARGS(args)->returnlen=strlen(NSS_ARGS(args)->buf.buffer);
 
303
  return NSS_STATUS_SUCCESS;
 
304
}
 
305
 
 
306
#define READ_RESULT_ERRONEMPTY(fp) \
 
307
  NSS_ARGS(args)->buf.result? \
 
308
    read_hostent_erronempty(fp,NSS_ARGS(args)->key.hostaddr.type,(struct hostent *)NSS_ARGS(args)->buf.result,NSS_ARGS(args)->buf.buffer,NSS_ARGS(args)->buf.buflen,&errno,&(NSS_ARGS(args)->h_errno)): \
 
309
    read_hoststring(fp,args,1); \
 
310
  if ((NSS_ARGS(args)->buf.result)&&(retv==NSS_STATUS_SUCCESS)) \
 
311
    NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.result;
 
312
 
 
313
#define READ_RESULT_NEXTONEMPTY(fp) \
 
314
  NSS_ARGS(args)->buf.result? \
 
315
    read_hostent_nextonempty(fp,NSS_ARGS(args)->key.hostaddr.type,(struct hostent *)NSS_ARGS(args)->buf.result,NSS_ARGS(args)->buf.buffer,NSS_ARGS(args)->buf.buflen,&errno,&(NSS_ARGS(args)->h_errno)): \
 
316
    read_hoststring(fp,args,0); \
 
317
  if ((NSS_ARGS(args)->buf.result)&&(retv==NSS_STATUS_SUCCESS)) \
 
318
    NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.result;
 
319
 
 
320
#else /* not HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN */
 
321
 
 
322
#define READ_RESULT_ERRONEMPTY(fp) \
 
323
  read_hostent_erronempty(fp,NSS_ARGS(args)->key.hostaddr.type,(struct hostent *)NSS_ARGS(args)->buf.result,NSS_ARGS(args)->buf.buffer,NSS_ARGS(args)->buf.buflen,&errno,&(NSS_ARGS(args)->h_errno)); \
 
324
  if (retv==NSS_STATUS_SUCCESS) \
 
325
    NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.result;
 
326
 
 
327
#define READ_RESULT_NEXTONEMPTY(fp) \
 
328
  read_hostent_nextonempty(fp,NSS_ARGS(args)->key.hostaddr.type,(struct hostent *)NSS_ARGS(args)->buf.result,NSS_ARGS(args)->buf.buffer,NSS_ARGS(args)->buf.buflen,&errno,&(NSS_ARGS(args)->h_errno)); \
 
329
  if (retv==NSS_STATUS_SUCCESS) \
 
330
    NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.result;
 
331
 
 
332
#endif /* not HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN */
 
333
 
 
334
/* hack to set the correct errno and h_errno */
 
335
#define h_errnop &(NSS_ARGS(args)->h_errno)
 
336
 
 
337
static nss_status_t hosts_gethostbyname(nss_backend_t UNUSED(*be),void *args)
 
338
{
 
339
  NSS_BYNAME(NSLCD_ACTION_HOST_BYNAME,
 
340
             NSS_ARGS(args)->key.name,
 
341
             READ_RESULT_ERRONEMPTY(fp));
 
342
}
 
343
 
 
344
static nss_status_t hosts_gethostbyaddr(nss_backend_t UNUSED(*be),void *args)
 
345
{
 
346
  NSS_BYGEN(NSLCD_ACTION_HOST_BYADDR,
 
347
            WRITE_ADDRESS(fp,NSS_ARGS(args)->key.hostaddr.type,NSS_ARGS(args)->key.hostaddr.len,NSS_ARGS(args)->key.hostaddr.addr),
 
348
            READ_RESULT_ERRONEMPTY(fp));
 
349
}
 
350
 
 
351
static nss_status_t hosts_sethostent(nss_backend_t *be,void UNUSED(*args))
 
352
{
 
353
  NSS_SETENT(LDAP_BE(be)->fp);
 
354
}
 
355
 
 
356
static nss_status_t hosts_gethostent(nss_backend_t *be,void *args)
 
357
{
 
358
  NSS_GETENT(LDAP_BE(be)->fp,NSLCD_ACTION_HOST_ALL,
 
359
             READ_RESULT_NEXTONEMPTY(LDAP_BE(be)->fp));
 
360
}
 
361
 
 
362
static nss_status_t hosts_endhostent(nss_backend_t *be,void UNUSED(*args))
 
363
{
 
364
  NSS_ENDENT(LDAP_BE(be)->fp);
 
365
}
 
366
 
 
367
static nss_backend_op_t hosts_ops[]={
 
368
  nss_ldap_destructor,
 
369
  hosts_endhostent,
 
370
  hosts_sethostent,
 
371
  hosts_gethostent,
 
372
  hosts_gethostbyname,
 
373
  hosts_gethostbyaddr
 
374
};
 
375
 
 
376
nss_backend_t *_nss_ldap_hosts_constr(const char UNUSED(*db_name),
 
377
                  const char UNUSED(*src_name),const char UNUSED(*cfg_args))
 
378
{
 
379
  return nss_ldap_constructor(hosts_ops,sizeof(hosts_ops));
 
380
}
 
381
 
 
382
#endif /* NSS_FLAVOUR_SOLARIS */