]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
ext_ldap_group_acl: Require base dn and user search filter (#2167)
authorJoshua Rogers <MegaManSec@users.noreply.github.com>
Sat, 13 Sep 2025 12:02:58 +0000 (12:02 +0000)
committerSquid Anubis <squid-anubis@squid-cache.org>
Sat, 13 Sep 2025 12:06:17 +0000 (12:06 +0000)
Make ext_ldap_group_acl require -B (user base DN) and -F (user search
filter) so the helper finds the user before checking group membership.
Fix LDAP referrals handling and make %v always expand to the requested
group name. Improve logging and errors, and include release notes for
the breaking flag requirements.

doc/release-notes/release-8.sgml.in
src/acl/external/LDAP_group/ext_ldap_group_acl.cc

index 2c7a44edd119bcff5c7abecc43344d906a8a667f..a521cf4f8d32927a2c715f8f5c7aab7f16677a6a 100644 (file)
@@ -46,6 +46,17 @@ The Squid-@SQUID_RELEASE@ change history can be <url url="https://github.com/squ
        <p>Removed <em>ntlm_smb_lm_auth</em> NTLM authentication helper.
           Use the <em>ntlm_auth</em> helper from the Samba project instead.
 
+       <p>Updated <em>ext_ldap_group_acl</em> external ACL helper:
+          now requires <tt>-B</tt> (user base DN) and <tt>-F</tt>
+          (user search filter) to locate the user prior to evaluating
+          group membership. Administrators who omitted one or both options
+          must update their configurations to continue using this helper.
+
+       <p>Fixed <em>ext_ldap_group_acl</em> handling of LDAP referrals and
+          placeholders: corrected referrals option processing and aligned the
+          <tt>%v</tt> placeholder to mean the requested group name, matching
+          the helper documentation/help-text.
+
 </descrip>
 
 <sect1>Cache Manager changes
index 69ba3e3ebac4c9972a4d34109f081c31b2bac729..08a46a6b0fb9e9d6a972fede207ff37aed8d9937 100644 (file)
@@ -188,7 +188,7 @@ static void
 squid_ldap_set_referrals(LDAP * ld, int referrals)
 {
     if (referrals)
-        ld->ld_options |= ~LDAP_OPT_REFERRALS;
+        ld->ld_options |= LDAP_OPT_REFERRALS;
     else
         ld->ld_options &= ~LDAP_OPT_REFERRALS;
 }
@@ -231,6 +231,7 @@ main(int argc, char **argv)
 
     setbuf(stdout, nullptr);
 
+    const auto prog = argv[0];
     while (argc > 1 && argv[1][0] == '-') {
         const char *value = "";
         char option = argv[1][1];
@@ -410,7 +411,7 @@ main(int argc, char **argv)
     if (!ldapServer)
         ldapServer = (char *) "localhost";
 
-    if (!basedn || !searchfilter) {
+    if (!basedn || !searchfilter || !userbasedn || !usersearchfilter) {
         fprintf(stderr, "\n" PROGRAM_NAME " version " PROGRAM_VERSION "\n\n");
         fprintf(stderr, "Usage: " PROGRAM_NAME " -b basedn -f filter [options] ldap_server_name\n\n");
         fprintf(stderr, "\t-b basedn (REQUIRED)\tbase dn under where to search for groups\n");
@@ -466,9 +467,9 @@ main(int argc, char **argv)
         int found = 0;
         if (!strchr(buf, '\n')) {
             /* too large message received.. skip and deny */
-            fprintf(stderr, "%s: ERROR: Input Too large: %s\n", argv[0], buf);
+            fprintf(stderr, "%s: ERROR: Input Too large: %s\n", prog, buf);
             while (fgets(buf, sizeof(buf), stdin)) {
-                fprintf(stderr, "%s: ERROR: Input Too large..: %s\n", argv[0], buf);
+                fprintf(stderr, "%s: ERROR: Input Too large..: %s\n", prog, buf);
                 if (strchr(buf, '\n') != nullptr)
                     break;
             }
@@ -477,7 +478,7 @@ main(int argc, char **argv)
         }
         user = strtok(buf, " \n");
         if (!user) {
-            debug("%s: Invalid request: No Username given\n", argv[0]);
+            debug("%s: Invalid request: No Username given\n", prog);
             SEND_BH(HLP_MSG("Invalid request. No Username"));
             continue;
         }
@@ -500,7 +501,7 @@ main(int argc, char **argv)
         if (use_extension_dn) {
             extension_dn = strtok(nullptr, " \n");
             if (!extension_dn) {
-                debug("%s: Invalid request: Extension DN configured, but none sent.\n", argv[0]);
+                debug("%s: Invalid request: Extension DN configured, but none sent.\n", prog);
                 SEND_BH(HLP_MSG("Invalid Request. Extension DN required"));
                 continue;
             }
@@ -517,7 +518,7 @@ recover:
                     rc = ldap_initialize(&ld, ldapServer);
                     if (rc != LDAP_SUCCESS) {
                         broken = HLP_MSG("Unable to connect to LDAP server");
-                        fprintf(stderr, "%s: ERROR: Unable to connect to LDAPURI:%s\n", argv[0], ldapServer);
+                        fprintf(stderr, "%s: ERROR: Unable to connect to LDAPURI:%s\n", prog, ldapServer);
                         break;
                     }
                 } else
@@ -581,7 +582,7 @@ recover:
                     rc = ldap_simple_bind_s(ld, binddn, bindpasswd);
                     if (rc != LDAP_SUCCESS) {
                         broken = HLP_MSG("could not bind");
-                        fprintf(stderr, PROGRAM_NAME ": WARNING: %s to binddn '%s'\n", broken, ldap_err2string(rc));
+                        fprintf(stderr, PROGRAM_NAME ": WARNING: %s to binddn '%s'\n", broken, binddn);
                         ldap_unbind(ld);
                         ld = nullptr;
                         break;
@@ -654,10 +655,10 @@ build_filter(std::string &filter, const char *templ, const char *user, const cha
             ++templ;
             switch (*templ) {
             case 'u':
-            case 'v':
                 ++templ;
                 str << ldap_escape_value(user);
                 break;
+            case 'v':
             case 'g':
             case 'a':
                 ++templ;
@@ -778,7 +779,7 @@ searchLDAP(LDAP * ld, char *group, char *login, char *extension_dn)
         entry = ldap_first_entry(ld, ldapRes.get());
         if (!entry) {
             std::cerr << PROGRAM_NAME << ": WARNING: User '" << login <<
-                      " not found in '" << searchbase.c_str() << "'" << std::endl;
+                      "' not found in '" << searchbase.c_str() << "'" << std::endl;
             return 1;
         }
         userdn = ldap_get_dn(ld, entry);