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

« back to all changes in this revision

Viewing changes to nslcd/group.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
   group.c - group entry lookup routines
3
 
   Parts of this file were part of the nss_ldap library (as ldap-grp.c) which
4
 
   has been forked into the nss-pam-ldapd library.
 
3
   Parts of this file were part of the nss_ldap library (as ldap-grp.c)
 
4
   which has been forked into the nss-pam-ldapd library.
5
5
 
6
6
   Copyright (C) 1997-2006 Luke Howard
7
7
   Copyright (C) 2006 West Consulting
8
 
   Copyright (C) 2006, 2007, 2008, 2009, 2010 Arthur de Jong
 
8
   Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Arthur de Jong
9
9
 
10
10
   This library is free software; you can redistribute it and/or
11
11
   modify it under the terms of the GNU Lesser General Public
37
37
#include "myldap.h"
38
38
#include "cfg.h"
39
39
#include "attmap.h"
 
40
#include "compat/strndup.h"
40
41
 
41
42
/* ( nisSchema.2.2 NAME 'posixGroup' SUP top STRUCTURAL
42
43
 *   DESC 'Abstraction of a group of accounts'
43
44
 *   MUST ( cn $ gidNumber )
44
45
 *   MAY ( userPassword $ memberUid $ description ) )
45
46
 *
46
 
 * apart from that the above the uniqueMember attributes may be
47
 
 * supported in a coming release (they map to DNs, which is an extra
48
 
 * lookup step)
 
47
 * apart from the above a member attribute is also supported that
 
48
 * may contains a DN of a user
49
49
 *
50
 
 * using nested groups (groups that are member of a group) is currently
51
 
 * not supported, this may be added in a later release
 
50
 * nested groups (groups that are member of a group) are currently
 
51
 * not supported
52
52
 */
53
53
 
54
54
/* the search base for searches */
62
62
 
63
63
/* the attributes to request with searches */
64
64
const char *attmap_group_cn            = "cn";
65
 
const char *attmap_group_userPassword  = "userPassword";
 
65
const char *attmap_group_userPassword  = "\"*\"";
66
66
const char *attmap_group_gidNumber     = "gidNumber";
67
67
const char *attmap_group_memberUid     = "memberUid";
68
 
const char *attmap_group_uniqueMember  = "uniqueMember";
 
68
const char *attmap_group_member        = "member";
 
69
 
 
70
/* special property for objectSid-based searches
 
71
   (these are already LDAP-escaped strings) */
 
72
static char *gidSid=NULL;
69
73
 
70
74
/* default values for attributes */
71
75
static const char *default_group_userPassword     = "*"; /* unmatchable */
72
76
 
73
 
 
74
77
/* the attribute list to request with searches */
75
 
static const char *group_attrs[6];
 
78
static const char **group_attrs=NULL;
76
79
 
77
80
/* create a search filter for searching a group entry
78
81
   by name, return -1 on errors */
95
98
static int mkfilter_group_bygid(gid_t gid,
96
99
                                char *buffer,size_t buflen)
97
100
{
98
 
  return mysnprintf(buffer,buflen,
99
 
                    "(&%s(%s=%d))",
100
 
                    group_filter,
101
 
                    attmap_group_gidNumber,(int)gid);
 
101
  if (gidSid!=NULL)
 
102
  {
 
103
    return mysnprintf(buffer,buflen,
 
104
                      "(&%s(%s=%s\\%02x\\%02x\\%02x\\%02x))",
 
105
                      group_filter,
 
106
                      attmap_group_gidNumber,gidSid,
 
107
                      (int)(gid&0xff),(int)((gid>>8)&0xff),
 
108
                      (int)((gid>>16)&0xff),(int)((gid>>24)&0xff));
 
109
  }
 
110
  else
 
111
  {
 
112
    return mysnprintf(buffer,buflen,
 
113
                      "(&%s(%s=%d))",
 
114
                      group_filter,
 
115
                      attmap_group_gidNumber,(int)gid);
 
116
  }
102
117
}
103
118
 
104
119
/* create a search filter for searching a group entry
127
142
                    "(&%s(|(%s=%s)(%s=%s)))",
128
143
                    group_filter,
129
144
                    attmap_group_memberUid,safeuid,
130
 
                    attmap_group_uniqueMember,safedn);
 
145
                    attmap_group_member,safedn);
131
146
}
132
147
 
133
148
void group_init(void)
134
149
{
135
150
  int i;
 
151
  SET *set;
136
152
  /* set up search bases */
137
153
  if (group_bases[0]==NULL)
138
154
    for (i=0;i<NSS_LDAP_CONFIG_MAX_BASES;i++)
140
156
  /* set up scope */
141
157
  if (group_scope==LDAP_SCOPE_DEFAULT)
142
158
    group_scope=nslcd_cfg->ldc_scope;
 
159
  /* special case when gidNumber references objectSid */
 
160
  if (strncasecmp(attmap_group_gidNumber,"objectSid:",10)==0)
 
161
  {
 
162
    gidSid=sid2search(attmap_group_gidNumber+10);
 
163
    attmap_group_gidNumber=strndup(attmap_group_gidNumber,9);
 
164
  }
143
165
  /* set up attribute list */
144
 
  group_attrs[0]=attmap_group_cn;
145
 
  group_attrs[1]=attmap_group_userPassword;
146
 
  group_attrs[2]=attmap_group_memberUid;
147
 
  group_attrs[3]=attmap_group_gidNumber;
148
 
  group_attrs[4]=attmap_group_uniqueMember;
149
 
  group_attrs[5]=NULL;
 
166
  set=set_new();
 
167
  attmap_add_attributes(set,attmap_group_cn);
 
168
  attmap_add_attributes(set,attmap_group_userPassword);
 
169
  attmap_add_attributes(set,attmap_group_memberUid);
 
170
  attmap_add_attributes(set,attmap_group_gidNumber);
 
171
  attmap_add_attributes(set,attmap_group_member);
 
172
  group_attrs=set_tolist(set);
 
173
  set_free(set);
150
174
}
151
175
 
152
176
static int do_write_group(
160
184
  {
161
185
    if (!isvalidname(names[i]))
162
186
    {
163
 
      log_log(LOG_WARNING,"group entry %s contains invalid group name: \"%s\"",
 
187
      log_log(LOG_WARNING,"group entry %s name denied by validnames option: \"%s\"",
164
188
                          myldap_get_dn(entry),names[i]);
165
189
    }
166
190
    else if ((reqname==NULL)||(strcmp(reqname,names[i])==0))
181
205
/* return the list of members */
182
206
static const char **getmembers(MYLDAP_ENTRY *entry,MYLDAP_SESSION *session)
183
207
{
184
 
  char buf[20];
 
208
  char buf[256];
185
209
  int i;
186
210
  const char **values;
187
211
  SET *set;
197
221
      if (isvalidname(values[i]))
198
222
        set_add(set,values[i]);
199
223
    }
200
 
  /* add the uniqueMember values */
201
 
  values=myldap_get_values(entry,attmap_group_uniqueMember);
 
224
  /* add the member values */
 
225
  values=myldap_get_values(entry,attmap_group_member);
202
226
  if (values!=NULL)
203
227
    for (i=0;values[i]!=NULL;i++)
204
228
    {
225
249
  gid_t gids[MAXGIDS_PER_ENTRY];
226
250
  int numgids;
227
251
  char *tmp;
 
252
  char passbuffer[64];
228
253
  int rc;
229
254
  /* get group name (cn) */
230
255
  names=myldap_get_values(entry,attmap_group_cn);
242
267
  }
243
268
  else
244
269
  {
245
 
    gidvalues=myldap_get_values(entry,attmap_group_gidNumber);
 
270
    gidvalues=myldap_get_values_len(entry,attmap_group_gidNumber);
246
271
    if ((gidvalues==NULL)||(gidvalues[0]==NULL))
247
272
    {
248
273
      log_log(LOG_WARNING,"group entry %s does not contain %s value",
249
274
                          myldap_get_dn(entry),attmap_group_gidNumber);
250
275
      return 0;
251
276
    }
252
 
    for (numgids=0;(gidvalues[numgids]!=NULL)&&(numgids<MAXGIDS_PER_ENTRY);numgids++)
 
277
    for (numgids=0;(numgids<MAXGIDS_PER_ENTRY)&&(gidvalues[numgids]!=NULL);numgids++)
253
278
    {
254
 
      gids[numgids]=(gid_t)strtol(gidvalues[numgids],&tmp,0);
255
 
      if ((*(gidvalues[numgids])=='\0')||(*tmp!='\0'))
 
279
      if (gidSid!=NULL)
 
280
        gids[numgids]=(gid_t)binsid2id(gidvalues[numgids]);
 
281
      else
256
282
      {
257
 
        log_log(LOG_WARNING,"group entry %s contains non-numeric %s value",
258
 
                            myldap_get_dn(entry),attmap_group_gidNumber);
259
 
        return 0;
 
283
        errno=0;
 
284
        gids[numgids]=strtogid(gidvalues[numgids],&tmp,0);
 
285
        if ((*(gidvalues[numgids])=='\0')||(*tmp!='\0'))
 
286
        {
 
287
          log_log(LOG_WARNING,"group entry %s contains non-numeric %s value",
 
288
                              myldap_get_dn(entry),attmap_group_gidNumber);
 
289
          return 0;
 
290
        }
 
291
        else if (errno!=0)
 
292
        {
 
293
          log_log(LOG_WARNING,"group entry %s contains too large %s value",
 
294
                              myldap_get_dn(entry),attmap_group_gidNumber);
 
295
          return 0;
 
296
        }
260
297
      }
261
298
    }
262
299
  }
263
300
  /* get group passwd (userPassword) (use only first entry) */
264
 
  passwd=get_userpassword(entry,attmap_group_userPassword);
 
301
  passwd=get_userpassword(entry,attmap_group_userPassword,passbuffer,sizeof(passbuffer));
265
302
  if (passwd==NULL)
266
303
    passwd=default_group_userPassword;
267
 
  /* get group memebers (memberUid&uniqueMember) */
 
304
  /* get group memebers (memberUid&member) */
268
305
  if (wantmembers)
269
306
    members=getmembers(entry,session);
270
307
  else
283
320
  char name[256];
284
321
  char filter[1024];
285
322
  READ_STRING(fp,name);
 
323
  log_setrequest("group=\"%s\"",name);
286
324
  if (!isvalidname(name)) {
287
 
    log_log(LOG_WARNING,"nslcd_group_byname(%s): invalid group name",name);
 
325
    log_log(LOG_WARNING,"\"%s\": name denied by validnames option",name);
288
326
    return -1;
289
327
  },
290
 
  log_log(LOG_DEBUG,"nslcd_group_byname(%s)",name);,
291
328
  NSLCD_ACTION_GROUP_BYNAME,
292
329
  mkfilter_group_byname(name,filter,sizeof(filter)),
293
330
  write_group(fp,entry,name,NULL,1,session)
297
334
  group,bygid,
298
335
  gid_t gid;
299
336
  char filter[1024];
300
 
  READ_TYPE(fp,gid,gid_t);,
301
 
  log_log(LOG_DEBUG,"nslcd_group_bygid(%d)",(int)gid);,
 
337
  READ_TYPE(fp,gid,gid_t);
 
338
  log_setrequest("group=%d",(int)gid);,
302
339
  NSLCD_ACTION_GROUP_BYGID,
303
340
  mkfilter_group_bygid(gid,filter,sizeof(filter)),
304
341
  write_group(fp,entry,NULL,&gid,1,session)
309
346
  char name[256];
310
347
  char filter[1024];
311
348
  READ_STRING(fp,name);
312
 
  if (!isvalidname(name)) {
313
 
    log_log(LOG_WARNING,"nslcd_group_bymember(%s): invalid user name",name);
 
349
  log_setrequest("group/member=\"%s\"",name);
 
350
  if (!isvalidname(name))
 
351
  {
 
352
    log_log(LOG_WARNING,"\"%s\": name denied by validnames option",name);
314
353
    return -1;
315
354
  }
316
355
  if ((nslcd_cfg->ldc_nss_initgroups_ignoreusers!=NULL)&&
317
356
      set_contains(nslcd_cfg->ldc_nss_initgroups_ignoreusers,name))
318
357
  {
 
358
    log_log(LOG_DEBUG,"ignored group member");
319
359
    /* just end the request, returning no results */
320
360
    WRITE_INT32(fp,NSLCD_VERSION);
321
361
    WRITE_INT32(fp,NSLCD_ACTION_GROUP_BYMEMBER);
322
362
    WRITE_INT32(fp,NSLCD_RESULT_END);
323
363
    return 0;
324
364
  },
325
 
  log_log(LOG_DEBUG,"nslcd_group_bymember(%s)",name);,
326
365
  NSLCD_ACTION_GROUP_BYMEMBER,
327
366
  mkfilter_group_bymember(session,name,filter,sizeof(filter)),
328
367
  write_group(fp,entry,NULL,NULL,0,session)
331
370
NSLCD_HANDLE(
332
371
  group,all,
333
372
  const char *filter;
334
 
  /* no parameters to read */,
335
 
  log_log(LOG_DEBUG,"nslcd_group_all()");,
 
373
  log_setrequest("group(all)");,
336
374
  NSLCD_ACTION_GROUP_ALL,
337
375
  (filter=group_filter,0),
338
376
  write_group(fp,entry,NULL,NULL,1,session)