lists.arthurdejong.org
RSS feed

nss-pam-ldapd commit: r1485 - nss-pam-ldapd/nslcd

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

nss-pam-ldapd commit: r1485 - nss-pam-ldapd/nslcd



Author: arthur
Date: Fri Aug  5 13:52:37 2011
New Revision: 1485
URL: http://arthurdejong.org/viewvc/nss-pam-ldapd?view=rev&revision=1485

Log:
implementation of myldap_get_values_len() to use ldap_get_values_len() instead 
of ldap_get_values() to fix some problems with binary data in returned 
attribute values (patch by Wesley Mason)

Modified:
   nss-pam-ldapd/nslcd/group.c
   nss-pam-ldapd/nslcd/myldap.c
   nss-pam-ldapd/nslcd/myldap.h
   nss-pam-ldapd/nslcd/passwd.c

Modified: nss-pam-ldapd/nslcd/group.c
==============================================================================
--- nss-pam-ldapd/nslcd/group.c Wed Aug  3 21:54:53 2011        (r1484)
+++ nss-pam-ldapd/nslcd/group.c Fri Aug  5 13:52:37 2011        (r1485)
@@ -267,7 +267,7 @@
   }
   else
   {
-    gidvalues=myldap_get_values(entry,attmap_group_gidNumber);
+    gidvalues=myldap_get_values_len(entry,attmap_group_gidNumber);
     if ((gidvalues==NULL)||(gidvalues[0]==NULL))
     {
       log_log(LOG_WARNING,"group entry %s does not contain %s value",

Modified: nss-pam-ldapd/nslcd/myldap.c
==============================================================================
--- nss-pam-ldapd/nslcd/myldap.c        Wed Aug  3 21:54:53 2011        (r1484)
+++ nss-pam-ldapd/nslcd/myldap.c        Fri Aug  5 13:52:37 2011        (r1485)
@@ -130,7 +130,7 @@
 
 /* The maximum number of ranged attribute values that may be stoted
    per entry. */
-#define MAX_RANGED_ATTRIBUTES_PER_ENTRY 2
+#define MAX_RANGED_ATTRIBUTES_PER_ENTRY 8
 
 /* A single entry from the LDAP database as returned by
    myldap_get_entry(). */
@@ -1430,6 +1430,109 @@
   return NULL;
 }
 
+/* Convert the bervalues to a simple list of strings that can be freed
+   with one call to free(). */
+static const char **bervalues_to_values(struct berval **bvalues)
+{
+  int num_values;
+  int i;
+  size_t sz;
+  char *buf;
+  char **values;
+  /* figure out how much memory to allocate */
+  num_values=ldap_count_values_len(bvalues);
+  sz=(num_values+1)*sizeof(char *);
+  for (i=0;i<num_values;i++)
+    sz+=bvalues[i]->bv_len+1;
+  /* allocate the needed memory */
+  buf=(char *)malloc(sz);
+  if (buf==NULL)
+  {
+    log_log(LOG_CRIT,"myldap_get_values_len(): malloc() failed to allocate 
memory");
+    ldap_value_free_len(bvalues);
+    return NULL;
+  }
+  values=(char **)buf;
+  buf+=(num_values+1)*sizeof(char *);
+  /* copy from bvalues */
+  for (i=0;i<num_values;i++)
+  {
+    values[i]=buf;
+    memcpy(values[i],bvalues[i]->bv_val,bvalues[i]->bv_len);
+    values[i][bvalues[i]->bv_len]='\0';
+    buf+=bvalues[i]->bv_len+1;
+  }
+  values[i]=NULL;
+  return (const char **)values;
+}
+
+/* Simple wrapper around ldap_get_values(). */
+const char **myldap_get_values_len(MYLDAP_ENTRY *entry,const char *attr)
+{
+  const char **values;
+  struct berval **bvalues;
+  int rc;
+  int i;
+  SET *set;
+  /* check parameters */
+  if (!is_valid_entry(entry))
+  {
+    log_log(LOG_ERR,"myldap_get_values_len(): invalid result entry passed");
+    errno=EINVAL;
+    return NULL;
+  }
+  else if (attr==NULL)
+  {
+    log_log(LOG_ERR,"myldap_get_values_len(): invalid attribute name passed");
+    errno=EINVAL;
+    return NULL;
+  }
+  if (!entry->search->valid)
+    return NULL; /* search has been stopped */
+  /* get from LDAP */
+  
bvalues=ldap_get_values_len(entry->search->session->ld,entry->search->msg,attr);
+  if (bvalues==NULL)
+  {
+    if 
(ldap_get_option(entry->search->session->ld,LDAP_OPT_ERROR_NUMBER,&rc)!=LDAP_SUCCESS)
+      rc=LDAP_UNAVAILABLE;
+    /* ignore decoding errors as they are just nonexisting attribute values */
+    if (rc==LDAP_DECODING_ERROR)
+    {
+      rc=LDAP_SUCCESS;
+      ldap_set_option(entry->search->session->ld,LDAP_OPT_ERROR_NUMBER,&rc);
+    }
+    else if (rc==LDAP_SUCCESS)
+    {
+      /* we have a success code but no values, let's try to get ranged
+         values */
+      set=myldap_get_ranged_values(entry,attr);
+      if (set==NULL)
+        return NULL;
+      values=set_tolist(set);
+    }
+    else
+      log_log(LOG_WARNING,"myldap_get_values_len() of attribute \"%s\" on 
entry \"%s\" returned NULL: %s",
+                          attr,myldap_get_dn(entry),ldap_err2string(rc));
+    return NULL;
+  }
+  else
+  {
+    values=bervalues_to_values(bvalues);
+    ldap_value_free_len(bvalues);
+  }
+  /* store values entry so we can free it later on */
+  for (i=0;i<MAX_RANGED_ATTRIBUTES_PER_ENTRY;i++)
+    if (entry->rangedattributevalues[i]==NULL)
+    {
+      entry->rangedattributevalues[i]=(char **)values;
+      return values;
+    }
+  /* we found no room to store the values */
+  log_log(LOG_ERR,"myldap_get_values_len() couldn't store results, increase 
MAX_RANGED_ATTRIBUTES_PER_ENTRY");
+  free(values);
+  return NULL;
+}
+
 /* Go over the entries in exploded_rdn and see if any start with
    the requested attribute. Return a reference to the value part of
    the DN (does not modify exploded_rdn). */

Modified: nss-pam-ldapd/nslcd/myldap.h
==============================================================================
--- nss-pam-ldapd/nslcd/myldap.h        Wed Aug  3 21:54:53 2011        (r1484)
+++ nss-pam-ldapd/nslcd/myldap.h        Fri Aug  5 13:52:37 2011        (r1485)
@@ -117,6 +117,10 @@
    May return NULL or an empty array. */
 MUST_USE const char **myldap_get_values(MYLDAP_ENTRY *entry,const char *attr);
 
+/* Get the attribute values from a certain entry as a NULL terminated list.
+   May return NULL or an empty array. */
+MUST_USE const char **myldap_get_values_len(MYLDAP_ENTRY *entry,const char 
*attr);
+
 /* Checks to see if the entry has the specified object class. */
 MUST_USE int myldap_has_objectclass(MYLDAP_ENTRY *entry,const char 
*objectclass);
 

Modified: nss-pam-ldapd/nslcd/passwd.c
==============================================================================
--- nss-pam-ldapd/nslcd/passwd.c        Wed Aug  3 21:54:53 2011        (r1484)
+++ nss-pam-ldapd/nslcd/passwd.c        Fri Aug  5 13:52:37 2011        (r1485)
@@ -179,7 +179,7 @@
   if (nslcd_cfg->ldc_nss_min_uid==0)
     return 1;
   /* get all uidNumber attributes */
-  values=myldap_get_values(entry,attmap_passwd_uidNumber);
+  values=myldap_get_values_len(entry,attmap_passwd_uidNumber);
   if ((values==NULL)||(values[0]==NULL))
   {
     log_log(LOG_WARNING,"passwd entry %s does not contain %s value",
@@ -425,7 +425,7 @@
   }
   else
   {
-    tmpvalues=myldap_get_values(entry,attmap_passwd_uidNumber);
+    tmpvalues=myldap_get_values_len(entry,attmap_passwd_uidNumber);
     if ((tmpvalues==NULL)||(tmpvalues[0]==NULL))
     {
       log_log(LOG_WARNING,"passwd entry %s does not contain %s value",
@@ -451,7 +451,7 @@
   /* get the gid for this entry */
   if (gidSid!=NULL)
   {
-    tmpvalues=myldap_get_values(entry,attmap_passwd_gidNumber);
+    tmpvalues=myldap_get_values_len(entry,attmap_passwd_gidNumber);
     if ((tmpvalues==NULL)||(tmpvalues[0]==NULL))
     {
       log_log(LOG_WARNING,"passwd entry %s does not contain %s value",
-- 
To unsubscribe send an email to
nss-pam-ldapd-commits-unsubscribe@lists.arthurdejong.org or see
http://lists.arthurdejong.org/nss-pam-ldapd-commits