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

« back to all changes in this revision

Viewing changes to nss/netgroup.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
   netgroup.c - NSS lookup functions for netgroup entries
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
29
30
#include "prototypes.h"
30
31
#include "common.h"
31
32
#include "compat/attrs.h"
 
33
#include "common/set.h"
32
34
 
33
35
/* we redefine this here because we need to return NSS_STATUS_RETURN
34
36
   instead of NSS_STATUS_NOTFOUND */
39
41
  return NSS_STATUS_RETURN;
40
42
 
41
43
/* function for reading a single result entry */
42
 
static enum nss_status read_netgrent(
 
44
static nss_status_t read_netgrent(
43
45
        TFILE *fp,struct __netgrent *result,
44
46
        char *buffer,size_t buflen,int *errnop)
45
47
{
86
88
  return NSS_STATUS_SUCCESS;
87
89
}
88
90
 
 
91
#ifdef NSS_FLAVOUR_GLIBC
 
92
 
89
93
/* thread-local file pointer to an ongoing request */
90
94
static __thread TFILE *netgrentfp;
91
95
 
92
 
enum nss_status _nss_ldap_setnetgrent(const char *group,struct __netgrent UNUSED(*result))
 
96
/* start a request to get a netgroup by name */
 
97
nss_status_t _nss_ldap_setnetgrent(
 
98
        const char *group,struct __netgrent UNUSED(*result))
93
99
{
94
100
  /* we cannot use NSS_SETENT() here because we have a parameter that is only
95
101
     available in this function */
107
113
  return NSS_STATUS_SUCCESS;
108
114
}
109
115
 
110
 
enum nss_status _nss_ldap_getnetgrent_r(struct __netgrent *result,char *buffer,size_t buflen,int *errnop)
 
116
/* get a single netgroup tuple from the stream */
 
117
nss_status_t _nss_ldap_getnetgrent_r(
 
118
        struct __netgrent *result,
 
119
        char *buffer,size_t buflen,int *errnop)
111
120
{
112
121
  NSS_GETENT(netgrentfp,NSLCD_ACTION_NETGROUP_BYNAME,
113
122
             read_netgrent(netgrentfp,result,buffer,buflen,errnop));
114
123
}
115
124
 
116
 
enum nss_status _nss_ldap_endnetgrent(struct __netgrent UNUSED(* result))
 
125
/* close the stream opened with setnetgrent() above */
 
126
nss_status_t _nss_ldap_endnetgrent(struct __netgrent UNUSED(*result))
117
127
{
118
128
  NSS_ENDENT(netgrentfp);
119
129
}
 
130
 
 
131
#endif /* NSS_FLAVOUR_GLIBC */
 
132
 
 
133
#ifdef NSS_FLAVOUR_SOLARIS
 
134
 
 
135
/* this is the backend structure for the {set,get,end}ent() functions */
 
136
struct setnetgrent_backend
 
137
{
 
138
  nss_backend_op_t *ops; /* function-pointer table */
 
139
  int n_ops; /* number of function pointers */
 
140
  TFILE *fp; /* the file pointer for {set,get,end}ent() functions */
 
141
  SET *seen_groups; /* netgroups seen, for loop detection */
 
142
  SET *unseen_groups; /* netgroups that need to be chased */
 
143
};
 
144
 
 
145
/* easy way to get sets from back-end */
 
146
#define NETGROUP_BE(be) ((struct setnetgrent_backend*)(be))
 
147
 
 
148
/* access arguments */
 
149
#define SETNETGRENT_ARGS(args) ((struct nss_setnetgrent_args *)(args))
 
150
#define GETNETGRENT_ARGS(args) ((struct nss_getnetgrent_args *)(args))
 
151
 
 
152
/* return a netgroup that has not been traversed */
 
153
static char *find_unseen_netgroup(nss_backend_t *be)
 
154
{
 
155
  char *group;
 
156
  while (1)
 
157
  {
 
158
    group=set_pop(NETGROUP_BE(be)->unseen_groups);
 
159
    if (group==NULL)
 
160
      return NULL;
 
161
    if (!set_contains(NETGROUP_BE(be)->seen_groups,group))
 
162
    {
 
163
      set_add(NETGROUP_BE(be)->seen_groups,group);
 
164
      return group;
 
165
    }
 
166
  }
 
167
}
 
168
 
 
169
static nss_status_t netgroup_nslcd_setnetgrent(nss_backend_t *be,const char *group)
 
170
{
 
171
  /* we cannot use NSS_SETENT() here because we have a parameter that is only
 
172
     available in this function */
 
173
  int32_t tmpint32;
 
174
  int errnocp;
 
175
  int *errnop;
 
176
  errnop=&errnocp;
 
177
  /* check parameter */
 
178
  if ((group==NULL)||(group[0]=='\0'))
 
179
    return NSS_STATUS_UNAVAIL;
 
180
  /* open a new stream and write the request */
 
181
  NSLCD_REQUEST(NETGROUP_BE(be)->fp,NSLCD_ACTION_NETGROUP_BYNAME,
 
182
                WRITE_STRING(NETGROUP_BE(be)->fp,group));
 
183
  return NSS_STATUS_SUCCESS;
 
184
}
 
185
 
 
186
static nss_status_t netgroup_nslcd_getnetgrent(nss_backend_t *be,struct __netgrent *result,char *buffer,size_t buflen,void *args)
 
187
{
 
188
  NSS_GETENT(NETGROUP_BE(be)->fp,NSLCD_ACTION_NETGROUP_BYNAME,
 
189
             read_netgrent(NETGROUP_BE(be)->fp,result,buffer,buflen,errnop));
 
190
}
 
191
 
 
192
static nss_status_t netgroup_setnetgrent_setnetgrent(nss_backend_t UNUSED(*be),void UNUSED(*args))
 
193
{
 
194
  return NSS_STATUS_SUCCESS;
 
195
}
 
196
 
 
197
static nss_status_t netgroup_setnetgrent_getnetgrent(nss_backend_t *be,void *args)
 
198
{
 
199
  struct __netgrent result;
 
200
  char *group=NULL;
 
201
  int done=0;
 
202
  nss_status_t status,rc;
 
203
  GETNETGRENT_ARGS(args)->status=NSS_NETGR_NO;
 
204
  while (!done)
 
205
  {
 
206
    status=netgroup_nslcd_getnetgrent(be,&result,GETNETGRENT_ARGS(args)->buffer,
 
207
                                         GETNETGRENT_ARGS(args)->buflen,args);
 
208
    if (status!=NSS_STATUS_SUCCESS)
 
209
    {
 
210
      if (errno==ENOENT)
 
211
      {
 
212
        /* done with the current netgroup */
 
213
        /* explore nested netgroup,if any */
 
214
        int found=0;
 
215
        while (!found)
 
216
        {
 
217
          /* find a nested netgroup to pursue further */
 
218
          group=find_unseen_netgroup(be);
 
219
          if (group==NULL)
 
220
          {
 
221
            /* no more netgroup */
 
222
            found=1; done=1;
 
223
            errno=ENOENT;
 
224
          }
 
225
          else
 
226
          {
 
227
            rc=netgroup_nslcd_setnetgrent(be,group);
 
228
            if (rc==NSS_STATUS_SUCCESS)
 
229
              found=1;
 
230
            free(group);
 
231
            group=NULL;
 
232
          }
 
233
        } /* while !found */
 
234
      }
 
235
      else
 
236
      { /* err!=ENOENT */
 
237
        done=1;
 
238
      }
 
239
    }
 
240
    else
 
241
    { /* status==NSS_STATUS_SUCCESS */
 
242
      if (result.type==group_val)
 
243
      {
 
244
        /* a netgroup nested within the current netgroup */
 
245
        set_add(NETGROUP_BE(be)->unseen_groups,result.val.group);
 
246
      }
 
247
      else if (result.type==triple_val)
 
248
      {
 
249
        GETNETGRENT_ARGS(args)->retp[NSS_NETGR_MACHINE]=result.val.triple.host;
 
250
        GETNETGRENT_ARGS(args)->retp[NSS_NETGR_USER]=result.val.triple.user;
 
251
        GETNETGRENT_ARGS(args)->retp[NSS_NETGR_DOMAIN]=result.val.triple.domain;
 
252
        GETNETGRENT_ARGS(args)->status=NSS_NETGR_FOUND;
 
253
        done=1;
 
254
      }
 
255
      else
 
256
      {
 
257
        /* NSS_STATUS_SUCCESS,but type is not group_val or triple_val */
 
258
        /* should not be here,log a message */
 
259
        status=NSS_STATUS_NOTFOUND;
 
260
        done=1;
 
261
      }
 
262
    }
 
263
  } /* while !done */
 
264
  return status;
 
265
}
 
266
 
 
267
static nss_status_t netgroup_setnetgrent_endnetgrent(nss_backend_t UNUSED(*be),void UNUSED(*args))
 
268
{
 
269
  NSS_ENDENT(NETGROUP_BE(be)->fp);
 
270
}
 
271
 
 
272
static nss_status_t netgroup_setnetgrent_destructor(nss_backend_t *be,void *UNUSED(args))
 
273
{
 
274
  struct setnetgrent_backend *ngbe=(struct setnetgrent_backend *)be;
 
275
  if (ngbe->fp!=NULL)
 
276
    (void)tio_close(ngbe->fp);
 
277
  set_free(ngbe->seen_groups);
 
278
  set_free(ngbe->unseen_groups);
 
279
  free(ngbe);
 
280
  return NSS_STATUS_SUCCESS;
 
281
}
 
282
 
 
283
static nss_backend_op_t netgroup_setnetgrent_ops[]={
 
284
  netgroup_setnetgrent_destructor,
 
285
  netgroup_setnetgrent_endnetgrent,
 
286
  netgroup_setnetgrent_setnetgrent,
 
287
  netgroup_setnetgrent_getnetgrent,
 
288
};
 
289
 
 
290
static nss_status_t netgroup_setnetgrent_constructor(nss_backend_t *be,void *args)
 
291
{
 
292
  struct setnetgrent_backend *ngbe;
 
293
  nss_status_t retv;
 
294
  NSS_AVAILCHECK;
 
295
  SETNETGRENT_ARGS(args)->iterator=NULL;        /* initialize */
 
296
  /* allocate a back-end specific to this request */
 
297
  ngbe=(struct setnetgrent_backend *)malloc(sizeof(struct setnetgrent_backend));
 
298
  if (ngbe==NULL)
 
299
    return NSS_STATUS_UNAVAIL;
 
300
  ngbe->ops=netgroup_setnetgrent_ops;
 
301
  ngbe->n_ops=sizeof(netgroup_setnetgrent_ops)/sizeof(nss_backend_op_t);
 
302
  ngbe->fp=NULL;
 
303
  ngbe->seen_groups=set_new();
 
304
  ngbe->unseen_groups=set_new();
 
305
  /* start the first search */
 
306
  retv=netgroup_nslcd_setnetgrent(be,SETNETGRENT_ARGS(args)->netgroup);
 
307
  if (retv!=NSS_STATUS_SUCCESS)
 
308
  {
 
309
    netgroup_setnetgrent_destructor(be,args);
 
310
    return retv;
 
311
  }
 
312
  /* return the new back-end */
 
313
  SETNETGRENT_ARGS(args)->iterator=(nss_backend_t *)ngbe;
 
314
  return NSS_STATUS_SUCCESS;
 
315
}
 
316
 
 
317
static nss_backend_op_t netgroup_ops[]={
 
318
  nss_ldap_destructor,
 
319
  NULL,
 
320
  NULL,
 
321
  NULL,
 
322
  NULL,/* TODO:_nss_ldap_netgr_in,*/
 
323
  netgroup_setnetgrent_constructor
 
324
};
 
325
 
 
326
nss_backend_t *_nss_ldap_netgroup_constr(const char UNUSED(*db_name),
 
327
                  const char UNUSED(*src_name),const char UNUSED(*cfg_args))
 
328
{
 
329
  return nss_ldap_constructor(netgroup_ops,sizeof(netgroup_ops));
 
330
}
 
331
 
 
332
#endif /* NSS_FLAVOUR_SOLARIS */