s4-repl: fixed memory leaks
authorAndrew Tridgell <tridge@samba.org>
Sat, 12 Sep 2009 05:22:26 +0000 (15:22 +1000)
committerAndrew Tridgell <tridge@samba.org>
Sat, 12 Sep 2009 05:22:26 +0000 (15:22 +1000)
These memory leaks were mostly caused by the fact that
refresh_partitions is now called periodically

source4/dsdb/repl/drepl_out_helpers.c
source4/dsdb/repl/drepl_partitions.c
source4/dsdb/repl/drepl_periodic.c

index 59b31764449b8a56c23c919bad5e9d32e081c79a..e90f2783b145866d5c0ff41f4e864f5fbf4e9948 100644 (file)
@@ -464,10 +464,8 @@ static void dreplsrv_update_refs_recv(struct rpc_request *req)
 
        c->status = dcerpc_ndr_request_recv(req);
        if (!composite_is_ok(c)) {
-               DEBUG(0,("UpdateRefs failed with %s for %s %s\n", 
-                        nt_errstr(c->status),
-                        r->in.req.req1.dest_dsa_dns_name,
-                        r->in.req.req1.naming_context->dn));
+               DEBUG(0,("UpdateRefs failed with %s\n", 
+                        nt_errstr(c->status)));
                return;
        }
 
index 88c4bbf0652545573a5a7644052755dec034d477..85412a793c5becb7ddc1552859c11476a4db8f77 100644 (file)
@@ -148,7 +148,7 @@ static WERROR dreplsrv_partition_add_source_dsa(struct dreplsrv_service *s,
 {
        WERROR status;
        enum ndr_err_code ndr_err;
-       struct dreplsrv_partition_source_dsa *source;
+       struct dreplsrv_partition_source_dsa *source, *s2;
 
        source = talloc_zero(p, struct dreplsrv_partition_source_dsa);
        W_ERROR_HAVE_NO_MEMORY(source);
@@ -158,10 +158,12 @@ static WERROR dreplsrv_partition_add_source_dsa(struct dreplsrv_service *s,
                                       (ndr_pull_flags_fn_t)ndr_pull_repsFromToBlob);
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
                NTSTATUS nt_status = ndr_map_error2ntstatus(ndr_err);
+               talloc_free(source);
                return ntstatus_to_werror(nt_status);
        }
        /* NDR_PRINT_DEBUG(repsFromToBlob, &source->_repsFromBlob); */
        if (source->_repsFromBlob.version != 1) {
+               talloc_free(source);
                return WERR_DS_DRA_INTERNAL_ERROR;
        }
 
@@ -171,13 +173,24 @@ static WERROR dreplsrv_partition_add_source_dsa(struct dreplsrv_service *s,
        status = dreplsrv_out_connection_attach(s, source->repsFrom1, &source->conn);
        W_ERROR_NOT_OK_RETURN(status);
 
+       /* remove any existing source with the same GUID */
+       for (s2=p->sources; s2; s2=s2->next) {
+               if (GUID_compare(&s2->repsFrom1->source_dsa_obj_guid, 
+                                &source->repsFrom1->source_dsa_obj_guid) == 0) {
+                       talloc_free(s2->repsFrom1->other_info);
+                       *s2->repsFrom1 = *source->repsFrom1;
+                       talloc_steal(s2, s2->repsFrom1->other_info);
+                       talloc_free(source);
+                       return WERR_OK;
+               }
+       }
+
        DLIST_ADD_END(p->sources, source, struct dreplsrv_partition_source_dsa *);
        return WERR_OK;
 }
 
 static WERROR dreplsrv_refresh_partition(struct dreplsrv_service *s,
-                                        struct dreplsrv_partition *p,
-                                        TALLOC_CTX *mem_ctx)
+                                        struct dreplsrv_partition *p)
 {
        WERROR status;
        const struct ldb_val *ouv_value;
@@ -187,6 +200,7 @@ static WERROR dreplsrv_refresh_partition(struct dreplsrv_service *s,
        struct ldb_result *r;
        uint32_t i;
        int ret;
+       TALLOC_CTX *mem_ctx = talloc_new(p);
        static const char *attrs[] = {
                "objectSid",
                "objectGUID",
@@ -201,12 +215,14 @@ static WERROR dreplsrv_refresh_partition(struct dreplsrv_service *s,
        ret = ldb_search(s->samdb, mem_ctx, &r, p->dn, LDB_SCOPE_BASE, attrs,
                         "(objectClass=*)");
        if (ret != LDB_SUCCESS) {
+               talloc_free(mem_ctx);
                return WERR_FOOBAR;
        } else if (r->count != 1) {
-               talloc_free(r);
+               talloc_free(mem_ctx);
                return WERR_FOOBAR;
        }
-
+       
+       talloc_free(discard_const(p->nc.dn));
        ZERO_STRUCT(p->nc);
        p->nc.dn        = ldb_dn_alloc_linearized(p, p->dn);
        W_ERROR_HAVE_NO_MEMORY(p->nc.dn);
@@ -214,6 +230,7 @@ static WERROR dreplsrv_refresh_partition(struct dreplsrv_service *s,
        nc_sid          = samdb_result_dom_sid(p, r->msgs[0], "objectSid");
        if (nc_sid) {
                p->nc.sid       = *nc_sid;
+               talloc_free(nc_sid);
        }
 
        ouv_value = ldb_msg_find_ldb_val(r->msgs[0], "replUpToDateVector");
@@ -224,15 +241,18 @@ static WERROR dreplsrv_refresh_partition(struct dreplsrv_service *s,
                                               (ndr_pull_flags_fn_t)ndr_pull_replUpToDateVectorBlob);
                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
                        NTSTATUS nt_status = ndr_map_error2ntstatus(ndr_err);
+                       talloc_free(mem_ctx);
                        return ntstatus_to_werror(nt_status);
                }
                /* NDR_PRINT_DEBUG(replUpToDateVectorBlob, &ouv); */
                if (ouv.version != 2) {
+                       talloc_free(mem_ctx);
                        return WERR_DS_DRA_INTERNAL_ERROR;
                }
 
                p->uptodatevector.count         = ouv.ctr.ctr2.count;
                p->uptodatevector.reserved      = ouv.ctr.ctr2.reserved;
+               talloc_free(p->uptodatevector.cursors);
                p->uptodatevector.cursors       = talloc_steal(p, ouv.ctr.ctr2.cursors);
        }
 
@@ -249,7 +269,7 @@ static WERROR dreplsrv_refresh_partition(struct dreplsrv_service *s,
                }
        }
 
-       talloc_free(r);
+       talloc_free(mem_ctx);
 
        return WERR_OK;
 }
@@ -260,7 +280,7 @@ WERROR dreplsrv_refresh_partitions(struct dreplsrv_service *s)
        struct dreplsrv_partition *p;
 
        for (p = s->partitions; p; p = p->next) {
-               status = dreplsrv_refresh_partition(s, p, p);
+               status = dreplsrv_refresh_partition(s, p);
                W_ERROR_NOT_OK_RETURN(status);
        }
 
index 36d5f924be5ac07e51f806add97d46ed190a7440..2cfcb310dcffcdabc325275026d47a630dd0612c 100644 (file)
@@ -103,7 +103,8 @@ static void dreplsrv_periodic_run(struct dreplsrv_service *service)
        dreplsrv_schedule_pull_replication(service, mem_ctx);
        talloc_free(mem_ctx);
 
-       DEBUG(2,("dreplsrv_periodic_run(): run pending_ops\n"));
+       DEBUG(2,("dreplsrv_periodic_run(): run pending_ops memory=%u\n", 
+                (unsigned)talloc_total_blocks(service)));
 
        /* the KCC might have changed repsFrom */
        dreplsrv_refresh_partitions(service);