Skip to content

Commit f24f72f

Browse files
committed
sudo_ldap_build_pass2: incorporate the negative filter from pass1
In order to support a mix of netgroups, non-Unix groups and negated sudoUser entries in the same sudoRole we need to apply the same negative filter as in pass1. Reported by Christos Papakonstantinou from Cantina (cantina.xyz)
1 parent 273e094 commit f24f72f

1 file changed

Lines changed: 16 additions & 10 deletions

File tree

plugins/sudoers/ldap.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -802,7 +802,8 @@ sudo_netgroup_lookup(struct sudoers_context *ctx, LDAP *ld, struct passwd *pw,
802802
* Builds up a filter to check against LDAP.
803803
*/
804804
static char *
805-
sudo_ldap_build_pass1(struct sudoers_context *ctx, LDAP *ld, struct passwd *pw)
805+
sudo_ldap_build_pass1(struct sudoers_context *ctx, LDAP *ld, struct passwd *pw,
806+
char **notbufp)
806807
{
807808
char idbuf[STRLEN_MAX_UNSIGNED(uid_t) + 1];
808809
char timebuffer[TIMEFILTER_LENGTH + 1];
@@ -971,11 +972,11 @@ sudo_ldap_build_pass1(struct sudoers_context *ctx, LDAP *ld, struct passwd *pw)
971972

972973
/* Add ALL to the list and close it. */
973974
CHECK_STRLCAT(buf, "(sudoUser=ALL))", sz);
975+
CHECK_STRLCAT(notbuf, "(sudoUser=!ALL)", sz);
974976

975977
/* Add filter for negated entries. */
976978
CHECK_STRLCAT(buf, "(!(|", sz);
977979
CHECK_STRLCAT(buf, notbuf, sz);
978-
CHECK_STRLCAT(buf, "(sudoUser=!ALL)", sz);
979980
CHECK_STRLCAT(buf, ")", sz);
980981

981982
/* Add the time restriction, or simply end the global OR. */
@@ -997,7 +998,7 @@ sudo_ldap_build_pass1(struct sudoers_context *ctx, LDAP *ld, struct passwd *pw)
997998
sudo_grlist_delref(grlist);
998999
if (grp != NULL)
9991000
sudo_gr_delref(grp);
1000-
free(notbuf);
1001+
*notbufp = notbuf;
10011002
debug_return_str(buf);
10021003
overflow:
10031004
sudo_warnx(U_("internal error, %s overflow"), __func__);
@@ -1020,10 +1021,11 @@ sudo_ldap_build_pass1(struct sudoers_context *ctx, LDAP *ld, struct passwd *pw)
10201021

10211022
/*
10221023
* Builds up a filter to check against non-Unix group
1023-
* entries in LDAP, including netgroups.
1024+
* entries in LDAP, including netgroups. We use the
1025+
* negative filter generated during the first pass.
10241026
*/
10251027
static char *
1026-
sudo_ldap_build_pass2(void)
1028+
sudo_ldap_build_pass2(const char *filt_neg)
10271029
{
10281030
char *filt, timebuffer[TIMEFILTER_LENGTH + 1];
10291031
bool query_netgroups = def_use_netgroups;
@@ -1057,19 +1059,20 @@ sudo_ldap_build_pass2(void)
10571059
* Match all sudoUsers beginning with '+' or '%:'.
10581060
* If a search filter or time restriction is specified,
10591061
* those get ANDed in to the expression.
1062+
* We also use the negative filter generated in pass1.
10601063
*/
10611064
if (query_netgroups && def_group_plugin) {
1062-
len = asprintf(&filt, "%s%s(|(sudoUser=+*)(sudoUser=!+*)(sudoUser=%%:*)(sudoUser=!%%:*))%s%s",
1065+
len = asprintf(&filt, "%s%s(|(sudoUser=+*)(sudoUser=!+*)(sudoUser=%%:*)(sudoUser=!%%:*))(!(|%s))%s%s",
10631066
(ldap_conf.timed || ldap_conf.search_filter) ? "(&" : "",
10641067
ldap_conf.search_filter ? ldap_conf.search_filter : "",
1065-
ldap_conf.timed ? timebuffer : "",
1068+
filt_neg, ldap_conf.timed ? timebuffer : "",
10661069
(ldap_conf.timed || ldap_conf.search_filter) ? ")" : "");
10671070
} else {
1068-
len = asprintf(&filt, "%s%s(|(sudoUser=%s*)(sudoUser=!%s*))%s%s",
1071+
len = asprintf(&filt, "%s%s(|(sudoUser=%s*)(sudoUser=!%s*))(!(|%s))%s%s",
10691072
(ldap_conf.timed || ldap_conf.search_filter) ? "(&" : "",
10701073
ldap_conf.search_filter ? ldap_conf.search_filter : "",
10711074
query_netgroups ? "+" : "%:", query_netgroups ? "+" : "%:",
1072-
ldap_conf.timed ? timebuffer : "",
1075+
filt_neg, ldap_conf.timed ? timebuffer : "",
10731076
(ldap_conf.timed || ldap_conf.search_filter) ? ")" : "");
10741077
}
10751078
if (len == -1)
@@ -1818,6 +1821,7 @@ sudo_ldap_result_get(struct sudoers_context *ctx, const struct sudo_nss *nss,
18181821
LDAPMessage *entry, *result;
18191822
LDAP *ld = handle->ld;
18201823
char *filt = NULL;
1824+
char *filt_neg = NULL;
18211825
int pass, rc;
18221826
debug_decl(sudo_ldap_result_get, SUDOERS_DEBUG_LDAP);
18231827

@@ -1843,7 +1847,8 @@ sudo_ldap_result_get(struct sudoers_context *ctx, const struct sudo_nss *nss,
18431847
if (lres == NULL)
18441848
goto oom;
18451849
for (pass = 0; pass < 2; pass++) {
1846-
filt = pass ? sudo_ldap_build_pass2() : sudo_ldap_build_pass1(ctx, ld, pw);
1850+
filt = pass ? sudo_ldap_build_pass2(filt_neg) :
1851+
sudo_ldap_build_pass1(ctx, ld, pw, &filt_neg);
18471852
if (filt != NULL) {
18481853
DPRINTF1("ldap search '%s'", filt);
18491854
STAILQ_FOREACH(base, &ldap_conf.base, entries) {
@@ -1903,6 +1908,7 @@ sudo_ldap_result_get(struct sudoers_context *ctx, const struct sudo_nss *nss,
19031908
oom:
19041909
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
19051910
free(filt);
1911+
free(filt_neg);
19061912
sudo_ldap_result_free(lres);
19071913
debug_return_ptr(NULL);
19081914
}

0 commit comments

Comments
 (0)