lists.arthurdejong.org
RSS feed

nss-pam-ldapd commit: r1425 - in nss-pam-ldapd: man nslcd

[Date Prev][Date Next] [Thread Prev][Thread Next]

nss-pam-ldapd commit: r1425 - in nss-pam-ldapd: man nslcd



Author: arthur
Date: Fri Apr 15 23:16:33 2011
New Revision: 1425
URL: http://arthurdejong.org/viewvc/nss-pam-ldapd?view=rev&revision=1425

Log:
support using the objectSid attribute to provide numeric user and group ids, 
based on a patch by Wesley Mason

Modified:
   nss-pam-ldapd/man/nslcd.conf.5.xml
   nss-pam-ldapd/nslcd/common.c
   nss-pam-ldapd/nslcd/common.h
   nss-pam-ldapd/nslcd/group.c
   nss-pam-ldapd/nslcd/passwd.c

Modified: nss-pam-ldapd/man/nslcd.conf.5.xml
==============================================================================
--- nss-pam-ldapd/man/nslcd.conf.5.xml  Fri Apr 15 21:10:57 2011        (r1424)
+++ nss-pam-ldapd/man/nslcd.conf.5.xml  Fri Apr 15 23:16:33 2011        (r1425)
@@ -388,7 +388,7 @@
        the supported maps below.
        The <replaceable>ATTRIBUTE</replaceable> is the one as
        used in <acronym>RFC</acronym> 2307 (e.g. 
<literal>userPassword</literal>,
-       <literal>ipProtocolNumber</literal> or <literal>macAddress</literal>).
+       <literal>ipProtocolNumber</literal>, <literal>macAddress</literal>, 
etc.).
        The <replaceable>NEWATTRIBUTE</replaceable> may be any attribute
        as it is available in the directory.
       </para>
@@ -415,6 +415,13 @@
        <literal>shadowExpire</literal> and <literal>shadowFlag</literal>.
       </para>
       <para>
+       The <literal>uidNumber</literal> and <literal>gidNumber</literal>
+       attributes in the <literal>passwd</literal> and <literal>group</literal>
+       maps may be mapped to the <literal>objectSid</literal> followed by
+       the domain SID to derive numeric user and group ids from the SID
+       (e.g. 
<literal>objectSid:S-1-5-21-3623811015-3361044348-30300820</literal>).
+      </para>
+      <para>
        By default all <literal>userPassword</literal> attributes are mapped
        to the unmatchable password ("*") to avoid accidentally leaking
        password information.

Modified: nss-pam-ldapd/nslcd/common.c
==============================================================================
--- nss-pam-ldapd/nslcd/common.c        Fri Apr 15 21:10:57 2011        (r1424)
+++ nss-pam-ldapd/nslcd/common.c        Fri Apr 15 23:16:33 2011        (r1425)
@@ -34,6 +34,7 @@
 #include <netdb.h>
 #include <string.h>
 #include <regex.h>
+#include <stdlib.h>
 
 #include "nslcd.h"
 #include "common.h"
@@ -212,3 +213,59 @@
   /* we're done */
   return 0;
 }
+
+/* convert the provided string representation of a sid
+   (e.g. S-1-5-21-1936905831-823966427-12391542-23578)
+   to a format that can be used to search the objectSid property with */
+char *sid2search(const char *sid)
+{
+  const char *tmpsid=sid;
+  char *res,*tmp;
+  int i=0;
+  long int l;
+  /* check the beginning of the string */
+  if (strncasecmp(sid,"S-",2)!=0)
+  {
+    log_log(LOG_ERR,"error in SID %s",sid);
+    exit(EXIT_FAILURE);
+  }
+  /* count the number of dashes in the sid */
+  while (tmpsid!=NULL)
+  {
+    i++;
+    tmpsid=strchr(tmpsid+1,'-');
+  }
+  i-=2; /* number of security ids plus one because we add the uid later */
+  /* allocate memory */
+  res=malloc(3+3+6*3+i*4*3+1);
+  if (res==NULL)
+  {
+    log_log(LOG_CRIT,"malloc() failed to allocate memory");
+    exit(1);
+  }
+  /* build the first part */
+  l=strtol(sid+2,&tmp,10);
+  sprintf(res,"\\%02x\\%02x",(int)l&0xff,(int)i);
+  /* build authority part (we only handle 32 of the 48 bits) */
+  l=strtol(tmp+1,&tmp,10);
+  sprintf(res+strlen(res),"\\00\\00\\%02x\\%02x\\%02x\\%02x",
+          
(int)((l>>24)&0xff),(int)((l>>16)&0xff),(int)((l>>8)&0xff),(int)(l&0xff));
+  /* go over the rest of the bits */
+  while (*tmp!='\0')
+  {
+    l=strtol(tmp+1,&tmp,10);
+    sprintf(res+strlen(res),"\\%02x\\%02x\\%02x\\%02x",
+            
(int)(l&0xff),(int)((l>>8)&0xff),(int)((l>>16)&0xff),(int)((l>>24)&0xff));
+  }
+  return res;
+}
+
+/* return the last security identifier of the binary sid */
+long int binsid2id(const char *binsid)
+{
+  int i;
+  /* find the position of the last security id */
+  i=2+6+((((int)binsid[1])&0xff)-1)*4;
+  return (((long int)binsid[i])&0xff)|((((long int)binsid[i+1])&0xff)<<8)|
+         ((((long int)binsid[i+2])&0xff)<<16)|((((long 
int)binsid[i+3])&0xff)<<24);
+}

Modified: nss-pam-ldapd/nslcd/common.h
==============================================================================
--- nss-pam-ldapd/nslcd/common.h        Fri Apr 15 21:10:57 2011        (r1424)
+++ nss-pam-ldapd/nslcd/common.h        Fri Apr 15 23:16:33 2011        (r1425)
@@ -84,6 +84,14 @@
   if (read_address(fp,addr,&(len),&(af))) \
     return -1;
 
+/* convert the provided string representation of a sid
+   (e.g. S-1-5-21-1936905831-823966427-12391542-23578)
+   to a format that can be used to search the objectSid property with */
+MUST_USE char *sid2search(const char *sid);
+
+/* return the last security identifier of the binary sid */
+MUST_USE long int binsid2id(const char *binsid);
+
 /* checks to see if the specified string is a valid user or group name */
 MUST_USE int isvalidname(const char *name);
 

Modified: nss-pam-ldapd/nslcd/group.c
==============================================================================
--- nss-pam-ldapd/nslcd/group.c Fri Apr 15 21:10:57 2011        (r1424)
+++ nss-pam-ldapd/nslcd/group.c Fri Apr 15 23:16:33 2011        (r1425)
@@ -5,7 +5,7 @@
 
    Copyright (C) 1997-2006 Luke Howard
    Copyright (C) 2006 West Consulting
-   Copyright (C) 2006, 2007, 2008, 2009, 2010 Arthur de Jong
+   Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Arthur de Jong
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -66,6 +66,10 @@
 const char *attmap_group_memberUid     = "memberUid";
 const char *attmap_group_uniqueMember  = "uniqueMember";
 
+/* special property for objectSid-based searches
+   (these are already LDAP-escaped strings) */
+static char *gidSid=NULL;
+
 /* default values for attributes */
 static const char *default_group_userPassword     = "*"; /* unmatchable */
 
@@ -93,10 +97,22 @@
 static int mkfilter_group_bygid(gid_t gid,
                                 char *buffer,size_t buflen)
 {
-  return mysnprintf(buffer,buflen,
-                    "(&%s(%s=%d))",
-                    group_filter,
-                    attmap_group_gidNumber,(int)gid);
+  if (gidSid!=NULL)
+  {
+    return mysnprintf(buffer,buflen,
+                      "(&%s(%s=%s\\%02x\\%02x\\%02x\\%02x))",
+                      group_filter,
+                      attmap_group_gidNumber,gidSid,
+                      (int)(gid&0xff),(int)((gid>>8)&0xff),
+                      (int)((gid>>16)&0xff),(int)((gid>>24)&0xff));
+  }
+  else
+  {
+    return mysnprintf(buffer,buflen,
+                      "(&%s(%s=%d))",
+                      group_filter,
+                      attmap_group_gidNumber,(int)gid);
+  }
 }
 
 /* create a search filter for searching a group entry
@@ -139,6 +155,12 @@
   /* set up scope */
   if (group_scope==LDAP_SCOPE_DEFAULT)
     group_scope=nslcd_cfg->ldc_scope;
+  /* special case when gidNumber references objectSid */
+  if (strncasecmp(attmap_group_gidNumber,"objectSid:",10)==0)
+  {
+    gidSid=sid2search(attmap_group_gidNumber+10);
+    attmap_group_gidNumber=strndup(attmap_group_gidNumber,9);
+  }
   /* set up attribute list */
   set=set_new();
   attmap_add_attributes(set,attmap_group_cn);
@@ -253,12 +275,17 @@
     }
     for 
(numgids=0;(gidvalues[numgids]!=NULL)&&(numgids<MAXGIDS_PER_ENTRY);numgids++)
     {
-      gids[numgids]=(gid_t)strtol(gidvalues[numgids],&tmp,0);
-      if ((*(gidvalues[numgids])=='\0')||(*tmp!='\0'))
+      if (gidSid!=NULL)
+        gids[numgids]=(gid_t)binsid2id(gidvalues[numgids]);
+      else
       {
-        log_log(LOG_WARNING,"group entry %s contains non-numeric %s value",
-                            myldap_get_dn(entry),attmap_group_gidNumber);
-        return 0;
+        gids[numgids]=(gid_t)strtol(gidvalues[numgids],&tmp,0);
+        if ((*(gidvalues[numgids])=='\0')||(*tmp!='\0'))
+        {
+          log_log(LOG_WARNING,"group entry %s contains non-numeric %s value",
+                              myldap_get_dn(entry),attmap_group_gidNumber);
+          return 0;
+        }
       }
     }
   }

Modified: nss-pam-ldapd/nslcd/passwd.c
==============================================================================
--- nss-pam-ldapd/nslcd/passwd.c        Fri Apr 15 21:10:57 2011        (r1424)
+++ nss-pam-ldapd/nslcd/passwd.c        Fri Apr 15 23:16:33 2011        (r1425)
@@ -63,6 +63,11 @@
 const char *attmap_passwd_homeDirectory = "homeDirectory";
 const char *attmap_passwd_loginShell    = "loginShell";
 
+/* special properties for objectSid-based searches
+   (these are already LDAP-escaped strings) */
+static char *uidSid=NULL;
+static char *gidSid=NULL;
+
 /* default values for attributes */
 static const char *default_passwd_userPassword     = "*"; /* unmatchable */
 
@@ -97,10 +102,22 @@
 static int mkfilter_passwd_byuid(uid_t uid,
                                  char *buffer,size_t buflen)
 {
-  return mysnprintf(buffer,buflen,
-                    "(&%s(%s=%d))",
-                    passwd_filter,
-                    attmap_passwd_uidNumber,(int)uid);
+  if (uidSid!=NULL)
+  {
+    return mysnprintf(buffer,buflen,
+                      "(&%s(%s=%s\\%02x\\%02x\\%02x\\%02x))",
+                      passwd_filter,
+                      attmap_passwd_uidNumber,uidSid,
+                      (int)(uid&0xff),(int)((uid>>8)&0xff),
+                      (int)((uid>>16)&0xff),(int)((uid>>24)&0xff));
+  }
+  else
+  {
+    return mysnprintf(buffer,buflen,
+                      "(&%s(%s=%d))",
+                      passwd_filter,
+                      attmap_passwd_uidNumber,(int)uid);
+  }
 }
 
 void passwd_init(void)
@@ -114,6 +131,17 @@
   /* set up scope */
   if (passwd_scope==LDAP_SCOPE_DEFAULT)
     passwd_scope=nslcd_cfg->ldc_scope;
+  /* special case when uidNumber or gidNumber reference objectSid */
+  if (strncasecmp(attmap_passwd_uidNumber,"objectSid:",10)==0)
+  {
+    uidSid=sid2search(attmap_passwd_uidNumber+10);
+    attmap_passwd_uidNumber=strndup(attmap_passwd_uidNumber,9);
+  }
+  if (strncasecmp(attmap_passwd_gidNumber,"objectSid:",10)==0)
+  {
+    gidSid=sid2search(attmap_passwd_gidNumber+10);
+    attmap_passwd_gidNumber=strndup(attmap_passwd_gidNumber,9);
+  }
   /* set up attribute list */
   set=set_new();
   attmap_add_attributes(set,"objectClass"); /* for testing shadowAccount */
@@ -160,11 +188,19 @@
   /* check if there is a uidNumber attributes >= min_uid */
   for (i=0;values[i]!=NULL;i++)
   {
-    uid=(uid_t)strtol(values[i],&tmp,0);
-    if ((*(values[i])=='\0')||(*tmp!='\0'))
-      log_log(LOG_WARNING,"passwd entry %s contains non-numeric %s value",
-                          myldap_get_dn(entry),attmap_passwd_uidNumber);
-    else if (uid>=nslcd_cfg->ldc_nss_min_uid)
+    if (uidSid!=NULL)
+      uid=(uid_t)binsid2id(values[i]);
+    else
+    {
+      uid=(uid_t)strtol(values[i],&tmp,0);
+      if ((*(values[i])=='\0')||(*tmp!='\0'))
+      {
+        log_log(LOG_WARNING,"passwd entry %s contains non-numeric %s value",
+                            myldap_get_dn(entry),attmap_passwd_uidNumber);
+        continue;
+      }
+    }
+    if (uid>=nslcd_cfg->ldc_nss_min_uid)
       return 1;
   }
   /* nothing found */
@@ -397,29 +433,48 @@
     }
     for 
(numuids=0;(numuids<MAXUIDS_PER_ENTRY)&&(tmpvalues[numuids]!=NULL);numuids++)
     {
-      uids[numuids]=(uid_t)strtol(tmpvalues[numuids],&tmp,0);
-      if ((*(tmpvalues[numuids])=='\0')||(*tmp!='\0'))
+      if (uidSid!=NULL)
+        uids[numuids]=(uid_t)binsid2id(tmpvalues[numuids]);
+      else
       {
-        log_log(LOG_WARNING,"passwd entry %s contains non-numeric %s value",
-                            myldap_get_dn(entry),attmap_passwd_uidNumber);
-        return 0;
+        uids[numuids]=(uid_t)strtol(tmpvalues[numuids],&tmp,0);
+        if ((*(tmpvalues[numuids])=='\0')||(*tmp!='\0'))
+        {
+          log_log(LOG_WARNING,"passwd entry %s contains non-numeric %s value",
+                              myldap_get_dn(entry),attmap_passwd_uidNumber);
+          return 0;
+        }
       }
     }
   }
   /* get the gid for this entry */
-  attmap_get_value(entry,attmap_passwd_gidNumber,gidbuf,sizeof(gidbuf));
-  if (gidbuf[0]=='\0')
+  if (gidSid!=NULL)
   {
-    log_log(LOG_WARNING,"passwd entry %s does not contain %s value",
-                        myldap_get_dn(entry),attmap_passwd_gidNumber);
-    return 0;
+    tmpvalues=myldap_get_values(entry,attmap_passwd_gidNumber);
+    if ((tmpvalues==NULL)||(tmpvalues[0]==NULL))
+    {
+      log_log(LOG_WARNING,"passwd entry %s does not contain %s value",
+                          myldap_get_dn(entry),attmap_passwd_gidNumber);
+      return 0;
+    }
+    gid=(gid_t)binsid2id(tmpvalues[0]);
   }
-  gid=(gid_t)strtol(gidbuf,&tmp,0);
-  if ((gidbuf[0]=='\0')||(*tmp!='\0'))
+  else
   {
-    log_log(LOG_WARNING,"passwd entry %s contains non-numeric %s value",
-                        myldap_get_dn(entry),attmap_passwd_gidNumber);
-    return 0;
+    attmap_get_value(entry,attmap_passwd_gidNumber,gidbuf,sizeof(gidbuf));
+    if (gidbuf[0]=='\0')
+    {
+      log_log(LOG_WARNING,"passwd entry %s does not contain %s value",
+                          myldap_get_dn(entry),attmap_passwd_gidNumber);
+      return 0;
+    }
+    gid=(gid_t)strtol(gidbuf,&tmp,0);
+    if ((gidbuf[0]=='\0')||(*tmp!='\0'))
+    {
+      log_log(LOG_WARNING,"passwd entry %s contains non-numeric %s value",
+                          myldap_get_dn(entry),attmap_passwd_gidNumber);
+      return 0;
+    }
   }
   /* get the gecos for this entry */
   attmap_get_value(entry,attmap_passwd_gecos,gecos,sizeof(gecos));
-- 
To unsubscribe send an email to
nss-pam-ldapd-commits-unsubscribe@lists.arthurdejong.org or see
http://lists.arthurdejong.org/nss-pam-ldapd-commits