lists.arthurdejong.org
RSS feed

nss-pam-ldapd branch master updated. 0.9.13-5-gd8bc607

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

nss-pam-ldapd branch master updated. 0.9.13-5-gd8bc607



This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "nss-pam-ldapd".

The branch, master has been updated
       via  d8bc6073c090990e59d8b1f9968109a9d0b1150e (commit)
       via  f02fba85150ca5f17a2f5dc5d5691eb6977c5aef (commit)
       via  c1720c5432d25350444f08c222eb7e8e0811205a (commit)
      from  76abe053e4d02b691538ab97161ecaca4ede54ea (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://arthurdejong.org/git/nss-pam-ldapd/commit/?id=d8bc6073c090990e59d8b1f9968109a9d0b1150e

commit d8bc6073c090990e59d8b1f9968109a9d0b1150e
Author: Arthur de Jong <arthur@arthurdejong.org>
Date:   Tue Aug 4 23:00:59 2026 +0200

    Ensure myldap_get_values_bin() returns large enough values
    
    This ensurs that myldap_get_values_bin() for each entry will at least
    return a buffer of 68 bytes per entry. This is needed to ensure that the
    binsid2id() function can assume the buffer always at least has this size
    to avoid and out-of-bounds read when the LDAP server returns an invalid
    binary SID value.
    
    Fixes https://github.com/arthurdejong/nss-pam-ldapd/issues/85

diff --git a/nslcd/myldap.c b/nslcd/myldap.c
index 3388eb0..3e0ee92 100644
--- a/nslcd/myldap.c
+++ b/nslcd/myldap.c
@@ -5,7 +5,7 @@
 
    Copyright (C) 1997-2006 Luke Howard
    Copyright (C) 2006-2007 West Consulting
-   Copyright (C) 2006-2020 Arthur de Jong
+   Copyright (C) 2006-2026 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
@@ -1960,20 +1960,29 @@ const char **myldap_get_values(MYLDAP_ENTRY *entry, 
const char *attr)
   return NULL;
 }
 
+/* Minimum buffer size to allocate for myldap_get_values_bin() returned entries
+   (this is required for the binsid2id() function) */
+#define GET_VALUES_BIN_MIN_SIZE 68
+
 /* 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;
+  size_t sz, l;
   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;
+  {
+    l = bvalues[i]->bv_len;
+    if (l < GET_VALUES_BIN_MIN_SIZE)
+      l = GET_VALUES_BIN_MIN_SIZE;
+    sz += l + 1;
+  }
   /* allocate the needed memory */
   values = (char **)malloc(sz);
   if (values == NULL)
@@ -1988,8 +1997,11 @@ static const char **bervalues_to_values(struct berval 
**bvalues)
   {
     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;
+    l = bvalues[i]->bv_len;
+    if (l < GET_VALUES_BIN_MIN_SIZE)
+      l = GET_VALUES_BIN_MIN_SIZE;
+    memset(values[i] + bvalues[i]->bv_len, 0, l + 1 - bvalues[i]->bv_len);
+    buf += l + 1;
   }
   values[i] = NULL;
   return (const char **)values;

https://arthurdejong.org/git/nss-pam-ldapd/commit/?id=f02fba85150ca5f17a2f5dc5d5691eb6977c5aef

commit f02fba85150ca5f17a2f5dc5d5691eb6977c5aef
Author: Arthur de Jong <arthur@arthurdejong.org>
Date:   Tue Aug 4 22:28:31 2026 +0200

    Rename myldap_get_values_len() to myldap_get_values_bin()

diff --git a/nslcd/group.c b/nslcd/group.c
index 11317f2..8a3de94 100644
--- a/nslcd/group.c
+++ b/nslcd/group.c
@@ -347,7 +347,7 @@ static int write_group(TFILE *fp, MYLDAP_ENTRY *entry, 
const char *reqname,
   }
   else
   {
-    gidvalues = myldap_get_values_len(entry, attmap_group_gidNumber);
+    gidvalues = myldap_get_values_bin(entry, attmap_group_gidNumber);
     if ((gidvalues == NULL) || (gidvalues[0] == NULL))
     {
       log_log(LOG_WARNING, "%s: %s: missing",
diff --git a/nslcd/myldap.c b/nslcd/myldap.c
index 43a46cb..3388eb0 100644
--- a/nslcd/myldap.c
+++ b/nslcd/myldap.c
@@ -1995,8 +1995,8 @@ static const char **bervalues_to_values(struct berval 
**bvalues)
   return (const char **)values;
 }
 
-/* Simple wrapper around ldap_get_values(). */
-const char **myldap_get_values_len(MYLDAP_ENTRY *entry, const char *attr)
+/* Simple wrapper around ldap_get_values_len(). */
+const char **myldap_get_values_bin(MYLDAP_ENTRY *entry, const char *attr)
 {
   const char **values;
   struct berval **bvalues;
@@ -2005,13 +2005,13 @@ const char **myldap_get_values_len(MYLDAP_ENTRY *entry, 
const char *attr)
   /* check parameters */
   if (!is_valid_entry(entry))
   {
-    log_log(LOG_ERR, "myldap_get_values_len(): invalid result entry passed");
+    log_log(LOG_ERR, "myldap_get_values_bin(): invalid result entry passed");
     errno = EINVAL;
     return NULL;
   }
   else if (attr == NULL)
   {
-    log_log(LOG_ERR, "myldap_get_values_len(): invalid attribute name passed");
+    log_log(LOG_ERR, "myldap_get_values_bin(): invalid attribute name passed");
     errno = EINVAL;
     return NULL;
   }
@@ -2040,7 +2040,7 @@ const char **myldap_get_values_len(MYLDAP_ENTRY *entry, 
const char *attr)
     else
     {
       myldap_err(LOG_WARNING, entry->search->session->ld, rc,
-                 "myldap_get_values_len() of attribute \"%s\" on entry \"%s\" 
returned NULL",
+                 "myldap_get_values_bin() of attribute \"%s\" on entry \"%s\" 
returned NULL",
                  attr, myldap_get_dn(entry));
       return NULL;
     }
@@ -2061,7 +2061,7 @@ const char **myldap_get_values_len(MYLDAP_ENTRY *entry, 
const char *attr)
       return values;
     }
   /* we found no room to store the values */
-  log_log(LOG_ERR, "myldap_get_values_len() couldn't store results, increase 
MAX_BUFFERS_PER_ENTRY");
+  log_log(LOG_ERR, "myldap_get_values_bin() couldn't store results, increase 
MAX_BUFFERS_PER_ENTRY");
   free(values);
   return NULL;
 }
diff --git a/nslcd/myldap.h b/nslcd/myldap.h
index 32b4b07..5b8fc3a 100644
--- a/nslcd/myldap.h
+++ b/nslcd/myldap.h
@@ -2,7 +2,7 @@
    myldap.h - simple interface to do LDAP requests
    This file is part of the nss-pam-ldapd library.
 
-   Copyright (C) 2007-2017 Arthur de Jong
+   Copyright (C) 2007-2026 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
@@ -123,8 +123,9 @@ char *myldap_cpy_dn(MYLDAP_ENTRY *entry, char *buf, size_t 
buflen);
 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);
+   May return NULL or an empty array. This function is meant to be used
+   with binary values. */
+MUST_USE const char **myldap_get_values_bin(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);
diff --git a/nslcd/passwd.c b/nslcd/passwd.c
index 92d60de..19d5ec0 100644
--- a/nslcd/passwd.c
+++ b/nslcd/passwd.c
@@ -177,7 +177,7 @@ static int entry_has_valid_uid(MYLDAP_ENTRY *entry)
   if (nslcd_cfg->nss_min_uid == 0)
     return 1;
   /* get all uidNumber attributes */
-  values = myldap_get_values_len(entry, attmap_passwd_uidNumber);
+  values = myldap_get_values_bin(entry, attmap_passwd_uidNumber);
   if ((values == NULL) || (values[0] == NULL))
   {
     log_log(LOG_WARNING, "%s: %s: missing",
@@ -465,7 +465,7 @@ static int write_passwd(TFILE *fp, MYLDAP_ENTRY *entry, 
const char *requser,
   }
   else
   {
-    tmpvalues = myldap_get_values_len(entry, attmap_passwd_uidNumber);
+    tmpvalues = myldap_get_values_bin(entry, attmap_passwd_uidNumber);
     if ((tmpvalues == NULL) || (tmpvalues[0] == NULL))
     {
       log_log(LOG_WARNING, "%s: %s: missing",
@@ -504,7 +504,7 @@ static int write_passwd(TFILE *fp, MYLDAP_ENTRY *entry, 
const char *requser,
   /* get the gid for this entry */
   if (gidSid != NULL)
   {
-    tmpvalues = myldap_get_values_len(entry, attmap_passwd_gidNumber);
+    tmpvalues = myldap_get_values_bin(entry, attmap_passwd_gidNumber);
     if ((tmpvalues == NULL) || (tmpvalues[0] == NULL))
     {
       log_log(LOG_WARNING, "%s: %s: missing",

https://arthurdejong.org/git/nss-pam-ldapd/commit/?id=c1720c5432d25350444f08c222eb7e8e0811205a

commit c1720c5432d25350444f08c222eb7e8e0811205a
Author: Arthur de Jong <arthur@arthurdejong.org>
Date:   Sun Aug 2 23:58:49 2026 +0200

    Limit the number of sub-authorities to parse from a SID
    
    See https://github.com/arthurdejong/nss-pam-ldapd/issues/85

diff --git a/nslcd/common.c b/nslcd/common.c
index 567d402..6083852 100644
--- a/nslcd/common.c
+++ b/nslcd/common.c
@@ -3,7 +3,7 @@
    This file is part of the nss-pam-ldapd library.
 
    Copyright (C) 2006 West Consulting
-   Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Arthur de Jong
+   Copyright (C) 2006-2026 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
@@ -327,9 +327,19 @@ char *sid2search(const char *sid)
 /* return the last security identifier of the binary sid */
 unsigned long int binsid2id(const char *binsid)
 {
-  int i;
+  unsigned int n, i;
+  /*
+     The SID consists of (so total max 68 bytes):
+     - 1 byte: revision
+     - 1 byte: number of sub-authorities (N) (max 15, but usually much less)
+     - 6 bytes: authority ID
+     - N * 4 bytes: sub-authority ID
+  */
+  n = ((unsigned int)binsid[1]) & 0xff;
+  if (n > 15)
+    return 65534;  /* nobody / nogroup */
   /* find the position of the last security id */
-  i = 2 + 6 + ((((unsigned int)binsid[1]) & 0xff) - 1) * 4;
+  i = 2 + 6 + (n - 1) * 4;
   return (((unsigned long int)binsid[i]) & 0xff) |
          ((((unsigned long int)binsid[i + 1]) & 0xff) << 8) |
          ((((unsigned long int)binsid[i + 2]) & 0xff) << 16) |

-----------------------------------------------------------------------

Summary of changes:
 nslcd/common.c | 16 +++++++++++++---
 nslcd/group.c  |  2 +-
 nslcd/myldap.c | 34 +++++++++++++++++++++++-----------
 nslcd/myldap.h |  7 ++++---
 nslcd/passwd.c |  6 +++---
 5 files changed, 44 insertions(+), 21 deletions(-)


hooks/post-receive
-- 
nss-pam-ldapd