From: Andrew Bartlett Date: Mon, 21 May 2018 03:23:53 +0000 (+1200) Subject: CVE-2018-1140 ldb_tdb: Check for DN validity in add, rename and search X-Git-Tag: ldb-1.3.5~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ebc3a1a137f0182d5c0b2b60d65578864b441e54;p=thirdparty%2Fsamba.git CVE-2018-1140 ldb_tdb: Check for DN validity in add, rename and search 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 Reviewed-by: Douglas Bagnall BUG: https://bugzilla.samba.org/show_bug.cgi?id=13374 --- diff --git a/lib/ldb/ldb_tdb/ldb_search.c b/lib/ldb/ldb_tdb/ldb_search.c index 02890862cf7..d14be0febd4 100644 --- a/lib/ldb/ldb_tdb/ldb_search.c +++ b/lib/ldb/ldb_tdb/ldb_search.c @@ -295,6 +295,14 @@ int ltdb_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_mes }; 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 (ltdb->cache->GUID_index_attribute == NULL) { tdb_key_ctx = talloc_new(msg); if (!tdb_key_ctx) { @@ -803,6 +811,14 @@ int ltdb_search(struct ltdb_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; diff --git a/lib/ldb/ldb_tdb/ldb_tdb.c b/lib/ldb/ldb_tdb/ldb_tdb.c index 701427609e9..c7bf865de58 100644 --- a/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/lib/ldb/ldb_tdb/ldb_tdb.c @@ -515,6 +515,16 @@ static int ltdb_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;inum_elements;i++) { struct ldb_message_element *el = &msg->elements[i]; @@ -1292,6 +1302,7 @@ static int ltdb_rename(struct ltdb_context *ctx) int ret = LDB_SUCCESS; TDB_DATA tdb_key, tdb_key_old; struct ldb_dn *db_dn; + bool valid_dn = false; ldb_request_set_state(req, LDB_ASYNC_PENDING); @@ -1304,10 +1315,24 @@ static int ltdb_rename(struct ltdb_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 = ltdb_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; }