Hi,
I have noticed that sssd does not trim whitespaces from strings while
parsing netgroup triples. Comment inside code explains that it follow
the nss_ldap implementation:

src/db/sysdb_search.c:
1687 /* This function splits a three-tuple into three strings
1688  * It assumes that any whitespace between the parentheses
1689  * and commas are intentional and does not attempt to
1690  * strip them out. Leading and trailing whitespace is
1691  * ignored.
1692  *
1693  * This behavior is compatible with nss_ldap's
1694  * implementation.
1695  */
1696 static errno_t sysdb_netgr_split_triple(TALLOC_CTX *mem_ctx,

Don't know which nss_ldap implementation is referenced, the one from
PADL trim the spaces (and glibc too):

https://github.com/PADL/nss_ldap/blob/154730b5a2b58a4212e419b498476fcb5
a60de7b/ldap-netgrp.c#L251

Is the difference intended?

I run into it when LDAP server returns some of the host strings with
spaces around which works with nss_ldap form PADL, but not with sssd.

Fix is easy, but I'm afraid that it could break some other corner cases
like netgroup rules for users with leading/trailing whitespaces in
username.

What's your opinion on it?
Thanks
Index: sssd-1.13.4/src/db/sysdb_search.c
===================================================================
--- sssd-1.13.4.orig/src/db/sysdb_search.c
+++ sssd-1.13.4/src/db/sysdb_search.c
@@ -1301,10 +1301,54 @@ done:
     return ret;
 }
 
+
+/* Get string until the first delimiter and strip out
+ * leading and trailing whitespaces.
+ */
+static errno_t sysdb_netgr_split_triple_string(TALLOC_CTX *mem_ctx,
+                                               const char **in,
+                                               const char delimiter,
+                                               char **out)
+{
+    size_t len;
+    const char *p = *in;
+    const char *begin;
+
+    /* Remove any leading whitespace */
+    while (*p && isspace(*p)) p++;
+    begin = p;
+
+    /* Find the delimiter */
+    while (*p && *p != delimiter) p++;
+
+    if (!*p) {
+        /* No delimiter was found: parse error */
+        return EINVAL;
+    }
+
+    len = p - begin;
+    /* Remove trailing spaces */
+    while (len > 0 && isspace(begin[len - 1])) len--;
+
+    *out = NULL;
+    if (len > 0) {
+        /* Copy the output string */
+        *out = talloc_strndup(mem_ctx, begin, len);
+        if (!*out) {
+            return ENOMEM;
+        }
+    }
+    p++;
+
+    *in = p;
+    return EOK;
+}
+
+
+
 /* This function splits a three-tuple into three strings
- * It assumes that any whitespace between the parentheses
- * and commas are intentional and does not attempt to
- * strip them out. Leading and trailing whitespace is
+ * It strips out any whitespace between the parentheses
+ * and commas. Leading and trailing whitespace is
  * ignored.
  *
  * This behavior is compatible with nss_ldap's
@@ -1349,72 +1393,22 @@ static errno_t sysdb_netgr_split_triple(
         goto done;
     }
     p++;
-    p_host = p;
-
-    /* Find the first comma */
-    while (*p && *p != ',') p++;
 
-    if (!*p) {
-        /* No comma was found: parse error */
-        ret = EINVAL;
+    ret = sysdb_netgr_split_triple_string(tmp_ctx, &p, ',', &host);
+    if (ret != EOK) {
         goto done;
     }
 
-    len = p - p_host;
-
-    if (len > 0) {
-        /* Copy the host string */
-        host = talloc_strndup(tmp_ctx, p_host, len);
-        if (!host) {
-            ret = ENOMEM;
-            goto done;
-        }
-    }
-    p++;
-    p_user = p;
-
-    /* Find the second comma */
-    while (*p && *p != ',') p++;
-
-    if (!*p) {
-        /* No comma was found: parse error */
-        ret = EINVAL;
+    ret = sysdb_netgr_split_triple_string(tmp_ctx, &p, ',', &user);
+    if (ret != EOK) {
         goto done;
     }
 
-    len = p - p_user;
-
-    if (len > 0) {
-        /* Copy the user string */
-        user = talloc_strndup(tmp_ctx, p_user, len);
-        if (!user) {
-            ret = ENOMEM;
-            goto done;
-        }
-    }
-    p++;
-    p_domain = p;
-
-    /* Find the closing parenthesis */
-    while (*p && *p != ')') p++;
-    if (*p != ')') {
-        /* No trailing parenthesis: parse error */
-        ret = EINVAL;
+    ret = sysdb_netgr_split_triple_string(tmp_ctx, &p, ')', &domain);
+    if (ret != EOK) {
         goto done;
     }
 
-    len = p - p_domain;
-
-    if (len > 0) {
-        /* Copy the domain string */
-        domain = talloc_strndup(tmp_ctx, p_domain, len);
-        if (!domain) {
-            ret = ENOMEM;
-            goto done;
-        }
-    }
-    p++;
-
     /* skip trailing whitespace */
     while (*p && isspace(*p)) p++;
 
_______________________________________________
sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org
To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org

Reply via email to