Factor out filling in the secrets database.
authorAndrew Bartlett <abartlet@samba.org>
Wed, 9 Apr 2008 04:56:24 +0000 (14:56 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 9 Apr 2008 04:56:24 +0000 (14:56 +1000)
This allows the vampire code to start with a join, but fill in the
secrets only when the process is compleated.

Andrew Bartlett

source/libnet/libnet_join.c
source/libnet/libnet_join.h

index 22134518d695a15b6c4625e2de7eea6fe58c8fb6..4549cd6e9349c05096c890d18011fa1873f35f1f 100644 (file)
@@ -839,13 +839,11 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
        return status;
 }
 
-static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, 
-                                          TALLOC_CTX *mem_ctx, 
-                                          struct libnet_Join *r)
+NTSTATUS libnet_set_join_secrets(struct libnet_context *ctx, 
+                                TALLOC_CTX *mem_ctx, 
+                                struct libnet_set_join_secrets *r)
 {
-       NTSTATUS status;
        TALLOC_CTX *tmp_mem;
-       struct libnet_JoinDomain *r2;
        int ret, rtn;
        struct ldb_context *ldb;
        struct ldb_dn *base_dn;
@@ -860,56 +858,13 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
                "privateKeytab",
                NULL
        };
-       uint32_t acct_type = 0;
-       const char *account_name;
-       const char *netbios_name;
-       
-       r->out.error_string = NULL;
 
        tmp_mem = talloc_new(mem_ctx);
        if (!tmp_mem) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       r2 = talloc(tmp_mem, struct libnet_JoinDomain);
-       if (!r2) {
-               r->out.error_string = NULL;
-               talloc_free(tmp_mem);
-               return NT_STATUS_NO_MEMORY;
-       }
-       
-       if (r->in.join_type == SEC_CHAN_BDC) {
-               acct_type = ACB_SVRTRUST;
-       } else if (r->in.join_type == SEC_CHAN_WKSTA) {
-               acct_type = ACB_WSTRUST;
-       } else {
-               r->out.error_string = NULL;
-               talloc_free(tmp_mem);   
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       if (r->in.netbios_name != NULL) {
-               netbios_name = r->in.netbios_name;
-       } else {
-               netbios_name = talloc_reference(tmp_mem, lp_netbios_name(ctx->lp_ctx));
-               if (!netbios_name) {
-                       r->out.error_string = NULL;
-                       talloc_free(tmp_mem);
-                       return NT_STATUS_NO_MEMORY;
-               }
-       }
-
-       account_name = talloc_asprintf(tmp_mem, "%s$", netbios_name);
-       if (!account_name) {
-               r->out.error_string = NULL;
-               talloc_free(tmp_mem);
-               return NT_STATUS_NO_MEMORY;
-       }
-       
-       /*
-        * Local secrets are stored in secrets.ldb 
-        * open it to make sure we can write the info into it after the join
-        */
+       /* Open the secrets database */
        ldb = secrets_db_connect(tmp_mem, ctx->lp_ctx);
        if (!ldb) {
                r->out.error_string
@@ -919,23 +874,6 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
                return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
        }
 
-       /*
-        * join the domain
-        */
-       ZERO_STRUCTP(r2);
-       r2->in.domain_name      = r->in.domain_name;
-       r2->in.account_name     = account_name;
-       r2->in.netbios_name     = netbios_name;
-       r2->in.level            = LIBNET_JOINDOMAIN_AUTOMATIC;
-       r2->in.acct_type        = acct_type;
-       r2->in.recreate_account = false;
-       status = libnet_JoinDomain(ctx, r2, r2);
-       if (!NT_STATUS_IS_OK(status)) {
-               r->out.error_string = talloc_steal(mem_ctx, r2->out.error_string);
-               talloc_free(tmp_mem);
-               return status;
-       }
-       
        /*
         * now prepare the record for secrets.ldb
         */
@@ -961,21 +899,21 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
        }
 
        msg->dn = ldb_dn_copy(tmp_mem, base_dn);
-       if ( ! ldb_dn_add_child_fmt(msg->dn, "flatname=%s", r2->out.domain_name)) {
+       if ( ! ldb_dn_add_child_fmt(msg->dn, "flatname=%s", r->in.domain_name)) {
                r->out.error_string = NULL;
                talloc_free(tmp_mem);
                return NT_STATUS_NO_MEMORY;
        }
        
-       rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "flatname", r2->out.domain_name);
+       rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "flatname", r->in.domain_name);
        if (rtn == -1) {
                r->out.error_string = NULL;
                talloc_free(tmp_mem);
                return NT_STATUS_NO_MEMORY;
        }
 
-       if (r2->out.realm) {
-               rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "realm", r2->out.realm);
+       if (r->in.realm) {
+               rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "realm", r->in.realm);
                if (rtn == -1) {
                        r->out.error_string = NULL;
                        talloc_free(tmp_mem);
@@ -997,14 +935,14 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
                return NT_STATUS_NO_MEMORY;
        }
 
-       rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "secret", r2->out.join_password);
+       rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "secret", r->in.join_password);
        if (rtn == -1) {
                r->out.error_string = NULL;
                talloc_free(tmp_mem);
                return NT_STATUS_NO_MEMORY;
        }
 
-       rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "samAccountName", r2->in.account_name);
+       rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "samAccountName", r->in.account_name);
        if (rtn == -1) {
                r->out.error_string = NULL;
                talloc_free(tmp_mem);
@@ -1018,9 +956,9 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
                return NT_STATUS_NO_MEMORY;
        }
 
-       if (r2->out.kvno) {
+       if (r->in.kvno) {
                rtn = samdb_msg_add_uint(ldb, tmp_mem, msg, "msDS-KeyVersionNumber",
-                                        r2->out.kvno);
+                                        r->in.kvno);
                if (rtn == -1) {
                        r->out.error_string = NULL;
                        talloc_free(tmp_mem);
@@ -1028,9 +966,9 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
                }
        }
 
-       if (r2->out.domain_sid) {
+       if (r->in.domain_sid) {
                rtn = samdb_msg_add_dom_sid(ldb, tmp_mem, msg, "objectSid",
-                                           r2->out.domain_sid);
+                                           r->in.domain_sid);
                if (rtn == -1) {
                        r->out.error_string = NULL;
                        talloc_free(tmp_mem);
@@ -1047,7 +985,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
                           tmp_mem, base_dn,
                           &msgs, attrs,
                           "(|" SECRETS_PRIMARY_DOMAIN_FILTER "(realm=%s))",
-                          r2->out.domain_name, r2->out.realm);
+                          r->in.domain_name, r->in.realm);
        if (ret == 0) {
                rtn = samdb_msg_set_string(ldb, tmp_mem, msg, "secretsKeytab", "secrets.keytab");
                if (rtn == -1) {
@@ -1059,7 +997,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
                r->out.error_string
                        = talloc_asprintf(mem_ctx, 
                                          "Search for domain: %s and realm: %s failed: %s", 
-                                         r2->out.domain_name, r2->out.realm, ldb_errstring(ldb));
+                                         r->in.domain_name, r->in.realm, ldb_errstring(ldb));
                talloc_free(tmp_mem);
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        } else {
@@ -1082,7 +1020,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
                                return NT_STATUS_NO_MEMORY;
                        }
                }
-               rtn = samdb_msg_set_string(ldb, tmp_mem, msg, "secret", r2->out.join_password);
+               rtn = samdb_msg_set_string(ldb, tmp_mem, msg, "secret", r->in.join_password);
                if (rtn == -1) {
                        r->out.error_string = NULL;
                        talloc_free(tmp_mem);
@@ -1101,7 +1039,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
                        }
                }
 
-               rtn = samdb_msg_set_string(ldb, tmp_mem, msg, "samAccountName", r2->in.account_name);
+               rtn = samdb_msg_set_string(ldb, tmp_mem, msg, "samAccountName", r->in.account_name);
                if (rtn == -1) {
                        r->out.error_string = NULL;
                        talloc_free(tmp_mem);
@@ -1146,6 +1084,104 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
 
+       return NT_STATUS_OK;
+}
+
+static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, 
+                                          TALLOC_CTX *mem_ctx, 
+                                          struct libnet_Join *r)
+{
+       NTSTATUS status;
+       TALLOC_CTX *tmp_mem;
+       struct libnet_JoinDomain *r2;
+       struct libnet_set_join_secrets *r3;
+       uint32_t acct_type = 0;
+       const char *account_name;
+       const char *netbios_name;
+       
+       r->out.error_string = NULL;
+
+       tmp_mem = talloc_new(mem_ctx);
+       if (!tmp_mem) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       r2 = talloc(tmp_mem, struct libnet_JoinDomain);
+       if (!r2) {
+               r->out.error_string = NULL;
+               talloc_free(tmp_mem);
+               return NT_STATUS_NO_MEMORY;
+       }
+       
+       if (r->in.join_type == SEC_CHAN_BDC) {
+               acct_type = ACB_SVRTRUST;
+       } else if (r->in.join_type == SEC_CHAN_WKSTA) {
+               acct_type = ACB_WSTRUST;
+       } else {
+               r->out.error_string = NULL;
+               talloc_free(tmp_mem);   
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       if (r->in.netbios_name != NULL) {
+               netbios_name = r->in.netbios_name;
+       } else {
+               netbios_name = talloc_reference(tmp_mem, lp_netbios_name(ctx->lp_ctx));
+               if (!netbios_name) {
+                       r->out.error_string = NULL;
+                       talloc_free(tmp_mem);
+                       return NT_STATUS_NO_MEMORY;
+               }
+       }
+
+       account_name = talloc_asprintf(tmp_mem, "%s$", netbios_name);
+       if (!account_name) {
+               r->out.error_string = NULL;
+               talloc_free(tmp_mem);
+               return NT_STATUS_NO_MEMORY;
+       }
+       
+       /*
+        * join the domain
+        */
+       ZERO_STRUCTP(r2);
+       r2->in.domain_name      = r->in.domain_name;
+       r2->in.account_name     = account_name;
+       r2->in.netbios_name     = netbios_name;
+       r2->in.level            = LIBNET_JOINDOMAIN_AUTOMATIC;
+       r2->in.acct_type        = acct_type;
+       r2->in.recreate_account = false;
+       status = libnet_JoinDomain(ctx, r2, r2);
+       if (!NT_STATUS_IS_OK(status)) {
+               r->out.error_string = talloc_steal(mem_ctx, r2->out.error_string);
+               talloc_free(tmp_mem);
+               return status;
+       }
+
+       r3 = talloc(tmp_mem, struct libnet_set_join_secrets);
+       if (!r3) {
+               r->out.error_string = NULL;
+               talloc_free(tmp_mem);
+               return NT_STATUS_NO_MEMORY;
+       }
+       
+       ZERO_STRUCTP(r3);
+       r3->in.domain_name = r2->out.domain_name;
+       r3->in.realm = r2->out.realm;
+       r3->in.account_name = account_name;
+       r3->in.netbios_name = netbios_name;
+       r3->in.join_type = r->in.join_type;
+       r3->in.join_password = r2->out.join_password;
+       r3->in.kvno = r2->out.kvno;
+       r3->in.domain_sid = r2->out.domain_sid;
+       
+       status = libnet_set_join_secrets(ctx, r3, r3);
+       if (!NT_STATUS_IS_OK(status)) {
+               r->out.error_string = talloc_steal(mem_ctx, r3->out.error_string);
+               talloc_free(tmp_mem);
+               return status;
+       }
+
        /* move all out parameter to the callers TALLOC_CTX */
        r->out.error_string     = NULL;
        r->out.join_password    = r2->out.join_password;
index 6da4564cb37065d1984e1e5c4e9728df3825fcc4..79884130d8a48743ac40ed5db6cfc3d38bd5a8a2 100644 (file)
@@ -79,5 +79,22 @@ struct libnet_Join {
        } out;
 };
 
+struct libnet_set_join_secrets {
+       struct {
+               const char *domain_name;
+               const char *realm;
+               const char *netbios_name;
+               const char *account_name;
+               enum netr_SchannelType join_type;
+               const char *join_password;
+               int kvno;
+               struct dom_sid *domain_sid;
+       } in;
+       
+       struct {
+               const char *error_string;
+       } out;
+};
+
 
 #endif /* __LIBNET_JOIN_H__ */