CVE-2018-1140 ldb_tdb: Check for DN validity in add, rename and search
authorAndrew Bartlett <abartlet@samba.org>
Mon, 21 May 2018 03:23:53 +0000 (15:23 +1200)
committerKarolin Seeger <kseeger@samba.org>
Tue, 14 Aug 2018 11:57:15 +0000 (13:57 +0200)
This ensures we fail with a good error code before an eventual ldb_dn_get_casefold() which
would otherwise fail.

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13374

lib/ldb/ldb_key_value/ldb_kv.c
lib/ldb/ldb_key_value/ldb_kv_search.c

index 3ea8d5e2ed4044343c56c81a8aa92afd398309f8..d4f896736a298d82699a34f5b2ae9b17a34f54dd 100644 (file)
@@ -440,6 +440,16 @@ static int ldb_kv_add_internal(struct ldb_module *module,
        struct ldb_context *ldb = ldb_module_get_ctx(module);
        int ret = LDB_SUCCESS;
        unsigned int i;
+       bool valid_dn = false;
+
+       /* Check the new DN is reasonable */
+       valid_dn = ldb_dn_validate(msg->dn);
+       if (valid_dn == false) {
+               ldb_asprintf_errstring(ldb_module_get_ctx(module),
+                                      "Invalid DN in ADD: %s",
+                                      ldb_dn_get_linearized(msg->dn));
+               return LDB_ERR_INVALID_DN_SYNTAX;
+       }
 
        for (i=0;i<msg->num_elements;i++) {
                struct ldb_message_element *el = &msg->elements[i];
@@ -1229,6 +1239,7 @@ static int ldb_kv_rename(struct ldb_kv_context *ctx)
        int ret = LDB_SUCCESS;
        struct ldb_val  key, key_old;
        struct ldb_dn *db_dn;
+       bool valid_dn = false;
 
        ldb_request_set_state(req, LDB_ASYNC_PENDING);
 
@@ -1241,12 +1252,26 @@ static int ldb_kv_rename(struct ldb_kv_context *ctx)
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
+       /* Check the new DN is reasonable */
+       valid_dn = ldb_dn_validate(req->op.rename.newdn);
+       if (valid_dn == false) {
+               ldb_asprintf_errstring(ldb_module_get_ctx(module),
+                                      "Invalid New DN: %s",
+                                      ldb_dn_get_linearized(req->op.rename.newdn));
+               return LDB_ERR_INVALID_DN_SYNTAX;
+       }
+
        /* we need to fetch the old record to re-add under the new name */
        ret = ldb_kv_search_dn1(module,
                                req->op.rename.olddn,
                                msg,
                                LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC);
-       if (ret != LDB_SUCCESS) {
+       if (ret == LDB_ERR_INVALID_DN_SYNTAX) {
+               ldb_asprintf_errstring(ldb_module_get_ctx(module),
+                                      "Invalid Old DN: %s",
+                                      ldb_dn_get_linearized(req->op.rename.newdn));
+               return ret;
+       } else if (ret != LDB_SUCCESS) {
                /* not finding the old record is an error */
                return ret;
        }
index cd7ff52960791dc63ce527748837da751419109f..e9964c2bd63b95ed0939d13ade5c476e8df3d169 100644 (file)
@@ -294,6 +294,14 @@ int ldb_kv_search_dn1(struct ldb_module *module,
        };
        TALLOC_CTX *tdb_key_ctx = NULL;
 
+       bool valid_dn = ldb_dn_validate(dn);
+       if (valid_dn == false) {
+               ldb_asprintf_errstring(ldb_module_get_ctx(module),
+                                      "Invalid Base DN: %s",
+                                      ldb_dn_get_linearized(dn));
+               return LDB_ERR_INVALID_DN_SYNTAX;
+       }
+
        if (ldb_kv->cache->GUID_index_attribute == NULL ||
            ldb_dn_is_special(dn)) {
 
@@ -789,6 +797,14 @@ int ldb_kv_search(struct ldb_kv_context *ctx)
                                               ldb_dn_get_linearized(req->op.search.base));
                }
 
+       } else if (ldb_dn_validate(req->op.search.base) == false) {
+
+               /* We don't want invalid base DNs here */
+               ldb_asprintf_errstring(ldb,
+                                      "Invalid Base DN: %s",
+                                      ldb_dn_get_linearized(req->op.search.base));
+               ret = LDB_ERR_INVALID_DN_SYNTAX;
+
        } else {
                /* If we are not checking the base DN life is easy */
                ret = LDB_SUCCESS;