s4-dsdb Add ability to force a particular SID in the upgrade case
[idra/samba.git] / source4 / dsdb / common / util_samr.c
index deaea2e07fa60538c7e4c5cd5fa105ee8c55bff5..3ce8d76018da191bb004596b470cffea6ee78347 100644 (file)
@@ -36,6 +36,7 @@ NTSTATUS dsdb_add_user(struct ldb_context *ldb,
                       TALLOC_CTX *mem_ctx,
                       const char *account_name,
                       uint32_t acct_flags,
+                      const struct dom_sid *forced_sid,
                       struct dom_sid **sid,
                       struct ldb_dn **dn)
 {
@@ -143,6 +144,18 @@ NTSTATUS dsdb_add_user(struct ldb_context *ldb,
        ldb_msg_add_string(msg, "sAMAccountName", account_name);
        ldb_msg_add_string(msg, "objectClass", obj_class);
 
+       /* This is only here for migrations using pdb_samba4, the
+        * caller and the samldb are responsible for ensuring it makes
+        * sense */
+       if (forced_sid) {
+               ret = samdb_msg_add_dom_sid(ldb, msg, msg, "objectSID", forced_sid);
+               if (ret != LDB_SUCCESS) {
+                       ldb_transaction_cancel(ldb);
+                       talloc_free(tmp_ctx);
+                       return NT_STATUS_INTERNAL_ERROR;
+               }
+       }
+
        /* create the user */
        ret = ldb_add(ldb, msg);
        switch (ret) {
@@ -244,7 +257,9 @@ NTSTATUS dsdb_add_user(struct ldb_context *ldb,
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
        *dn = talloc_steal(mem_ctx, account_dn);
-       *sid = talloc_steal(mem_ctx, account_sid);
+       if (sid) {
+               *sid = talloc_steal(mem_ctx, account_sid);
+       }
        talloc_free(tmp_ctx);
        return NT_STATUS_OK;
 }
@@ -342,6 +357,11 @@ NTSTATUS dsdb_add_domain_alias(struct ldb_context *ldb,
        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
        NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
 
+       if (ldb_transaction_start(ldb) != LDB_SUCCESS) {
+               DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(ldb)));
+               return NT_STATUS_INTERNAL_ERROR;
+       }
+
        /* Check if alias already exists */
        name = samdb_search_string(ldb, tmp_ctx, NULL,
                                   "sAMAccountName",
@@ -350,12 +370,14 @@ NTSTATUS dsdb_add_domain_alias(struct ldb_context *ldb,
 
        if (name != NULL) {
                talloc_free(tmp_ctx);
+               ldb_transaction_cancel(ldb);
                return NT_STATUS_ALIAS_EXISTS;
        }
 
        msg = ldb_msg_new(tmp_ctx);
        if (msg == NULL) {
                talloc_free(tmp_ctx);
+               ldb_transaction_cancel(ldb);
                return NT_STATUS_NO_MEMORY;
        }
 
@@ -364,6 +386,7 @@ NTSTATUS dsdb_add_domain_alias(struct ldb_context *ldb,
        ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=Users", alias_name);
        if (!msg->dn) {
                talloc_free(tmp_ctx);
+               ldb_transaction_cancel(ldb);
                return NT_STATUS_NO_MEMORY;
        }
 
@@ -378,15 +401,18 @@ NTSTATUS dsdb_add_domain_alias(struct ldb_context *ldb,
                break;
        case LDB_ERR_ENTRY_ALREADY_EXISTS:
                talloc_free(tmp_ctx);
+               ldb_transaction_cancel(ldb);
                return NT_STATUS_ALIAS_EXISTS;
        case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
                talloc_free(tmp_ctx);
+               ldb_transaction_cancel(ldb);
                return NT_STATUS_ACCESS_DENIED;
        default:
                DEBUG(0,("Failed to create alias record %s: %s\n",
                         ldb_dn_get_linearized(msg->dn),
                         ldb_errstring(ldb)));
                talloc_free(tmp_ctx);
+               ldb_transaction_cancel(ldb);
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
 
@@ -394,10 +420,17 @@ NTSTATUS dsdb_add_domain_alias(struct ldb_context *ldb,
        alias_sid = samdb_search_dom_sid(ldb, tmp_ctx,
                                         msg->dn, "objectSid", NULL);
 
+       if (ldb_transaction_commit(ldb) != LDB_SUCCESS) {
+               DEBUG(0, ("Failed to commit transaction in dsdb_add_domain_alias(): %s\n",
+                         ldb_errstring(ldb)));
+               return NT_STATUS_INTERNAL_ERROR;
+       }
+
        *dn = talloc_steal(mem_ctx, msg->dn);
        *sid = talloc_steal(mem_ctx, alias_sid);
        talloc_free(tmp_ctx);
 
+
        return NT_STATUS_OK;
 }
 
@@ -507,7 +540,7 @@ NTSTATUS dsdb_lookup_rids(struct ldb_context *ldb,
                                    dom_sid_string(tmp_ctx,
                                                   dom_sid_add_rid(tmp_ctx, domain_sid,
                                                                   rids[i])));
-               if (!dn || !ldb_dn_validate(dn)) {
+               if (dn == NULL) {
                        talloc_free(tmp_ctx);
                        return NT_STATUS_NO_MEMORY;
                }