ldb_tdb: Use the DN extracted from the DB to filter the message later
authorAndrew Bartlett <abartlet@samba.org>
Mon, 28 Aug 2017 03:37:28 +0000 (15:37 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Fri, 22 Sep 2017 19:20:24 +0000 (21:20 +0200)
This should ensure that the upper or lower case the user chooses does not impact
on the filtering, at least for database that have checkBaseOnSearch set.

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
lib/ldb/ldb_tdb/ldb_search.c
lib/ldb/ldb_tdb/ldb_tdb.c
lib/ldb/ldb_tdb/ldb_tdb.h

index 249ecfeb8109c2c784d3e58fda9de3102e878a59..761d33ed6d625ca7069a8de8748888fe09749b8a 100644 (file)
@@ -113,7 +113,10 @@ static int msg_add_distinguished_name(struct ldb_message *msg)
   return LDB_ERR_NO_SUCH_OBJECT on record-not-found
   and LDB_SUCCESS on success
 */
-int ltdb_search_base(struct ldb_module *module, struct ldb_dn *dn)
+int ltdb_search_base(struct ldb_module *module,
+                    TALLOC_CTX *mem_ctx,
+                    struct ldb_dn *dn,
+                    struct ldb_dn **ret_dn)
 {
        int exists;
        int ret;
@@ -137,16 +140,34 @@ int ltdb_search_base(struct ldb_module *module, struct ldb_dn *dn)
 
        ret = ltdb_search_dn1(module, dn,
                              msg,
-                             LDB_UNPACK_DATA_FLAG_NO_DN|
                              LDB_UNPACK_DATA_FLAG_NO_ATTRS);
-       talloc_free(msg);
        if (ret == LDB_SUCCESS) {
+               const char *dn_linearized
+                       = ldb_dn_get_linearized(dn);
+               const char *msg_dn_linearlized
+                       = ldb_dn_get_linearized(msg->dn);
+
+               if (strcmp(dn_linearized, msg_dn_linearlized) == 0) {
+                       /*
+                        * Re-use the full incoming DN for
+                        * subtree checks
+                        */
+                       *ret_dn = dn;
+               } else {
+                       /*
+                        * Use the string DN from the unpack, so that
+                        * we have a case-exact match of the base
+                        */
+                       *ret_dn = talloc_steal(mem_ctx, msg->dn);
+               }
                exists = true;
        } else if (ret == LDB_ERR_NO_SUCH_OBJECT) {
                exists = false;
        } else {
+               talloc_free(msg);
                return ret;
        }
+       talloc_free(msg);
        if (exists) {
                return LDB_SUCCESS;
        }
@@ -721,8 +742,15 @@ int ltdb_search(struct ltdb_context *ctx)
                return ret;
 
        } else if (ltdb->check_base) {
-               /* This database has been marked as 'checkBaseOnSearch', so do a spot check of the base dn */
-               ret = ltdb_search_base(module, req->op.search.base);
+               /*
+                * This database has been marked as
+                * 'checkBaseOnSearch', so do a spot check of the base
+                * dn.  Also optimise the subsequent filter by filling
+                * in the ctx->base to be exactly case correct
+                */
+               ret = ltdb_search_base(module, ctx,
+                                      req->op.search.base,
+                                      &ctx->base);
                
                if (ret == LDB_ERR_NO_SUCH_OBJECT) {
                        ldb_asprintf_errstring(ldb, 
index ea391850b27066898b504277edc26341957a081e..d2d8ee8b151965faaa988e5f888dda7e992bd875 100644 (file)
@@ -1265,6 +1265,7 @@ static int ltdb_rename(struct ltdb_context *ctx)
        struct ldb_message *msg;
        int ret = LDB_SUCCESS;
        TDB_DATA tdb_key, tdb_key_old;
+       struct ldb_dn *db_dn;
 
        ldb_request_set_state(req, LDB_ASYNC_PENDING);
 
@@ -1311,8 +1312,9 @@ static int ltdb_rename(struct ltdb_context *ctx)
         */
        if (tdb_key_old.dsize != tdb_key.dsize
            || memcmp(tdb_key.dptr, tdb_key_old.dptr, tdb_key.dsize) != 0) {
-               ret = ltdb_search_base(module,
-                                      req->op.rename.newdn);
+               ret = ltdb_search_base(module, msg,
+                                      req->op.rename.newdn,
+                                      &db_dn);
                if (ret == LDB_SUCCESS) {
                        ret = LDB_ERR_ENTRY_ALREADY_EXISTS;
                } else if (ret == LDB_ERR_NO_SUCH_OBJECT) {
index 5e16abdd1cf0c1c1da4c71a7db11025a15e06767..e8fafd263900541a837474546912a360c764b105 100644 (file)
@@ -128,7 +128,10 @@ int ltdb_has_wildcard(struct ldb_module *module, const char *attr_name,
 void ltdb_search_dn1_free(struct ldb_module *module, struct ldb_message *msg);
 int ltdb_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_message *msg,
                    unsigned int unpack_flags);
-int ltdb_search_base(struct ldb_module *module, struct ldb_dn *dn);
+int ltdb_search_base(struct ldb_module *module,
+                    TALLOC_CTX *mem_ctx,
+                    struct ldb_dn *dn,
+                    struct ldb_dn **ret_dn);
 int ltdb_search_key(struct ldb_module *module, struct ltdb_private *ltdb,
                    struct TDB_DATA tdb_key,
                    struct ldb_message *msg,