]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
CVE-2026-58222: s4:ldap_server: don't allow untrusted compare requests for confidenti... master
authorStefan Metzmacher <metze@samba.org>
Wed, 24 Jun 2026 12:42:11 +0000 (14:42 +0200)
committerBjoern Jacke <bjacke@samba.org>
Tue, 28 Jul 2026 17:02:13 +0000 (17:02 +0000)
This means we apply acl checks against the search filter similar
to normal ldb searches.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=16148

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Autobuild-User(master): Björn Jacke <bjacke@samba.org>
Autobuild-Date(master): Tue Jul 28 17:02:13 UTC 2026 on atb-devel-224

source4/ldap_server/ldap_backend.c

index 7314e65778af155681c4f0fa02bb1476149fac56..50b0adc7b8ea294768f80c35dd595d29ba8c924b 100644 (file)
@@ -29,6 +29,7 @@
 #include "samba/service_stream.h"
 #include "dsdb/gmsa/util.h"
 #include "dsdb/samdb/samdb.h"
 #include "samba/service_stream.h"
 #include "dsdb/gmsa/util.h"
 #include "dsdb/samdb/samdb.h"
+#include "dsdb/common/util.h"
 #include <ldb_errors.h>
 #include <ldb_module.h>
 #include "ldb_wrap.h"
 #include <ldb_errors.h>
 #include <ldb_module.h>
 #include "ldb_wrap.h"
@@ -1453,6 +1454,7 @@ static NTSTATUS ldapsrv_CompareRequest(struct ldapsrv_call *call)
        struct ldb_dn *dn;
        const char *attrs[1];
        const char *errstr = NULL;
        struct ldb_dn *dn;
        const char *attrs[1];
        const char *errstr = NULL;
+       const char *value = NULL;
        const char *filter = NULL;
        int result = LDAP_SUCCESS;
        int ldb_ret;
        const char *filter = NULL;
        int result = LDAP_SUCCESS;
        int ldb_ret;
@@ -1465,21 +1467,31 @@ static NTSTATUS ldapsrv_CompareRequest(struct ldapsrv_call *call)
        dn = ldb_dn_new(local_ctx, samdb, req->dn);
        NT_STATUS_HAVE_NO_MEMORY(dn);
 
        dn = ldb_dn_new(local_ctx, samdb, req->dn);
        NT_STATUS_HAVE_NO_MEMORY(dn);
 
+       compare_r = ldapsrv_init_reply(call, LDAP_TAG_CompareResponse);
+       NT_STATUS_HAVE_NO_MEMORY(compare_r);
+
        DBG_DEBUG("dn: [%s]\n", req->dn);
        DBG_DEBUG("dn: [%s]\n", req->dn);
-       filter = talloc_asprintf(local_ctx, "(%s=%*s)", req->attribute,
-                                (int)req->value.length, req->value.data);
+
+       if (!ldb_valid_attr_name(req->attribute)) {
+               result = LDAP_INVALID_ATTRIBUTE_SYNTAX;
+               errstr = "Invalid Compare attribute name";
+               goto reply;
+       }
+       value = ldb_binary_encode(local_ctx, req->value);
+       NT_STATUS_HAVE_NO_MEMORY(value);
+
+       filter = talloc_asprintf(local_ctx, "%s=%s", req->attribute, value);
        NT_STATUS_HAVE_NO_MEMORY(filter);
 
        DBG_DEBUG("attribute: [%s]\n", filter);
 
        attrs[0] = NULL;
 
        NT_STATUS_HAVE_NO_MEMORY(filter);
 
        DBG_DEBUG("attribute: [%s]\n", filter);
 
        attrs[0] = NULL;
 
-       compare_r = ldapsrv_init_reply(call, LDAP_TAG_CompareResponse);
-       NT_STATUS_HAVE_NO_MEMORY(compare_r);
-
        if (result == LDAP_SUCCESS) {
        if (result == LDAP_SUCCESS) {
-               ldb_ret = ldb_search(samdb, local_ctx, &res,
-                                    dn, LDB_SCOPE_BASE, attrs, "%s", filter);
+               ldb_ret = dsdb_search(samdb, local_ctx, &res,
+                                     dn, LDB_SCOPE_BASE, attrs,
+                                     DSDB_MARK_REQ_UNTRUSTED,
+                                     "%s", filter);
                if (ldb_ret != LDB_SUCCESS) {
                        result = map_ldb_error(local_ctx, ldb_ret,
                                               ldb_errstring(samdb), &errstr);
                if (ldb_ret != LDB_SUCCESS) {
                        result = map_ldb_error(local_ctx, ldb_ret,
                                               ldb_errstring(samdb), &errstr);
@@ -1501,6 +1513,7 @@ static NTSTATUS ldapsrv_CompareRequest(struct ldapsrv_call *call)
                }
        }
 
                }
        }
 
+reply:
        compare = &compare_r->msg->r.CompareResponse;
        compare->dn = NULL;
        compare->resultcode = result;
        compare = &compare_r->msg->r.CompareResponse;
        compare->dn = NULL;
        compare->resultcode = result;