Re: Supporting sudoUser:!foo in sudo.ldap

Simon Lees <[email protected]> Mon, 17 Jan 2022 12:00:07 +1030
Newsgroups gmane.comp.tools.sudo.devel
Message-ID <[email protected]>
This is an OpenPGP/MIME signed message (RFC 4880 and 3156)
--===============7880317814608681149==
Content-Language: en-US
Content-Type: multipart/signed; micalg=pgp-sha256;
 protocol="application/pgp-signature";
 boundary="------------0mf0RU4Ns0TsbS0kS1PGpMfD"

This is an OpenPGP/MIME signed message (RFC 4880 and 3156)
--------------0mf0RU4Ns0TsbS0kS1PGpMfD
Content-Type: multipart/mixed; boundary="------------v8q1Jczc2b70PZo3KovILIYm";
 protected-headers="v1"
From: Simon Lees <[email protected]>
To: [email protected]
Message-ID: <[email protected]>
Subject: Re: [sudo-workers] Supporting sudoUser:!foo in sudo.ldap
References: <[email protected]>
 <[email protected]> <[email protected]>
In-Reply-To: <[email protected]>

--------------v8q1Jczc2b70PZo3KovILIYm
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Hi All,

On 12/15/21 14:07, Simon Lees wrote:
>=20
>=20
> On 12/15/21 02:25, Todd C. Miller wrote:
>> I think this is worth pursuing.  The question I have is whether
>> supporting !username is sufficient.  If we are going to support
>> this kind of construct, it should probably mirror the existing query
>> that contains uid, groups, gids and netgroups.
>>
>> Does that make sense?
>=20
> Yep, i'll go back and work on that, Thanks for the feedback.

Now I'm back from Summer Holidays here is round 2 that implements the
same Idea for everything.

Given the patch is larger i'm happy to upload it somewhere else if that
works better.


Again feedback is very much appreciated.

Thanks

Simon

Index: sudo-1.9.5p2/plugins/sudoers/ldap.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sudo-1.9.5p2.orig/plugins/sudoers/ldap.c
+++ sudo-1.9.5p2/plugins/sudoers/ldap.c
@@ -923,7 +923,7 @@ done:
 static char *
 sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw)
 {
-    char *buf, timebuffer[TIMEFILTER_LENGTH + 1], idbuf[MAX_UID_T_LEN + =
1];
+    char *buf, *notbuf, timebuffer[TIMEFILTER_LENGTH + 1],
idbuf[MAX_UID_T_LEN + 1];
     struct ldap_netgroup_list netgroups;
     struct ldap_netgroup *ng =3D NULL;
     struct gid_list *gidlist;
@@ -943,26 +943,29 @@ sudo_ldap_build_pass1(LDAP *ld, struct p
     if (ldap_conf.search_filter)
 	sz +=3D strlen(ldap_conf.search_filter);

-    /* Then add (|(sudoUser=3DUSERNAME)(sudoUser=3D#uid)(sudoUser=3DALL)=
) +
NUL */
-    sz +=3D 29 + (12 + MAX_UID_T_LEN) + sudo_ldap_value_len(pw->pw_name)=
;
+    /* Then add (| */
+    sz +=3D 2;
+    /* For the following mult by 2 and add additional chars for ! */
+    /* (sudoUser=3DUSERNAME)(sudoUser=3D#uid)(sudoUser=3DALL)) + NUL */
+    sz +=3D (27 + (12 + MAX_UID_T_LEN) +
sudo_ldap_value_len(pw->pw_name))*2+2;

     /* Add space for primary and supplementary groups and gids */
     if ((grp =3D sudo_getgrgid(pw->pw_gid)) !=3D NULL) {
-	sz +=3D 12 + sudo_ldap_value_len(grp->gr_name);
+	sz +=3D (12 + sudo_ldap_value_len(grp->gr_name))*2+1;
     }
-    sz +=3D 13 + MAX_UID_T_LEN;
+    sz +=3D (13 + MAX_UID_T_LEN)*2+1;
     if ((grlist =3D sudo_get_grlist(pw)) !=3D NULL) {
 	for (i =3D 0; i < grlist->ngroups; i++) {
 	    if (grp !=3D NULL && strcasecmp(grlist->groups[i], grp->gr_name) =3D=
=3D 0)
 		continue;
-	    sz +=3D 12 + sudo_ldap_value_len(grlist->groups[i]);
+	    sz +=3D (12 + sudo_ldap_value_len(grlist->groups[i]))*2+1;
 	}
     }
     if ((gidlist =3D sudo_get_gidlist(pw, ENTRY_TYPE_ANY)) !=3D NULL) {
 	for (i =3D 0; i < gidlist->ngids; i++) {
 	    if (pw->pw_gid =3D=3D gidlist->gids[i])
 		continue;
-	    sz +=3D 13 + MAX_UID_T_LEN;
+	    sz +=3D (13 + MAX_UID_T_LEN)*2+1;
 	}
     }

@@ -971,7 +974,7 @@ sudo_ldap_build_pass1(LDAP *ld, struct p
 	DPRINTF1("Looking up netgroups for %s", pw->pw_name);
 	if (sudo_netgroup_lookup(ld, pw, &netgroups)) {
 	    STAILQ_FOREACH(ng, &netgroups, entries) {
-		sz +=3D 14 + strlen(ng->name);
+		sz +=3D (14 + strlen(ng->name))*2+1;
 	    }
 	} else {
 	    /* sudo_netgroup_lookup() failed, clean up. */
@@ -986,9 +989,11 @@ sudo_ldap_build_pass1(LDAP *ld, struct p
     /* If timed, add space for time limits. */
     if (ldap_conf.timed)
 	sz +=3D TIMEFILTER_LENGTH;
-    if ((buf =3D malloc(sz)) =3D=3D NULL)
+
+    if (((buf =3D malloc(sz)) =3D=3D NULL) || ((notbuf =3D malloc(sz)) =3D=
=3D NULL))
 	goto bad;
     *buf =3D '\0';
+    *notbuf =3D '\0';

     /*
      * If timed or using a search filter, start a global AND clause to
@@ -1004,23 +1009,35 @@ sudo_ldap_build_pass1(LDAP *ld, struct p
     CHECK_STRLCAT(buf, "(|(sudoUser=3D", sz);
     CHECK_LDAP_VCAT(buf, pw->pw_name, sz);
     CHECK_STRLCAT(buf, ")", sz);
+    CHECK_STRLCAT(notbuf, "(sudoUser=3D!", sz);
+    CHECK_LDAP_VCAT(notbuf, pw->pw_name, sz);
+    CHECK_STRLCAT(notbuf, ")", sz);

     /* Append user-ID */
     (void) snprintf(idbuf, sizeof(idbuf), "%u", (unsigned int)pw->pw_uid=
);
     CHECK_STRLCAT(buf, "(sudoUser=3D#", sz);
     CHECK_STRLCAT(buf, idbuf, sz);
     CHECK_STRLCAT(buf, ")", sz);
+    CHECK_STRLCAT(notbuf, "(sudoUser=3D!#", sz);
+    CHECK_STRLCAT(notbuf, idbuf, sz);
+    CHECK_STRLCAT(notbuf, ")", sz);

     /* Append primary group and group-ID */
     if (grp !=3D NULL) {
 	CHECK_STRLCAT(buf, "(sudoUser=3D%", sz);
 	CHECK_LDAP_VCAT(buf, grp->gr_name, sz);
 	CHECK_STRLCAT(buf, ")", sz);
+	CHECK_STRLCAT(notbuf, "(sudoUser=3D!%", sz);
+	CHECK_LDAP_VCAT(notbuf, grp->gr_name, sz);
+	CHECK_STRLCAT(notbuf, ")", sz);
     }
     (void) snprintf(idbuf, sizeof(idbuf), "%u", (unsigned int)pw->pw_gid=
);
     CHECK_STRLCAT(buf, "(sudoUser=3D%#", sz);
     CHECK_STRLCAT(buf, idbuf, sz);
     CHECK_STRLCAT(buf, ")", sz);
+    CHECK_STRLCAT(notbuf, "(sudoUser=3D!%#", sz);
+    CHECK_STRLCAT(notbuf, idbuf, sz);
+    CHECK_STRLCAT(notbuf, ")", sz);

     /* Append supplementary groups and group-IDs */
     if (grlist !=3D NULL) {
@@ -1030,6 +1047,9 @@ sudo_ldap_build_pass1(LDAP *ld, struct p
 	    CHECK_STRLCAT(buf, "(sudoUser=3D%", sz);
 	    CHECK_LDAP_VCAT(buf, grlist->groups[i], sz);
 	    CHECK_STRLCAT(buf, ")", sz);
+	    CHECK_STRLCAT(notbuf, "(sudoUser=3D!%", sz);
+	    CHECK_LDAP_VCAT(notbuf, grlist->groups[i], sz);
+	    CHECK_STRLCAT(notbuf, ")", sz);
 	}
     }
     if (gidlist !=3D NULL) {
@@ -1041,6 +1061,9 @@ sudo_ldap_build_pass1(LDAP *ld, struct p
 	    CHECK_STRLCAT(buf, "(sudoUser=3D%#", sz);
 	    CHECK_STRLCAT(buf, idbuf, sz);
 	    CHECK_STRLCAT(buf, ")", sz);
+	    CHECK_STRLCAT(notbuf, "(sudoUser=3D!%#", sz);
+	    CHECK_STRLCAT(notbuf, idbuf, sz);
+	    CHECK_STRLCAT(notbuf, ")", sz);
 	}
     }

@@ -1058,6 +1081,9 @@ sudo_ldap_build_pass1(LDAP *ld, struct p
 	CHECK_STRLCAT(buf, "(sudoUser=3D+", sz);
 	CHECK_LDAP_VCAT(buf, ng->name, sz);
 	CHECK_STRLCAT(buf, ")", sz);
+	CHECK_STRLCAT(notbuf, "(sudoUser=3D!+", sz);
+	CHECK_LDAP_VCAT(notbuf, ng->name, sz);
+	CHECK_STRLCAT(notbuf, ")", sz);
 	free(ng->name);
 	free(ng);
     }
@@ -1074,8 +1100,15 @@ sudo_ldap_build_pass1(LDAP *ld, struct p
     } else if (ldap_conf.search_filter) {
 	CHECK_STRLCAT(buf, ")", sz); /* closes the global OR */
     }
+
+    /* Global ! filters */
+    CHECK_STRLCAT(buf, "(!", sz);
+    CHECK_LDAP_VCAT(buf, notbuf, sz);
+    CHECK_STRLCAT(buf, ")", sz);
+
     CHECK_STRLCAT(buf, ")", sz); /* closes the global OR or the global
AND */

+    free(notbuf);
     debug_return_str(buf);
 overflow:
     sudo_warnx(U_("internal error, %s overflow"), __func__);


--=20
Simon Lees (Simotek)                            http://simotek.net

Emergency Update Team                           keybase.io/simotek
SUSE Linux                           Adelaide Australia, UTC+10:30
GPG Fingerprint: 5B87 DB9D 88DC F606 E489 CEC5 0922 C246 02F0 014B

--------------v8q1Jczc2b70PZo3KovILIYm--

--------------0mf0RU4Ns0TsbS0kS1PGpMfD
Content-Type: application/pgp-signature; name="OpenPGP_signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="OpenPGP_signature"

-----BEGIN PGP SIGNATURE-----

wsB5BAABCAAjFiEED0hBIYMo9ADHKtZgEdQumr4Y/JEFAmHkxp8FAwAAAAAACgkQEdQumr4Y/JF0
qAf/ZmrZut/SpEqp+4pWkPn3t2gXpq8I343HyV3yhM8WeQHTqbUhDYtckgCOscv16eCUaw6ns619
ffgp/DxJH5kBtTd9cfy+sxyQyPUfLM9MmdvC5pmZcy/n7k7NY9Pgn8zDMPDcwGT1XIk8e9oJF8CX
l1nVcQ+muZgEYnIb1X/wWJi6pHeqI/6shH/z0rVtFBlbTxwjdkmIRltyHYYmmBHTJl22xM7zJkoc
9mHEeCnFyT3iIQNGMt5w3JJvEN0SzZlp3W9tAE4FggJr0JbR8rkzmniz09WL61PspoaKngaoz2SB
C1Tf/Z9BHFbKUMbn497lRP/egbbSLJeE+lfI64qoyQ==
=r/u3
-----END PGP SIGNATURE-----

--------------0mf0RU4Ns0TsbS0kS1PGpMfD--

--===============7880317814608681149==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

____________________________________________________________
sudo-workers mailing list <[email protected]>
For list information, options, or to unsubscribe, visit:
https://www.sudo.ws/mailman/listinfo/sudo-workers

--===============7880317814608681149==--