]> granicus.if.org Git - sudo/commitdiff
Use asprintf() to generate the netgroup filter instead of using
authorTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 12 Jan 2016 21:29:09 +0000 (14:29 -0700)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 12 Jan 2016 21:29:09 +0000 (14:29 -0700)
lots of concatenation.

plugins/sudoers/ldap.c

index 338991d59d893736e080561c0b65f3d514bacd18..f5f62c14a7a6846171a4a9ddf7d99f77742fef48 100644 (file)
@@ -1279,6 +1279,29 @@ done:
     return dlen + (s - src);   /* count does not include NUL */
 }
 
+/*
+ * Like strdup() but escapes characters as per RFC 4515.
+ */
+static char *
+sudo_ldap_value_dup(const char *src)
+{
+    char *dst;
+    size_t size;
+
+    size = sudo_ldap_value_len(src) + 1;
+    dst = malloc(size);
+    if (dst == NULL)
+       return NULL;
+
+    *dst = '\0';
+    if (sudo_ldap_value_cat(dst, src, size) >= size) {
+       /* Should not be possible... */
+       free(dst);
+       dst = NULL;
+    }
+    return dst;
+}
+
 /*
  * Check the netgroups list beginning at "start" for nesting.
  * Parent nodes with a memberNisNetgroup that match one of the
@@ -1378,9 +1401,9 @@ sudo_netgroup_lookup(LDAP *ld, struct passwd *pw,
     struct timeval tv, *tvp = NULL;
     LDAPMessage *entry, *result = NULL;
     const char *domain;
-    size_t filt_len;
-    char *filt;
-    int rc;
+    char *escaped_domain, *escaped_host, *escaped_shost, *escaped_user;
+    char *filt = NULL;
+    int filt_len, rc;
     debug_decl(sudo_netgroup_lookup, SUDOERS_DEBUG_LDAP);
 
     if (ldap_conf.timeout > 0) {
@@ -1392,86 +1415,34 @@ sudo_netgroup_lookup(LDAP *ld, struct passwd *pw,
     /* Use NIS domain if set, else wildcard match. */
     domain = sudo_getdomainname();
 
+    /* Escape the domain, host names, and user name per RFC 4515. */
+    escaped_domain = domain ? sudo_ldap_value_dup(domain) : NULL;
+    escaped_host = sudo_ldap_value_dup(user_runhost);
+    if (user_runhost == user_srunhost)
+       escaped_shost = escaped_host;
+    else 
+       escaped_shost = sudo_ldap_value_dup(user_srunhost);
+    escaped_user = sudo_ldap_value_dup(pw->pw_name);
+    if (escaped_domain == NULL || escaped_host == NULL ||
+       escaped_shost == NULL || escaped_user == NULL)
+       goto oom;
+
     /* Build query, using NIS domain if it is set. */
     if (domain != NULL) {
-       filt_len = sizeof("(nisNetgroupTriple=\\28,,\\29)") - 1 +
-           sudo_ldap_value_len(pw->pw_name);
-       if (user_runhost == user_srunhost) {
-           filt_len *= 4;
-           filt_len += 2 * sudo_ldap_value_len(user_srunhost);
-           filt_len += 2 * sudo_ldap_value_len(domain);
-       } else {
-           filt_len *= 6;
-           filt_len += 2 * sudo_ldap_value_len(user_srunhost);
-           filt_len += 2 * sudo_ldap_value_len(user_runhost);
-           filt_len += 3 * sudo_ldap_value_len(domain);
-       }
-       filt_len += 7 + strlen(ldap_conf.netgroup_search_filter);
-       if ((filt = malloc(filt_len)) == NULL)
-           goto oom;
-       CHECK_STRLCPY(filt, "(&", filt_len);
-       CHECK_STRLCAT(filt, ldap_conf.netgroup_search_filter, filt_len);
-       CHECK_STRLCAT(filt, "(|(nisNetgroupTriple=\\28,", filt_len);
-       CHECK_LDAP_VCAT(filt, pw->pw_name, filt_len);
-       CHECK_STRLCAT(filt, ",", filt_len);
-       CHECK_LDAP_VCAT(filt, domain, filt_len);
-       CHECK_STRLCAT(filt, "\\29)(nisNetgroupTriple=\\28", filt_len);
-       CHECK_LDAP_VCAT(filt, user_srunhost, filt_len);
-       CHECK_STRLCAT(filt, ",", filt_len);
-       CHECK_LDAP_VCAT(filt, pw->pw_name, filt_len);
-       if (user_runhost != user_srunhost) {
-           CHECK_STRLCAT(filt, ",", filt_len);
-           CHECK_LDAP_VCAT(filt, domain, filt_len);
-           CHECK_STRLCAT(filt, "\\29)(nisNetgroupTriple=\\28", filt_len);
-           CHECK_LDAP_VCAT(filt, user_runhost, filt_len);
-           CHECK_STRLCAT(filt, ",", filt_len);
-           CHECK_LDAP_VCAT(filt, pw->pw_name, filt_len);
-       }
-       CHECK_STRLCAT(filt, ",", filt_len);
-       CHECK_LDAP_VCAT(filt, domain, filt_len);
-       CHECK_STRLCAT(filt, "\\29)(nisNetgroupTriple=\\28,", filt_len);
-       CHECK_LDAP_VCAT(filt, pw->pw_name, filt_len);
-       CHECK_STRLCAT(filt, ",\\29)(nisNetgroupTriple=\\28", filt_len);
-       CHECK_LDAP_VCAT(filt, user_srunhost, filt_len);
-       CHECK_STRLCAT(filt, ",", filt_len);
-       CHECK_LDAP_VCAT(filt, pw->pw_name, filt_len);
        if (user_runhost != user_srunhost) {
-           CHECK_STRLCAT(filt, ",\\29)(nisNetgroupTriple=\\28", filt_len);
-           CHECK_LDAP_VCAT(filt, user_runhost, filt_len);
-           CHECK_STRLCAT(filt, ",", filt_len);
-           CHECK_LDAP_VCAT(filt, pw->pw_name, filt_len);
-       }
-       CHECK_STRLCAT(filt, ",\\29)))", filt_len);
-    } else {
-       filt_len = sizeof("(nisNetgroupTriple=\\28,,*\\29)") - 1 +
-           sudo_ldap_value_len(pw->pw_name);
-       if (user_runhost == user_srunhost) {
-           filt_len *= 2;
-           filt_len += sudo_ldap_value_len(user_srunhost);
+           filt_len = asprintf(&filt, "(&%s(|(nisNetgroupTriple=\\28,%s,%s\\29)(nisNetgroupTriple=\\28%s,%s,%s\\29)(nisNetgroupTriple=\\28%s,%s,%s\\29)(nisNetgroupTriple=\\28,%s,\\29)(nisNetgroupTriple=\\28%s,%s,\\29)(nisNetgroupTriple=\\28%s,%s,\\29)))", ldap_conf.netgroup_search_filter, escaped_user, escaped_domain, escaped_shost, escaped_user, escaped_domain, escaped_host, escaped_user, escaped_domain, escaped_user, escaped_shost, escaped_user, escaped_host, escaped_user);
        } else {
-           filt_len *= 3;
-           filt_len += sudo_ldap_value_len(user_srunhost);
-           filt_len += sudo_ldap_value_len(user_runhost);
+           filt_len = asprintf(&filt, "(&%s(|(nisNetgroupTriple=\\28,%s,%s\\29)(nisNetgroupTriple=\\28%s,%s,%s\\29)(nisNetgroupTriple=\\28,%s,\\29)(nisNetgroupTriple=\\28%s,%s,\\29)))", ldap_conf.netgroup_search_filter, escaped_user, escaped_domain, escaped_shost, escaped_user, escaped_domain, escaped_user, escaped_shost, escaped_user);
        }
-       filt_len += 7 + strlen(ldap_conf.netgroup_search_filter);
-       if ((filt = malloc(filt_len)) == NULL)
-           goto oom;
-       CHECK_STRLCPY(filt, "(&", filt_len);
-       CHECK_STRLCAT(filt, ldap_conf.netgroup_search_filter, filt_len);
-       CHECK_STRLCAT(filt, "(|(nisNetgroupTriple=\\28,", filt_len);
-       CHECK_LDAP_VCAT(filt, pw->pw_name, filt_len);
-       CHECK_STRLCAT(filt, ",*\\29)(nisNetgroupTriple=\\28", filt_len);
-       CHECK_LDAP_VCAT(filt, user_srunhost, filt_len);
-       CHECK_STRLCAT(filt, ",", filt_len);
-       CHECK_LDAP_VCAT(filt, pw->pw_name, filt_len);
+    } else {
        if (user_runhost != user_srunhost) {
-           CHECK_STRLCAT(filt, ",*\\29)(nisNetgroupTriple=\\28", filt_len);
-           CHECK_LDAP_VCAT(filt, user_runhost, filt_len);
-           CHECK_STRLCAT(filt, ",", filt_len);
-           CHECK_LDAP_VCAT(filt, pw->pw_name, filt_len);
+           filt_len = asprintf(&filt, "(&%s(|(nisNetgroupTriple=\\28,%s,*\\29)(nisNetgroupTriple=\\28%s,%s,*\\29)(nisNetgroupTriple=\\28%s,%s,*\\29)))", ldap_conf.netgroup_search_filter, escaped_user, escaped_shost, escaped_user, escaped_host, escaped_user);
+       } else {
+           filt_len = asprintf(&filt, "(&%s(|(nisNetgroupTriple=\\28,%s,*\\29)(nisNetgroupTriple=\\28%s,%s,*\\29)))", ldap_conf.netgroup_search_filter, escaped_user, escaped_shost, escaped_user);
        }
-       CHECK_STRLCAT(filt, ",*\\29)))", filt_len);
     }
+    if (filt_len == -1)
+       goto oom;
     DPRINTF1("ldap netgroup search filter: '%s'", filt);
 
     STAILQ_FOREACH(base, &ldap_conf.netgroup_base, entries) {
@@ -1525,13 +1496,14 @@ sudo_netgroup_lookup(LDAP *ld, struct passwd *pw,
     debug_return_bool(true);
 oom:
     sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+    free(escaped_domain);
+    free(escaped_host);
+    if (escaped_host != escaped_shost)
+       free(escaped_shost);
+    free(escaped_user);
     free(filt);
     ldap_msgfree(result);
     debug_return_bool(false);
-overflow:
-    sudo_warnx(U_("internal error, %s overflow"), __func__);
-    free(filt);
-    debug_return_bool(false);
 }
 
 /*