From feb00fe7cc238a78b3832c116cb4634936597735 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Matthias=20Dieter=20Walln=C3=B6fer?= Date: Wed, 10 Nov 2010 16:05:16 +0100 Subject: [PATCH] s4:dsdb - proof against empty RDN values where expected This should prevent crashes as pointed out on the mailing list. --- source4/dsdb/common/util.c | 5 +++++ source4/dsdb/samdb/ldb_modules/objectclass.c | 4 +++- source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 8 ++++++++ source4/dsdb/samdb/ldb_modules/samldb.c | 13 ++++++++++++- source4/lib/ldb/modules/rdn_name.c | 15 ++++++++++++--- 5 files changed, 40 insertions(+), 5 deletions(-) diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c index 04d97043b2e..7f6ce64180d 100644 --- a/source4/dsdb/common/util.c +++ b/source4/dsdb/common/util.c @@ -1595,7 +1595,12 @@ int samdb_find_site_for_computer(struct ldb_context *ldb, talloc_free(dn); return LDB_ERR_INVALID_DN_SYNTAX; } + rdn_val = ldb_dn_get_rdn_val(dn); + if (rdn_val == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + (*site_name) = talloc_strndup(mem_ctx, (const char *)rdn_val->data, rdn_val->length); talloc_free(dn); if (!*site_name) { diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index 811bc96f025..2e95eb5e91a 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -334,8 +334,10 @@ static int fix_dn(struct ldb_context *ldb, return ldb_operr(ldb); } - rdn_val = ldb_dn_get_rdn_val(newdn); + if (rdn_val == NULL) { + return ldb_operr(ldb); + } #if 0 /* the rules for rDN length constraints are more complex than diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 7838b65fdfc..b2d5292a14f 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -2561,6 +2561,10 @@ static int replmd_delete(struct ldb_module *module, struct ldb_request *req) rdn_name = ldb_dn_get_rdn_name(old_dn); rdn_value = ldb_dn_get_rdn_val(old_dn); + if ((rdn_name == NULL) || (rdn_value == NULL)) { + talloc_free(tmp_ctx); + return ldb_operr(ldb); + } msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { @@ -2753,6 +2757,10 @@ static int replmd_delete(struct ldb_module *module, struct ldb_request *req) /* work out what the new rdn value is, for updating the rDN and name fields */ new_rdn_value = ldb_dn_get_rdn_val(new_dn); + if (new_rdn_value == NULL) { + talloc_free(tmp_ctx); + return ldb_operr(ldb); + } sa = dsdb_attribute_by_lDAPDisplayName(schema, rdn_name); if (!sa) { diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index 04b8dff0e0e..1ac86148e6e 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -575,6 +575,9 @@ static int samldb_fill_object(struct samldb_ctx *ac) } rdn_value = ldb_dn_get_rdn_val(ac->msg->dn); + if (rdn_value == NULL) { + return ldb_operr(ldb); + } if (!ldb_msg_find_element(ac->msg, "lDAPDisplayName")) { /* the RDN has prefix "CN" */ ret = ldb_msg_add_string(ac->msg, "lDAPDisplayName", @@ -638,6 +641,9 @@ static int samldb_fill_object(struct samldb_ctx *ac) } else if (strcmp(ac->type, "attributeSchema") == 0) { const struct ldb_val *rdn_value; rdn_value = ldb_dn_get_rdn_val(ac->msg->dn); + if (rdn_value == NULL) { + return ldb_operr(ldb); + } if (!ldb_msg_find_element(ac->msg, "lDAPDisplayName")) { /* the RDN has prefix "CN" */ ret = ldb_msg_add_string(ac->msg, "lDAPDisplayName", @@ -692,6 +698,7 @@ static int samldb_fill_object(struct samldb_ctx *ac) static int samldb_fill_foreignSecurityPrincipal_object(struct samldb_ctx *ac) { struct ldb_context *ldb; + const struct ldb_val *rdn_value; struct dom_sid *sid; int ret; @@ -699,8 +706,12 @@ static int samldb_fill_foreignSecurityPrincipal_object(struct samldb_ctx *ac) sid = samdb_result_dom_sid(ac->msg, ac->msg, "objectSid"); if (sid == NULL) { + rdn_value = ldb_dn_get_rdn_val(ac->msg->dn); + if (rdn_value == NULL) { + return ldb_operr(ldb); + } sid = dom_sid_parse_talloc(ac->msg, - (const char *)ldb_dn_get_rdn_val(ac->msg->dn)->data); + (const char *)rdn_value->data); if (sid == NULL) { ldb_set_errstring(ldb, "samldb: No valid SID found in ForeignSecurityPrincipal CN!"); diff --git a/source4/lib/ldb/modules/rdn_name.c b/source4/lib/ldb/modules/rdn_name.c index 623471a397a..38d87b0712e 100644 --- a/source4/lib/ldb/modules/rdn_name.c +++ b/source4/lib/ldb/modules/rdn_name.c @@ -87,6 +87,7 @@ static int rdn_name_add(struct ldb_module *module, struct ldb_request *req) struct ldb_message_element *attribute; const struct ldb_schema_attribute *a; const char *rdn_name; + const struct ldb_val *rdn_val_p; struct ldb_val rdn_val; unsigned int i; int ret; @@ -116,7 +117,11 @@ static int rdn_name_add(struct ldb_module *module, struct ldb_request *req) return LDB_ERR_OPERATIONS_ERROR; } - rdn_val = ldb_val_dup(msg, ldb_dn_get_rdn_val(msg->dn)); + rdn_val_p = ldb_dn_get_rdn_val(msg->dn); + if (rdn_val_p == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + rdn_val = ldb_val_dup(msg, rdn_val_p); /* Perhaps someone above us tried to set this? Then ignore it */ ldb_msg_remove_attr(msg, "name"); @@ -233,6 +238,7 @@ static int rdn_rename_callback(struct ldb_request *req, struct ldb_reply *ares) struct rename_context *ac; struct ldb_request *mod_req; const char *rdn_name; + const struct ldb_val *rdn_val_p; struct ldb_val rdn_val; struct ldb_message *msg; int ret; @@ -273,8 +279,11 @@ static int rdn_rename_callback(struct ldb_request *req, struct ldb_reply *ares) if (rdn_name == NULL) { goto error; } - - rdn_val = ldb_val_dup(msg, ldb_dn_get_rdn_val(ac->req->op.rename.newdn)); + rdn_val_p = ldb_dn_get_rdn_val(msg->dn); + if (rdn_val_p == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + rdn_val = ldb_val_dup(msg, rdn_val_p); if (ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_REPLACE, NULL) != 0) { goto error; -- 2.34.1