Use asprintf() to generate the netgroup filter instead of using

lots of concatenation.
This commit is contained in:
Todd C. Miller
2016-01-12 14:29:09 -07:00
parent f97eba71f0
commit 9d7bc0311f

View 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);
if (user_runhost != 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 *= 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 = 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, ",", 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);
} else {
filt_len *= 3;
filt_len += sudo_ldap_value_len(user_srunhost);
filt_len += sudo_ldap_value_len(user_runhost);
}
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);
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);
}
/*