Rearrange libnet join code and add support for account pre-creation in AD.
authorGünther Deschner <gd@samba.org>
Mon, 7 Jan 2008 18:07:38 +0000 (19:07 +0100)
committerGünther Deschner <gd@samba.org>
Mon, 7 Jan 2008 18:39:11 +0000 (19:39 +0100)
Guenther

source/libnet/libnet_join.c

index 7c8b395cd35aff793fad6e8e57cf9e4d2ae10dfb..1d52b81a75a6805a77e5e631e569205ccc080428 100644 (file)
@@ -155,6 +155,39 @@ static ADS_STATUS libnet_unjoin_connect_ads(TALLOC_CTX *mem_ctx,
 /****************************************************************
 ****************************************************************/
 
+static ADS_STATUS libnet_join_precreate_machine_acct(TALLOC_CTX *mem_ctx,
+                                                    struct libnet_JoinCtx *r)
+{
+       ADS_STATUS status;
+       LDAPMessage *res = NULL;
+       const char *attrs[] = { "dn", NULL };
+
+       status = ads_search_dn(r->in.ads, &res, r->in.account_ou, attrs);
+       if (!ADS_ERR_OK(status)) {
+               return status;
+       }
+
+       if (ads_count_replies(r->in.ads, res) != 1) {
+               ads_msgfree(r->in.ads, res);
+               return ADS_ERROR_LDAP(LDAP_NO_SUCH_OBJECT);
+       }
+
+       status = ads_create_machine_acct(r->in.ads,
+                                        r->in.machine_name,
+                                        r->in.account_ou);
+       ads_msgfree(r->in.ads, res);
+
+       if ((status.error_type == ENUM_ADS_ERROR_LDAP) &&
+           (status.err.rc == LDAP_ALREADY_EXISTS)) {
+               status = ADS_SUCCESS;
+       }
+
+       return status;
+}
+
+/****************************************************************
+****************************************************************/
+
 static bool libnet_join_joindomain_store_secrets(TALLOC_CTX *mem_ctx,
                                                 struct libnet_JoinCtx *r)
 {
@@ -174,6 +207,9 @@ static bool libnet_join_joindomain_store_secrets(TALLOC_CTX *mem_ctx,
        return true;
 }
 
+/****************************************************************
+****************************************************************/
+
 static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx,
                                           struct libnet_JoinCtx *r)
 {
@@ -362,6 +398,9 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx,
        return status;
 }
 
+/****************************************************************
+****************************************************************/
+
 static bool libnet_join_unjoindomain_remove_secrets(TALLOC_CTX *mem_ctx,
                                                    struct libnet_UnjoinCtx *r)
 {
@@ -376,6 +415,9 @@ static bool libnet_join_unjoindomain_remove_secrets(TALLOC_CTX *mem_ctx,
        return true;
 }
 
+/****************************************************************
+****************************************************************/
+
 static NTSTATUS libnet_join_unjoindomain_rpc(TALLOC_CTX *mem_ctx,
                                             struct libnet_UnjoinCtx *r)
 {
@@ -481,6 +523,9 @@ done:
        return status;
 }
 
+/****************************************************************
+****************************************************************/
+
 static WERROR do_join_modify_vals_config(struct libnet_JoinCtx *r)
 {
        WERROR werr;
@@ -519,6 +564,9 @@ static WERROR do_join_modify_vals_config(struct libnet_JoinCtx *r)
        return werr;
 }
 
+/****************************************************************
+****************************************************************/
+
 static WERROR do_unjoin_modify_vals_config(struct libnet_UnjoinCtx *r)
 {
        WERROR werr = WERR_OK;
@@ -534,6 +582,8 @@ static WERROR do_unjoin_modify_vals_config(struct libnet_UnjoinCtx *r)
        return werr;
 }
 
+/****************************************************************
+****************************************************************/
 
 static WERROR do_JoinConfig(struct libnet_JoinCtx *r)
 {
@@ -558,6 +608,9 @@ static WERROR do_JoinConfig(struct libnet_JoinCtx *r)
        return werr;
 }
 
+/****************************************************************
+****************************************************************/
+
 static WERROR do_UnjoinConfig(struct libnet_UnjoinCtx *r)
 {
        WERROR werr;
@@ -651,11 +704,54 @@ WERROR libnet_init_UnjoinCtx(TALLOC_CTX *mem_ctx,
        return WERR_OK;
 }
 
+/****************************************************************
+****************************************************************/
+
+static WERROR libnet_DomainJoin(TALLOC_CTX *mem_ctx,
+                               struct libnet_JoinCtx *r)
+{
+       NTSTATUS status;
+       ADS_STATUS ads_status;
+
+       if (r->in.account_ou) {
+               ads_status = libnet_join_connect_ads(mem_ctx, r);
+               if (!ADS_ERR_OK(ads_status)) {
+                       return WERR_GENERAL_FAILURE;
+               }
+               ads_status = libnet_join_precreate_machine_acct(mem_ctx, r);
+               if (!ADS_ERR_OK(ads_status)) {
+                       libnet_join_set_error_string(mem_ctx, r,
+                               "failed to precreate account in ou %s: %s\n",
+                               r->in.account_ou,
+                               ads_errstr(ads_status));
+                       return WERR_GENERAL_FAILURE;
+               }
+
+               r->in.join_flags &= ~WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE;
+       }
+
+       status = libnet_join_joindomain_rpc(mem_ctx, r);
+       if (!NT_STATUS_IS_OK(status)) {
+               if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
+                       return WERR_SETUP_ALREADY_JOINED;
+               }
+               return ntstatus_to_werror(status);
+       }
+
+       if (!libnet_join_joindomain_store_secrets(mem_ctx, r)) {
+               return WERR_SETUP_NOT_JOINED;
+       }
+
+       return WERR_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
 WERROR libnet_Join(TALLOC_CTX *mem_ctx,
                   struct libnet_JoinCtx *r)
 {
        WERROR werr;
-       NTSTATUS status;
 
        if (!r->in.domain_name) {
                return WERR_INVALID_PARAM;
@@ -670,17 +766,9 @@ WERROR libnet_Join(TALLOC_CTX *mem_ctx,
        }
 
        if (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
-
-               status = libnet_join_joindomain_rpc(mem_ctx, r);
-               if (!NT_STATUS_IS_OK(status)) {
-                       if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
-                               return WERR_SETUP_ALREADY_JOINED;
-                       }
-                       return ntstatus_to_werror(status);
-               }
-
-               if (!libnet_join_joindomain_store_secrets(mem_ctx, r)) {
-                       return WERR_SETUP_NOT_JOINED;
+               werr = libnet_DomainJoin(mem_ctx, r);
+               if (!W_ERROR_IS_OK(werr)) {
+                       return werr;
                }
        }