@@ -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 */
804804static 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 );
10021003overflow :
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 */
10251027static 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,
19031908oom :
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