Don't walk past the end of ldb values.
authorAndrew Bartlett <abartlet@samba.org>
Thu, 21 Aug 2008 09:24:58 +0000 (19:24 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 21 Aug 2008 09:24:58 +0000 (19:24 +1000)
This is a partial fix towards bugs due to us walking past the end of
what we think are strings in ldb.  There is much more work to do in
this area.

Andrew Bartlett
(This used to be commit 5805a9a8f35fd90fa4f718f73534817fa3bbdfd2)

source4/dsdb/samdb/ldb_modules/linked_attributes.c
source4/dsdb/samdb/ldb_modules/normalise.c
source4/dsdb/samdb/ldb_modules/partition.c
source4/dsdb/samdb/ldb_modules/schema_syntax.c
source4/dsdb/samdb/ldb_modules/simple_ldap_map.c
source4/lib/ldb-samba/ldif_handlers.c
source4/lib/ldb/common/ldb_dn.c
source4/lib/ldb/common/ldb_msg.c
source4/lib/ldb/include/ldb.h
source4/lib/util/data_blob.c
source4/libcli/security/dom_sid.c

index 04b9987071df30aba5e783a8b34ef5c63ffee72c..e64472432d21d2293b1bfd173144a1942a16169e 100644 (file)
@@ -160,7 +160,7 @@ static int setup_modifies(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
                                ldb_oom(ldb);
                                return LDB_ERR_OPERATIONS_ERROR;
                        }
-                       new_msg->dn = ldb_dn_new(new_msg, ldb, (char *)el->values[j].data);
+                       new_msg->dn = ldb_dn_from_ldb_val(new_msg, ldb, &el->values[j]);
                        if (!new_msg->dn) {
                                ldb_asprintf_errstring(ldb, 
                                                       "attribute %s value %s was not a valid DN", msg->elements[i].name,
@@ -330,7 +330,7 @@ static int linked_attributes_mod_replace_search_callback(struct ldb_context *ldb
                        /* Add all the existing elements, marking as 'proposed for delete' by setting .add = false */
                        for (i=0; i < search_el->num_values; i++) {
                                merged_list = talloc_realloc(ares, merged_list, struct merge, size + 1);
-                               merged_list[size].dn = ldb_dn_new(merged_list, ldb, (char *)search_el->values[i].data);
+                               merged_list[size].dn = ldb_dn_from_ldb_val(merged_list, ldb, &search_el->values[i]);
                                merged_list[size].add = false;
                                merged_list[size].ignore = false;
                                size++;
@@ -339,7 +339,7 @@ static int linked_attributes_mod_replace_search_callback(struct ldb_context *ldb
                        /* Add all the new replacement elements, marking as 'proposed for add' by setting .add = true */
                        for (i=0; i < ac2->el->num_values; i++) {
                                merged_list = talloc_realloc(ares, merged_list, struct merge, size + 1);
-                               merged_list[size].dn = ldb_dn_new(merged_list, ldb, (char *)ac2->el->values[i].data);
+                               merged_list[size].dn = ldb_dn_from_ldb_val(merged_list, ldb, &ac2->el->values[i]);
                                merged_list[size].add = true;
                                merged_list[size].ignore = false;
                                size++;
@@ -610,7 +610,7 @@ static int linked_attributes_modify(struct ldb_module *module, struct ldb_reques
                                ldb_oom(module->ldb);
                                return LDB_ERR_OPERATIONS_ERROR;
                        }
-                       new_msg->dn = ldb_dn_new(new_msg, module->ldb, (char *)el->values[j].data);
+                       new_msg->dn = ldb_dn_from_ldb_val(new_msg, module->ldb, &el->values[j]);
                        if (!new_msg->dn) {
                                ldb_asprintf_errstring(module->ldb, 
                                               "attribute %s value %s was not a valid DN", req->op.mod.message->elements[i].name,
index 8de9e33002bace5f76d8173373f09f12ed3ddc3b..3306fd3c33b9f8cba6b1bd76d674465c3160d83c 100644 (file)
@@ -112,7 +112,7 @@ static int normalise_search_callback(struct ldb_context *ldb, void *context, str
                }
                for (j = 0; j < ares->message->elements[i].num_values; j++) {
                        const char *dn_str;
-                       struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, (const char *)ares->message->elements[i].values[j].data);
+                       struct ldb_dn *dn = ldb_dn_from_ldb_val(mem_ctx, ldb, &ares->message->elements[i].values[j]);
                        if (!dn) {
                                talloc_free(mem_ctx);
                                return LDB_ERR_OPERATIONS_ERROR;
index 9285d6d0d862e6e2d73b05f5db85d412ff356fed..9cae6ab7b538e96165ec7a011655270f674f8e15 100644 (file)
@@ -925,7 +925,7 @@ static int partition_init(struct ldb_module *module)
                }
                
                for (i=0; i < replicate_attributes->num_values; i++) {
-                       data->replicate[i] = ldb_dn_new(data->replicate, module->ldb, (const char *)replicate_attributes->values[i].data);
+                       data->replicate[i] = ldb_dn_from_ldb_val(data->replicate, module->ldb, &replicate_attributes->values[i]);
                        if (!ldb_dn_validate(data->replicate[i])) {
                                ldb_asprintf_errstring(module->ldb, 
                                                        "partition_init: "
index d800e4b6d242e9b24e0106d58a08582c1eed0427..ab9f32c913c7d2a928cdcfa7678a3da1cf53661d 100644 (file)
@@ -248,7 +248,7 @@ static int schema_validate_dn(struct ldb_context *ldb, struct ldb_val *val, int
        struct ldb_dn *dn;
        int ret = LDB_SUCCESS;
 
-       dn = ldb_dn_new(ldb, ldb, (const char *)val->data);
+       dn = ldb_dn_from_ldb_val(ldb, ldb, val);
        if ( ! ldb_dn_validate(dn)) {
                ret = LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
        }
index 6e967aab2f2061fac9fc9a1c2ff7cc17b735f8ac..8f9299514551a61af6eb1f4c75bbf8795729813a 100644 (file)
@@ -154,7 +154,7 @@ static struct ldb_val objectCategory_always_dn(struct ldb_module *module, TALLOC
        struct ldb_val out = data_blob(NULL, 0);
        const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(module->ldb, "objectCategory");
 
-       dn = ldb_dn_new(ctx, module->ldb, val->data);
+       dn = ldb_dn_from_ldb_val(ctx, module->ldb, val);
        if (dn && ldb_dn_validate(dn)) {
                talloc_free(dn);
                return val_copy(module, ctx, val);
index 750e35bca06a60fea71fe908809f546c54795cff..04fcd66b6eb79dd7b2b67830b8224ddf3b65da46 100644 (file)
@@ -38,7 +38,7 @@ static int ldif_read_objectSid(struct ldb_context *ldb, void *mem_ctx,
 {
        enum ndr_err_code ndr_err;
        struct dom_sid *sid;
-       sid = dom_sid_parse_talloc(mem_ctx, (const char *)in->data);
+       sid = dom_sid_parse_length(mem_ctx, in);
        if (sid == NULL) {
                return -1;
        }
@@ -70,12 +70,11 @@ static int ldif_write_objectSid(struct ldb_context *ldb, void *mem_ctx,
                talloc_free(sid);
                return -1;
        }
-       out->data = (uint8_t *)dom_sid_string(mem_ctx, sid);
+       *out = data_blob_string_const(dom_sid_string(mem_ctx, sid));
        talloc_free(sid);
        if (out->data == NULL) {
                return -1;
        }
-       out->length = strlen((const char *)out->data);
        return 0;
 }
 
@@ -146,10 +145,16 @@ static int ldif_read_objectGUID(struct ldb_context *ldb, void *mem_ctx,
                                const struct ldb_val *in, struct ldb_val *out)
 {
        struct GUID guid;
+       char *guid_string;
        NTSTATUS status;
        enum ndr_err_code ndr_err;
+       guid_string = talloc_strndup(mem_ctx, in->data, in->length);
+       if (!guid_string) {
+               return -1;
+       }
 
-       status = GUID_from_string((const char *)in->data, &guid);
+       status = GUID_from_string(guid_string, &guid);
+       talloc_free(guid_string);
        if (!NT_STATUS_IS_OK(status)) {
                return -1;
        }
@@ -324,7 +329,7 @@ static int ldif_canonicalise_objectCategory(struct ldb_context *ldb, void *mem_c
                }
                return LDB_SUCCESS;
        }
-       dn1 = ldb_dn_new(tmp_ctx, ldb, (char *)in->data);
+       dn1 = ldb_dn_from_ldb_val(tmp_ctx, ldb, in);
        if ( ! ldb_dn_validate(dn1)) {
                const char *lDAPDisplayName = talloc_strndup(tmp_ctx, (char *)in->data, in->length);
                class = dsdb_class_by_lDAPDisplayName(schema, lDAPDisplayName);
index 08911344b759cada33bac9786b1d2cbce1722ba1..c0d36cfbf3e0c48239b123a8920fbd4d065cc068 100644 (file)
@@ -71,7 +71,7 @@ struct ldb_dn {
 };
 
 /* strdn may be NULL */
-struct ldb_dn *ldb_dn_new(void *mem_ctx, struct ldb_context *ldb, const char *strdn)
+struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx, struct ldb_context *ldb, const struct ldb_val *strdn)
 {
        struct ldb_dn *dn;
 
@@ -82,27 +82,27 @@ struct ldb_dn *ldb_dn_new(void *mem_ctx, struct ldb_context *ldb, const char *st
 
        dn->ldb = ldb;
 
-       if (strdn) {
-               if (strdn[0] == '@') {
+       if (strdn->data && strdn->length) {
+               if (strdn->data[0] == '@') {
                        dn->special = true;
                }
-               if (strncasecmp(strdn, "<GUID=", 6) == 0) {
+               if (strdn->length >= 6 && strncasecmp((const char *)strdn->data, "<GUID=", 6) == 0) {
                        /* this is special DN returned when the
                         * exploded_dn control is used */
                        dn->special = true;
                        /* FIXME: add a GUID string to ldb_dn structure */
-               } else if (strncasecmp(strdn, "<SID=", 8) == 0) {
+               } else if (strdn->length >= 8 && strncasecmp((const char *)strdn->data, "<SID=", 8) == 0) {
                        /* this is special DN returned when the
                         * exploded_dn control is used */
                        dn->special = true;
                        /* FIXME: add a SID string to ldb_dn structure */
-               } else if (strncasecmp(strdn, "<WKGUID=", 8) == 0) {
+               } else if (strdn->length >= 8 && strncasecmp((const char *)strdn->data, "<WKGUID=", 8) == 0) {
                        /* this is special DN returned when the
                         * exploded_dn control is used */
                        dn->special = true;
                        /* FIXME: add a WKGUID string to ldb_dn structure */
                }
-               dn->linearized = talloc_strdup(dn, strdn);
+               dn->linearized = talloc_strndup(dn, (const char *)strdn->data, strdn->length);
        } else {
                dn->linearized = talloc_strdup(dn, "");
        }
@@ -115,6 +115,15 @@ failed:
        return NULL;
 }
 
+/* strdn may be NULL */
+struct ldb_dn *ldb_dn_new(void *mem_ctx, struct ldb_context *ldb, const char *strdn)
+{
+       struct ldb_val blob;
+       blob.data = strdn;
+       blob.length = strdn ? strlen(strdn) : 0;
+       return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob);
+}
+
 struct ldb_dn *ldb_dn_new_fmt(void *mem_ctx, struct ldb_context *ldb, const char *new_fmt, ...)
 {
        struct ldb_dn *dn;
index c1ea9db56bfb11a4319fb6503258199bcac471dd..2f5fe1d18c143cde271958948605ca0d82eea896 100644 (file)
@@ -389,10 +389,10 @@ int ldb_msg_find_attr_as_bool(const struct ldb_message *msg,
        if (!v || !v->data) {
                return default_value;
        }
-       if (strcasecmp((const char *)v->data, "FALSE") == 0) {
+       if (v->length == 5 && strncasecmp((const char *)v->data, "FALSE", 5) == 0) {
                return 0;
        }
-       if (strcasecmp((const char *)v->data, "TRUE") == 0) {
+       if (v->length == 4 && strncasecmp((const char *)v->data, "TRUE", 4) == 0) {
                return 1;
        }
        return default_value;
@@ -421,7 +421,7 @@ struct ldb_dn *ldb_msg_find_attr_as_dn(struct ldb_context *ldb,
        if (!v || !v->data) {
                return NULL;
        }
-       res_dn = ldb_dn_new(mem_ctx, ldb, (const char *)v->data);
+       res_dn = ldb_dn_from_ldb_val(mem_ctx, ldb, v);
        if ( ! ldb_dn_validate(res_dn)) {
                talloc_free(res_dn);
                return NULL;
index 7ce61034228da9dd9d176cd8f7e3908106968699..5dbf99e5bf9aa2aaf88ae34ba9b25089b2b2e1f7 100644 (file)
@@ -1381,6 +1381,7 @@ int ldb_base64_decode(char *s);
 
 struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *dn);
 struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *new_fmt, ...) PRINTF_ATTRIBUTE(3,4);
+struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx, struct ldb_context *ldb, const struct ldb_val *strdn);
 bool ldb_dn_validate(struct ldb_dn *dn);
 
 char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value);
index b258e47bbaf1646b5d09d7c36ea33baa9eab5fa8..57b34b7ae73d8aa698dc9df4fc164dc22a8b4512 100644 (file)
@@ -176,7 +176,7 @@ _PUBLIC_ DATA_BLOB data_blob_string_const(const char *str)
 {
        DATA_BLOB blob;
        blob.data = discard_const_p(uint8_t, str);
-       blob.length = strlen(str);
+       blob.length = str ? strlen(str) : 0;
        return blob;
 }
 
index f5457e7e0e4bcf8d927f6fa27b5585e9eb136449..1a7519e362988095b9bb945c7556a5f37f4adceb 100644 (file)
@@ -151,6 +151,21 @@ struct dom_sid *dom_sid_parse_talloc(TALLOC_CTX *mem_ctx, const char *sidstr)
        return ret;
 }
 
+/*
+  convert a string to a dom_sid, returning a talloc'd dom_sid
+*/
+struct dom_sid *dom_sid_parse_length(TALLOC_CTX *mem_ctx, const DATA_BLOB *sid)
+{
+       struct dom_sid *ret;
+       char *p = talloc_strndup(mem_ctx, sid->data, sid->length);
+       if (!p) {
+               return NULL;
+       }
+       ret = dom_sid_parse_talloc(mem_ctx, p);
+       talloc_free(p);
+       return ret;
+}
+
 /*
   copy a dom_sid structure
 */