passdb: Do not routinely clear the global memory returned by get_global_sam_sid()
[bbaumbach/samba-autobuild/.git] / source3 / passdb / pdb_samba_dsdb.c
index 01e747a00fc71ea054681fb69f2c39ac861ce4c3..e9255c7cfc551ec86fc3b6c4ab7d586e03f2e655 100644 (file)
@@ -339,6 +339,7 @@ static int pdb_samba_dsdb_replace_by_sam(struct pdb_samba_dsdb_state *state,
 
        msg = ldb_msg_new(frame);
        if (!msg) {
+               talloc_free(frame);
                return false;
        }
 
@@ -375,6 +376,7 @@ static int pdb_samba_dsdb_replace_by_sam(struct pdb_samba_dsdb_state *state,
                                           pw, strlen(pw),
                                           (void *)&pw_utf16.data,
                                           &pw_utf16.length)) {
+                       talloc_free(frame);
                        return LDB_ERR_OPERATIONS_ERROR;
                }
                ret |= ldb_msg_add_value(msg, "clearTextPassword", &pw_utf16, NULL);
@@ -1011,6 +1013,7 @@ static NTSTATUS pdb_samba_dsdb_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
 
        status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
        if (!NT_STATUS_IS_OK(status)) {
+               talloc_free(tmp_ctx);
                return status;
        }
        status = pdb_samba_dsdb_getgrsid(m, map, *id_map.sid);
@@ -1521,6 +1524,7 @@ static NTSTATUS pdb_samba_dsdb_delete_alias(struct pdb_methods *m,
 
        if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
                DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(state->ldb)));
+               talloc_free(tmp_ctx);
                return NT_STATUS_INTERNAL_ERROR;
        }
 
@@ -1542,15 +1546,18 @@ static NTSTATUS pdb_samba_dsdb_delete_alias(struct pdb_methods *m,
                DEBUG(10, ("ldb_delete failed %s\n",
                           ldb_errstring(state->ldb)));
                ldb_transaction_cancel(state->ldb);
+               talloc_free(tmp_ctx);
                return NT_STATUS_LDAP(rc);
        }
 
        if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
                DEBUG(0, ("Failed to commit transaction in pdb_samba_dsdb_delete_alias(): %s\n",
                          ldb_errstring(state->ldb)));
+               talloc_free(tmp_ctx);
                return NT_STATUS_INTERNAL_ERROR;
        }
 
+       talloc_free(tmp_ctx);
        return NT_STATUS_OK;
 }
 
@@ -2061,6 +2068,7 @@ static bool pdb_samba_dsdb_gid_to_sid(struct pdb_methods *m, gid_t gid,
 
        status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
        if (!NT_STATUS_IS_OK(status)) {
+               talloc_free(tmp_ctx);
                return false;
        }
        *sid = *id_map.sid;
@@ -2210,6 +2218,10 @@ static void free_private_data(void **vp)
 static NTSTATUS pdb_samba_dsdb_init_secrets(struct pdb_methods *m)
 {
        struct pdb_domain_info *dom_info;
+       struct dom_sid stored_sid;
+       struct GUID stored_guid;
+       bool sid_exists_and_matches = false;
+       bool guid_exists_and_matches = false;
        bool ret;
 
        dom_info = pdb_samba_dsdb_get_domain_info(m, m);
@@ -2217,20 +2229,38 @@ static NTSTATUS pdb_samba_dsdb_init_secrets(struct pdb_methods *m)
                return NT_STATUS_UNSUCCESSFUL;
        }
 
-       secrets_clear_domain_protection(dom_info->name);
-       ret = secrets_store_domain_sid(dom_info->name,
-                                      &dom_info->sid);
-       if (!ret) {
-               goto done;
+       ret = secrets_fetch_domain_sid(dom_info->name, &stored_sid);
+       if (ret) {
+               if (dom_sid_equal(&stored_sid, &dom_info->sid)) {
+                       sid_exists_and_matches = true;
+               }
        }
-       ret = secrets_store_domain_guid(dom_info->name,
-                                       &dom_info->guid);
-       if (!ret) {
-               goto done;
+
+       if (sid_exists_and_matches == false) {
+               secrets_clear_domain_protection(dom_info->name);
+               ret = secrets_store_domain_sid(dom_info->name,
+                                              &dom_info->sid);
+               ret &= secrets_mark_domain_protected(dom_info->name);
+               if (!ret) {
+                       goto done;
+               }
        }
-       ret = secrets_mark_domain_protected(dom_info->name);
-       if (!ret) {
-               goto done;
+
+       ret = secrets_fetch_domain_guid(dom_info->name, &stored_guid);
+       if (ret) {
+               if (GUID_equal(&stored_guid, &dom_info->guid)) {
+                       guid_exists_and_matches = true;
+               }
+       }
+
+       if (guid_exists_and_matches == false) {
+               secrets_clear_domain_protection(dom_info->name);
+               ret = secrets_store_domain_guid(dom_info->name,
+                                              &dom_info->guid);
+               ret &= secrets_mark_domain_protected(dom_info->name);
+               if (!ret) {
+                       goto done;
+               }
        }
 
 done: