dsdb: Do not store a struct ldb_dn in struct schema_data
authorAndrew Bartlett <abartlet@samba.org>
Fri, 23 May 2014 04:06:17 +0000 (16:06 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 11 Jun 2014 08:18:26 +0000 (10:18 +0200)
The issue is that the DN contains a pointer to the ldb it belongs to,
and if this is not kept around long enough, we might reference memory
after it is de-allocated.

Andrew Bartlett

Change-Id: I040a6c37a3164b3309f370e32e598dd56b1a1bbb
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
source4/dsdb/repl/drepl_out_helpers.c
source4/dsdb/samdb/ldb_modules/repl_meta_data.c
source4/dsdb/samdb/ldb_modules/samldb.c
source4/dsdb/samdb/ldb_modules/schema_data.c
source4/dsdb/samdb/ldb_modules/schema_load.c
source4/dsdb/schema/schema.h
source4/dsdb/schema/schema_init.c
source4/dsdb/schema/schema_set.c
source4/libnet/libnet_vampire.c

index fd7284cf673d75281041164e5e9e60e8f40919fe..2339027e5816cf79ba130ab0cf4ce36fe16fa091 100644 (file)
@@ -394,6 +394,7 @@ static void dreplsrv_op_pull_source_get_changes_trigger(struct tevent_req *req)
        NTSTATUS status;
        uint32_t replica_flags;
        struct drsuapi_DsReplicaHighWaterMark highwatermark;
+       struct ldb_dn *schema_dn = ldb_get_schema_basedn(service->samdb);
 
        r = talloc(state, struct drsuapi_DsGetNCChanges);
        if (tevent_req_nomem(r, req)) {
@@ -441,7 +442,7 @@ static void dreplsrv_op_pull_source_get_changes_trigger(struct tevent_req *req)
                replica_flags &= ~DRSUAPI_DRS_WRIT_REP;
        } else if (partition->rodc_replica) {
                bool for_schema = false;
-               if (ldb_dn_compare_base(ldb_get_schema_basedn(service->samdb), partition->dn) == 0) {
+               if (ldb_dn_compare_base(schema_dn, partition->dn) == 0) {
                        for_schema = true;
                }
 
@@ -628,6 +629,7 @@ static void dreplsrv_op_pull_source_apply_changes_trigger(struct tevent_req *req
        struct dreplsrv_service *service = state->op->service;
        struct dreplsrv_partition *partition = state->op->source_dsa->partition;
        struct dreplsrv_drsuapi_connection *drsuapi = state->op->source_dsa->conn->drsuapi;
+       struct ldb_dn *schema_dn = ldb_get_schema_basedn(service->samdb);
        struct dsdb_schema *schema;
        struct dsdb_schema *working_schema = NULL;
        const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr;
@@ -684,20 +686,23 @@ static void dreplsrv_op_pull_source_apply_changes_trigger(struct tevent_req *req
         * Decide what working schema to use for object conversion.
         * We won't need a working schema for empty replicas sent.
         */
-       if (first_object && ldb_dn_compare(partition->dn, schema->base_dn) == 0) {
-               /* create working schema to convert objects with */
-               status = dsdb_repl_make_working_schema(service->samdb,
-                                                      schema,
-                                                      mapping_ctr,
-                                                      object_count,
-                                                      first_object,
-                                                      &drsuapi->gensec_skey,
-                                                      state, &working_schema);
-               if (!W_ERROR_IS_OK(status)) {
-                       DEBUG(0,("Failed to create working schema: %s\n",
-                                win_errstr(status)));
-                       tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
-                       return;
+       if (first_object) {
+               bool is_schema = ldb_dn_compare(partition->dn, schema_dn) == 0;
+               if (is_schema) {
+                       /* create working schema to convert objects with */
+                       status = dsdb_repl_make_working_schema(service->samdb,
+                                                              schema,
+                                                              mapping_ctr,
+                                                              object_count,
+                                                              first_object,
+                                                              &drsuapi->gensec_skey,
+                                                              state, &working_schema);
+                       if (!W_ERROR_IS_OK(status)) {
+                               DEBUG(0,("Failed to create working schema: %s\n",
+                                        win_errstr(status)));
+                               tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+                               return;
+                       }
                }
        }
 
index 83dabdfdf3b1195e9174a14e4b44240a197fbef3..30b3012682941870431c8bf19935ca5b501313ef 100644 (file)
@@ -67,6 +67,7 @@ struct replmd_private {
                uint64_t mod_usn;
                uint64_t mod_usn_urgent;
        } *ncs;
+       struct ldb_dn *schema_dn;
 };
 
 struct la_entry {
@@ -240,6 +241,8 @@ static int replmd_init(struct ldb_module *module)
        }
        ldb_module_set_private(module, replmd_private);
 
+       replmd_private->schema_dn = ldb_get_schema_basedn(ldb);
+
        return ldb_next_init(module);
 }
 
@@ -888,6 +891,8 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
        bool remove_current_guid = false;
        bool is_urgent = false;
        struct ldb_message_element *objectclass_el;
+       struct replmd_private *replmd_private =
+               talloc_get_type_abort(ldb_module_get_private(module), struct replmd_private);
 
         /* check if there's a show relax control (used by provision to say 'I know what I'm doing') */
         control = ldb_request_get_control(req, LDB_CONTROL_RELAX_OID);
@@ -1179,7 +1184,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
        if (control) {
                control->critical = 0;
        }
-       if (ldb_dn_compare_base(ac->schema->base_dn, req->op.add.message->dn) != 0) {
+       if (ldb_dn_compare_base(replmd_private->schema_dn, req->op.add.message->dn) != 0) {
 
                /* Update the usn in the SAMLDB_MSDS_INTID_OPAQUE opaque */
                msds_intid_struct = (struct samldb_msds_intid_persistant *) ldb_get_opaque(ldb, SAMLDB_MSDS_INTID_OPAQUE);
@@ -2471,6 +2476,8 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req)
        unsigned int functional_level;
        const DATA_BLOB *guid_blob;
        struct ldb_control *sd_propagation_control;
+       struct replmd_private *replmd_private =
+               talloc_get_type(ldb_module_get_private(module), struct replmd_private);
 
        /* do not manipulate our control entries */
        if (ldb_dn_is_special(req->op.mod.message->dn)) {
@@ -2609,7 +2616,7 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req)
                }
        }
 
-       if (!ldb_dn_compare_base(ac->schema->base_dn, msg->dn)) {
+       if (!ldb_dn_compare_base(replmd_private->schema_dn, msg->dn)) {
                /* Update the usn in the SAMLDB_MSDS_INTID_OPAQUE opaque */
                msds_intid_struct = (struct samldb_msds_intid_persistant *) ldb_get_opaque(ldb, SAMLDB_MSDS_INTID_OPAQUE);
                if (msds_intid_struct) {
index 981898ee4d9e6568777617a459a85e0175a41402..ad3d4da17da6cec73f44d87d2b31fb41eb3baafb 100644 (file)
@@ -509,7 +509,8 @@ static int samldb_add_handle_msDS_IntId(struct samldb_ctx *ac)
                        continue;
                }
 
-               ret = dsdb_module_load_partition_usn(ac->module, schema->base_dn, &current_usn, NULL, NULL);
+               ret = dsdb_module_load_partition_usn(ac->module, schema_dn,
+                                                    &current_usn, NULL, NULL);
                if (ret != LDB_SUCCESS) {
                        ldb_debug_set(ldb, LDB_DEBUG_ERROR,
                                      __location__": Searching for schema USN failed: %s\n",
index 3ce7ef9935c1c38b0a7d5ce967027b35150391f9..996b1f2238618964f5449a02d8832cf635530051 100644 (file)
@@ -144,6 +144,8 @@ static int schema_data_add(struct ldb_module *module, struct ldb_request *req)
        WERROR status;
        bool rodc = false;
        int ret;
+       struct schema_data_private_data *mc;
+       mc = talloc_get_type(ldb_module_get_private(module), struct schema_data_private_data);
 
        ldb = ldb_module_get_ctx(module);
 
@@ -162,12 +164,6 @@ static int schema_data_add(struct ldb_module *module, struct ldb_request *req)
                return ldb_next_request(module, req);
        }
 
-       if (schema->base_dn == NULL) {
-               ldb_debug_set(ldb, LDB_DEBUG_FATAL,
-                         "schema_data_add: base_dn NULL\n");
-               return LDB_ERR_OPERATIONS_ERROR;
-       }
-
        ret = samdb_rodc(ldb, &rodc);
        if (ret != LDB_SUCCESS) {
                DEBUG(4, (__location__ ": unable to tell if we are an RODC \n"));
@@ -190,7 +186,7 @@ static int schema_data_add(struct ldb_module *module, struct ldb_request *req)
                 * the provision code needs to create
                 * the schema root object.
                 */
-               cmp = ldb_dn_compare(req->op.add.message->dn, schema->base_dn);
+               cmp = ldb_dn_compare(req->op.add.message->dn, mc->schema_dn);
                if (cmp == 0) {
                        return ldb_next_request(module, req);
                }
@@ -201,7 +197,7 @@ static int schema_data_add(struct ldb_module *module, struct ldb_request *req)
                return ldb_oom(ldb);
        }
 
-       cmp = ldb_dn_compare(parent_dn, schema->base_dn);
+       cmp = ldb_dn_compare(parent_dn, mc->schema_dn);
        if (cmp != 0) {
                ldb_debug_set(ldb, LDB_DEBUG_ERROR,
                          "schema_data_add: no direct child :%s\n",
@@ -257,6 +253,8 @@ static int schema_data_modify(struct ldb_module *module, struct ldb_request *req
        bool rodc = false;
        int ret;
        struct ldb_control *sd_propagation_control;
+       struct schema_data_private_data *mc;
+       mc = talloc_get_type(ldb_module_get_private(module), struct schema_data_private_data);
 
        ldb = ldb_module_get_ctx(module);
 
@@ -295,7 +293,7 @@ static int schema_data_modify(struct ldb_module *module, struct ldb_request *req
                return ldb_next_request(module, req);
        }
 
-       cmp = ldb_dn_compare(req->op.mod.message->dn, schema->base_dn);
+       cmp = ldb_dn_compare(req->op.mod.message->dn, mc->schema_dn);
        if (cmp == 0) {
                static const char * const constrained_attrs[] = {
                        "schemaInfo",
index f19d0c5830ba45cc6e894c081fd968df7fbc791d..fc725dfc6eb92139e0499fba2ac63edee4f01286 100644 (file)
@@ -161,6 +161,7 @@ static struct dsdb_schema *dsdb_schema_refresh(struct ldb_module *module, struct
        int ret;
        struct ldb_context *ldb = ldb_module_get_ctx(module);
        struct dsdb_schema *new_schema;
+       struct ldb_dn *schema_dn = ldb_get_schema_basedn(ldb);
        time_t ts, lastts;      
        
        struct schema_load_private_data *private_data = talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
@@ -199,12 +200,12 @@ static struct dsdb_schema *dsdb_schema_refresh(struct ldb_module *module, struct
        }
        schema->last_refresh = ts;
 
-       ret = dsdb_module_load_partition_usn(module, schema->base_dn, &current_usn, NULL, NULL);
+       ret = dsdb_module_load_partition_usn(module, schema_dn, &current_usn, NULL, NULL);
        if (ret != LDB_SUCCESS || current_usn == schema->loaded_usn) {
                return schema;
        }
 
-       ret = dsdb_schema_from_db(module, schema->base_dn, current_usn, &new_schema);
+       ret = dsdb_schema_from_db(module, schema_dn, current_usn, &new_schema);
        if (ret != LDB_SUCCESS) {
                return schema;
        }
index 538b8581234c150ab405fda33513f2706d550f7b..68c39c239275075ea12fc450cb902e1c7f0a7684 100644 (file)
@@ -201,8 +201,6 @@ struct dsdb_schema_info {
 
 
 struct dsdb_schema {
-       struct ldb_dn *base_dn;
-
        struct dsdb_schema_prefixmap *prefixmap;
 
        /* 
index efbd38a4ba39540c994f52152d75b4a58d6e6c3f..43a6a89b3c33e06b1dd5549e6a6d531dd59c74bc 100644 (file)
@@ -58,12 +58,6 @@ struct dsdb_schema *dsdb_schema_copy_shallow(TALLOC_CTX *mem_ctx,
                return NULL;
        }
 
-       /* schema base_dn */
-       schema_copy->base_dn = ldb_dn_copy(schema_copy, schema->base_dn);
-       if (!schema_copy->base_dn) {
-               goto failed;
-       }
-
        /* copy prexiMap & schemaInfo */
        schema_copy->prefixmap = dsdb_schema_pfm_copy_shallow(schema_copy,
                                                              schema->prefixmap);
@@ -931,8 +925,6 @@ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
                                                              false);
        }
 
-       schema->base_dn = talloc_steal(schema, schema_res->msgs[0]->dn);
-
        prefix_val = ldb_msg_find_ldb_val(schema_res->msgs[0], "prefixMap");
        if (!prefix_val) {
                *error_string = talloc_asprintf(mem_ctx, 
index ce8facbef3c9e62f0ad027cf9d435cff44b30098..78c6e56bb50354ffb9e626082e593f90f9060362 100644 (file)
@@ -763,10 +763,6 @@ WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb,
        if (!schema) {
                goto nomem;
        }
-       schema->base_dn = ldb_dn_new(schema, ldb, dn);
-       if (!schema->base_dn) {
-               goto nomem;
-       }
        schema->fsmo.we_are_master = true;
        schema->fsmo.update_allowed = true;
        schema->fsmo.master_dn = ldb_dn_new(schema, ldb, "@PROVISION_SCHEMA_MASTER");
index 9e287edbb852de7b1453cb72dc85bec1f09dc0cc..69195af180c134ea687b04c2546c598d2076813b 100644 (file)
@@ -508,11 +508,6 @@ NTSTATUS libnet_vampire_cb_schema_chunk(void *private_data,
                s->self_made_schema = dsdb_new_schema(s);
                NT_STATUS_HAVE_NO_MEMORY(s->self_made_schema);
 
-               s->self_made_schema->base_dn = ldb_dn_new(s->self_made_schema,
-                                               s->ldb,
-                                               c->forest->schema_dn_str);
-               NT_STATUS_HAVE_NO_MEMORY(s->self_made_schema->base_dn);
-
                status = dsdb_load_prefixmap_from_drsuapi(s->self_made_schema, mapping_ctr);
                if (!W_ERROR_IS_OK(status)) {
                        return werror_to_ntstatus(status);