The branch, master has been updated
       via  06aefe4 s3:libnet:libnet_join: update msDS-SupportedEncryptionTypes 
(if required) with machine creds.
       via  5d498d1 s3:libnet:libnet_join: fill in output enctypes and only 
modify when necessary.
       via  e0da059 s3:libnet:libnet_join: define list of desired encryption 
types only once.
       via  4a49f6f s3:librpc:idl:libnet_join: add encryption types to 
libnet_JoinCtx.
       via  df8f79c s3:libnet:libnet_join: always try to create machineaccount 
via LDAP first.
       via  c61b111 s3:libads:ldap: fix ads_check_ou_dn to deal with account_ou 
not being initialized
       via  e8f6acd s3:libads:ndr: add ADS_AUTH_USER_CREDS to 
ndr_print_ads_auth_flags()
       via  34030b0 s3:libads:ldap: print LDAP error message with log level 10.
       via  71d5634 s3:libnet:libnet_join: prepare to allow connecting with 
machine creds.
       via  6686f67 Partly revert "s3:libads: setup the 
msDS-SupportedEncryptionTypes attribute on ldap_add"
      from  e8e0ffc tests: Allow alternative error code for backupkey test

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 06aefe4b956ae8748e20ae4c730aa344e81808b6
Author: Günther Deschner <[email protected]>
Date:   Fri Mar 11 23:15:06 2016 +0100

    s3:libnet:libnet_join: update msDS-SupportedEncryptionTypes (if required) 
with machine creds.
    
    Guenther
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11755
    
    Pair-Programmed-With: Stefan Metzmacher <[email protected]>
    
    Signed-off-by: Guenther Deschner <[email protected]>
    Signed-off-by: Stefan Metzmacher <[email protected]>
    
    Autobuild-User(master): Stefan Metzmacher <[email protected]>
    Autobuild-Date(master): Mon Mar 14 19:38:48 CET 2016 on sn-devel-144

commit 5d498d1b4d9b83f179fb7b2841a19ad984eec5f8
Author: Günther Deschner <[email protected]>
Date:   Fri Mar 11 16:05:53 2016 +0100

    s3:libnet:libnet_join: fill in output enctypes and only modify when 
necessary.
    
    Guenther
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11755
    
    Signed-off-by: Guenther Deschner <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>

commit e0da059b39f9dd5ccb74f32f965e1ced384c77eb
Author: Günther Deschner <[email protected]>
Date:   Fri Mar 11 16:04:52 2016 +0100

    s3:libnet:libnet_join: define list of desired encryption types only once.
    
    Guenther
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11755
    
    Signed-off-by: Guenther Deschner <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>

commit 4a49f6fac9d6c77d1eedf914308e67eb6e2baa8d
Author: Günther Deschner <[email protected]>
Date:   Fri Mar 11 16:02:27 2016 +0100

    s3:librpc:idl:libnet_join: add encryption types to libnet_JoinCtx.
    
    Guenther
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11755
    
    Signed-off-by: Guenther Deschner <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>

commit df8f79cc9d44ad7b2caa6b86b7ebde7bb1fd4c8c
Author: Günther Deschner <[email protected]>
Date:   Thu Mar 10 18:03:47 2016 +0100

    s3:libnet:libnet_join: always try to create machineaccount via LDAP first.
    
    Guenther
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11755
    
    Signed-off-by: Guenther Deschner <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>

commit c61b111e6fa3e138d4d9cf5038b69644248e834a
Author: Günther Deschner <[email protected]>
Date:   Fri Mar 11 12:15:14 2016 +0100

    s3:libads:ldap: fix ads_check_ou_dn to deal with account_ou not being 
initialized
    
    Guenther
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11755
    
    Signed-off-by: Guenther Deschner <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>

commit e8f6acdeece990dc8953d494113dee856d80da45
Author: Günther Deschner <[email protected]>
Date:   Fri Mar 11 12:13:24 2016 +0100

    s3:libads:ndr: add ADS_AUTH_USER_CREDS to ndr_print_ads_auth_flags()
    
    Guenther
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11755
    
    Signed-off-by: Guenther Deschner <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>

commit 34030b025b9e4cd5e7321d6e242f6c03da2a60c0
Author: Günther Deschner <[email protected]>
Date:   Fri Mar 4 17:42:05 2016 +0100

    s3:libads:ldap: print LDAP error message with log level 10.
    
    Guenther
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11755
    
    Signed-off-by: Guenther Deschner <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>

commit 71d5634ab58f0ca21db633990231bd01a22c956c
Author: Günther Deschner <[email protected]>
Date:   Wed Mar 2 18:07:53 2016 +0100

    s3:libnet:libnet_join: prepare to allow connecting with machine creds.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11755
    
    Guenther
    
    Signed-off-by: Guenther Deschner <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>

commit 6686f67d2a91146c8bb2fb2a8104fcaa5710b855
Author: Günther Deschner <[email protected]>
Date:   Fri Mar 11 23:14:13 2016 +0100

    Partly revert "s3:libads: setup the msDS-SupportedEncryptionTypes attribute 
on ldap_add"
    
    This partly reverts commit 0c74d62524db376b6a3fac00c688be0cdffcaa80.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11755
    
    Signed-off-by: Günther Deschner <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>

-----------------------------------------------------------------------

Summary of changes:
 source3/libads/ads_proto.h         |   6 +-
 source3/libads/ldap.c              |  44 +++++---
 source3/libads/ndr.c               |   1 +
 source3/libnet/libnet_join.c       | 220 +++++++++++++++++++++++++++++++++++--
 source3/librpc/idl/libnet_join.idl |   4 +-
 5 files changed, 248 insertions(+), 27 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/libads/ads_proto.h b/source3/libads/ads_proto.h
index 1399f41..425c352 100644
--- a/source3/libads/ads_proto.h
+++ b/source3/libads/ads_proto.h
@@ -97,8 +97,10 @@ ADS_STATUS ads_get_service_principal_names(TALLOC_CTX 
*mem_ctx,
 ADS_STATUS ads_clear_service_principal_names(ADS_STRUCT *ads, const char 
*machine_name);
 ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char 
*machine_name,
                                           const char *my_fqdn, const char 
*spn);
-ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, const char *machine_name,
-                                   const char *org_unit);
+ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads,
+                                  const char *machine_name,
+                                  const char *org_unit,
+                                  uint32_t etype_list);
 ADS_STATUS ads_move_machine_acct(ADS_STRUCT *ads, const char *machine_name,
                                  const char *org_unit, bool *moved);
 int ads_count_replies(ADS_STRUCT *ads, void *res);
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index 028046b..9e2ed98 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -1344,7 +1344,7 @@ char *ads_parent_dn(const char *dn)
 {
        ADS_STATUS status;
        char *expr;
-       const char *attrs[] = {"*", "nTSecurityDescriptor", NULL};
+       const char *attrs[] = {"*", "msDS-SupportedEncryptionTypes", 
"nTSecurityDescriptor", NULL};
 
        *res = NULL;
 
@@ -1494,6 +1494,17 @@ static ADS_STATUS ads_mod_ber(TALLOC_CTX *ctx, 
ADS_MODLIST *mods,
 }
 #endif
 
+static void ads_print_error(int ret, LDAP *ld)
+{
+       if (ret != 0) {
+               char *ld_error = NULL;
+               ldap_get_option(ld, LDAP_OPT_ERROR_STRING, &ld_error);
+               DEBUG(10,("AD LDAP failure %d (%s):\n%s\n", ret,
+                       ldap_err2string(ret), ld_error));
+               SAFE_FREE(ld_error);
+       }
+}
+
 /**
  * Perform an ldap modify
  * @param ads connection to ads server
@@ -1529,6 +1540,7 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char 
*mod_dn, ADS_MODLIST mods)
        mods[i] = NULL;
        ret = ldap_modify_ext_s(ads->ldap.ld, utf8_dn,
                                (LDAPMod **) mods, controls, NULL);
+       ads_print_error(ret, ads->ldap.ld);
        TALLOC_FREE(utf8_dn);
        return ADS_ERROR(ret);
 }
@@ -1557,6 +1569,7 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char 
*new_dn, ADS_MODLIST mods)
        mods[i] = NULL;
 
        ret = ldap_add_s(ads->ldap.ld, utf8_dn, (LDAPMod**)mods);
+       ads_print_error(ret, ads->ldap.ld);
        TALLOC_FREE(utf8_dn);
        return ADS_ERROR(ret);
 }
@@ -1578,6 +1591,7 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn)
        }
 
        ret = ldap_delete_s(ads->ldap.ld, utf8_dn);
+       ads_print_error(ret, ads->ldap.ld);
        TALLOC_FREE(utf8_dn);
        return ADS_ERROR(ret);
 }
@@ -2063,8 +2077,10 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT 
*ads, const char *machine_n
  * @return 0 upon success, or non-zero otherwise
 **/
 
-ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, const char *machine_name, 
-                                   const char *org_unit)
+ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads,
+                                  const char *machine_name,
+                                  const char *org_unit,
+                                  uint32_t etype_list)
 {
        ADS_STATUS ret;
        char *samAccountName, *controlstr;
@@ -2116,16 +2132,8 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, 
const char *machine_name,
        ads_mod_str(ctx, &mods, "userAccountControl", controlstr);
 
        if (func_level >= DS_DOMAIN_FUNCTION_2008) {
-               uint32_t etype_list = ENC_CRC32 | ENC_RSA_MD5 | 
ENC_RC4_HMAC_MD5;
                const char *etype_list_str;
 
-#ifdef HAVE_ENCTYPE_AES128_CTS_HMAC_SHA1_96
-               etype_list |= ENC_HMAC_SHA1_96_AES128;
-#endif
-#ifdef HAVE_ENCTYPE_AES256_CTS_HMAC_SHA1_96
-               etype_list |= ENC_HMAC_SHA1_96_AES256;
-#endif
-
                etype_list_str = talloc_asprintf(ctx, "%d", (int)etype_list);
                if (etype_list_str == NULL) {
                        goto done;
@@ -3927,10 +3935,16 @@ ADS_STATUS ads_check_ou_dn(TALLOC_CTX *mem_ctx,
        const char *name;
        char *ou_string;
 
-       exploded_dn = ldap_explode_dn(*account_ou, 0);
-       if (exploded_dn) {
-               ldap_value_free(exploded_dn);
-               return ADS_SUCCESS;
+       if (account_ou == NULL) {
+               return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+       }
+
+       if (*account_ou != NULL) {
+               exploded_dn = ldap_explode_dn(*account_ou, 0);
+               if (exploded_dn) {
+                       ldap_value_free(exploded_dn);
+                       return ADS_SUCCESS;
+               }
        }
 
        ou_string = ads_ou_string(ads, *account_ou);
diff --git a/source3/libads/ndr.c b/source3/libads/ndr.c
index eb48437..957c0fa 100644
--- a/source3/libads/ndr.c
+++ b/source3/libads/ndr.c
@@ -37,6 +37,7 @@ static void ndr_print_ads_auth_flags(struct ndr_print *ndr, 
const char *name, ui
        ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "ADS_AUTH_SASL_SIGN", 
ADS_AUTH_SASL_SIGN, r);
        ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "ADS_AUTH_SASL_SEAL", 
ADS_AUTH_SASL_SEAL, r);
        ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "ADS_AUTH_SASL_FORCE", 
ADS_AUTH_SASL_FORCE, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "ADS_AUTH_USER_CREDS", 
ADS_AUTH_USER_CREDS, r);
        ndr->depth--;
 }
 
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index fc737a2..235592c 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -42,6 +42,7 @@
 #include "lib/param/loadparm.h"
 #include "libcli/auth/netlogon_creds_cli.h"
 #include "auth/credentials/credentials.h"
+#include "krb5_env.h"
 
 /****************************************************************
 ****************************************************************/
@@ -118,6 +119,7 @@ static ADS_STATUS libnet_connect_ads(const char 
*dns_domain_name,
                                     const char *dc_name,
                                     const char *user_name,
                                     const char *password,
+                                    const char *ccname,
                                     ADS_STRUCT **ads)
 {
        ADS_STATUS status;
@@ -150,6 +152,12 @@ static ADS_STATUS libnet_connect_ads(const char 
*dns_domain_name,
                my_ads->auth.password = SMB_STRDUP(password);
        }
 
+       if (ccname != NULL) {
+               SAFE_FREE(my_ads->auth.ccache_name);
+               my_ads->auth.ccache_name = SMB_STRDUP(ccname);
+               setenv(KRB5_ENV_CCNAME, my_ads->auth.ccache_name, 1);
+       }
+
        status = ads_connect_user_creds(my_ads);
        if (!ADS_ERR_OK(status)) {
                ads_destroy(&my_ads);
@@ -164,15 +172,51 @@ static ADS_STATUS libnet_connect_ads(const char 
*dns_domain_name,
 ****************************************************************/
 
 static ADS_STATUS libnet_join_connect_ads(TALLOC_CTX *mem_ctx,
-                                         struct libnet_JoinCtx *r)
+                                         struct libnet_JoinCtx *r,
+                                         bool use_machine_creds)
 {
        ADS_STATUS status;
+       const char *username;
+       const char *password;
+       const char *ccname = NULL;
+
+       if (use_machine_creds) {
+               if (r->in.machine_name == NULL ||
+                   r->in.machine_password == NULL) {
+                       return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               }
+               username = talloc_strdup(mem_ctx, r->in.machine_name);
+               if (username == NULL) {
+                       return ADS_ERROR(LDAP_NO_MEMORY);
+               }
+               if (username[strlen(username)] != '$') {
+                       username = talloc_asprintf(username, "%s$", username);
+                       if (username == NULL) {
+                               return ADS_ERROR(LDAP_NO_MEMORY);
+                       }
+               }
+               password = r->in.machine_password;
+               ccname = "MEMORY:libnet_join_machine_creds";
+       } else {
+               username = r->in.admin_account;
+               password = r->in.admin_password;
+
+               /*
+                * when r->in.use_kerberos is set to allow "net ads join -k" we
+                * may not override the provided credential cache - gd
+                */
+
+               if (!r->in.use_kerberos) {
+                       ccname = "MEMORY:libnet_join_user_creds";
+               }
+       }
 
        status = libnet_connect_ads(r->out.dns_domain_name,
                                    r->out.netbios_domain_name,
                                    r->in.dc_name,
-                                   r->in.admin_account,
-                                   r->in.admin_password,
+                                   username,
+                                   password,
+                                   ccname,
                                    &r->in.ads);
        if (!ADS_ERR_OK(status)) {
                libnet_join_set_error_string(mem_ctx, r,
@@ -201,6 +245,24 @@ static ADS_STATUS libnet_join_connect_ads(TALLOC_CTX 
*mem_ctx,
 /****************************************************************
 ****************************************************************/
 
+static ADS_STATUS libnet_join_connect_ads_user(TALLOC_CTX *mem_ctx,
+                                              struct libnet_JoinCtx *r)
+{
+       return libnet_join_connect_ads(mem_ctx, r, false);
+}
+
+/****************************************************************
+****************************************************************/
+
+static ADS_STATUS libnet_join_connect_ads_machine(TALLOC_CTX *mem_ctx,
+                                                 struct libnet_JoinCtx *r)
+{
+       return libnet_join_connect_ads(mem_ctx, r, true);
+}
+
+/****************************************************************
+****************************************************************/
+
 static ADS_STATUS libnet_unjoin_connect_ads(TALLOC_CTX *mem_ctx,
                                            struct libnet_UnjoinCtx *r)
 {
@@ -211,6 +273,7 @@ static ADS_STATUS libnet_unjoin_connect_ads(TALLOC_CTX 
*mem_ctx,
                                    r->in.dc_name,
                                    r->in.admin_account,
                                    r->in.admin_password,
+                                   NULL,
                                    &r->in.ads);
        if (!ADS_ERR_OK(status)) {
                libnet_unjoin_set_error_string(mem_ctx, r,
@@ -255,7 +318,8 @@ static ADS_STATUS 
libnet_join_precreate_machine_acct(TALLOC_CTX *mem_ctx,
 
        status = ads_create_machine_acct(r->in.ads,
                                         r->in.machine_name,
-                                        r->in.account_ou);
+                                        r->in.account_ou,
+                                        r->in.desired_encryption_types);
 
        if (ADS_ERR_OK(status)) {
                DEBUG(1,("machine account creation created\n"));
@@ -353,6 +417,11 @@ static ADS_STATUS libnet_join_find_machine_acct(TALLOC_CTX 
*mem_ctx,
                goto done;
        }
 
+       if (!ads_pull_uint32(r->in.ads, res, "msDS-SupportedEncryptionTypes",
+                            &r->out.set_encryption_types)) {
+               r->out.set_encryption_types = 0;
+       }
+
  done:
        ads_msgfree(r->in.ads, res);
        TALLOC_FREE(dn);
@@ -616,6 +685,56 @@ static ADS_STATUS libnet_join_set_os_attributes(TALLOC_CTX 
*mem_ctx,
 /****************************************************************
 ****************************************************************/
 
+static ADS_STATUS libnet_join_set_etypes(TALLOC_CTX *mem_ctx,
+                                        struct libnet_JoinCtx *r)
+{
+       ADS_STATUS status;
+       ADS_MODLIST mods;
+       const char *etype_list_str;
+
+       etype_list_str = talloc_asprintf(mem_ctx, "%d",
+                                        r->in.desired_encryption_types);
+       if (!etype_list_str) {
+               return ADS_ERROR(LDAP_NO_MEMORY);
+       }
+
+       /* Find our DN */
+
+       status = libnet_join_find_machine_acct(mem_ctx, r);
+       if (!ADS_ERR_OK(status)) {
+               return status;
+       }
+
+       if (r->in.desired_encryption_types == r->out.set_encryption_types) {
+               return ADS_SUCCESS;
+       }
+
+       /* now do the mods */
+
+       mods = ads_init_mods(mem_ctx);
+       if (!mods) {
+               return ADS_ERROR(LDAP_NO_MEMORY);
+       }
+
+       status = ads_mod_str(mem_ctx, &mods, "msDS-SupportedEncryptionTypes",
+                            etype_list_str);
+       if (!ADS_ERR_OK(status)) {
+               return status;
+       }
+
+       status = ads_gen_mod(r->in.ads, r->out.dn, mods);
+       if (!ADS_ERR_OK(status)) {
+               return status;
+       }
+
+       r->out.set_encryption_types = r->in.desired_encryption_types;
+
+       return ADS_SUCCESS;
+}
+
+/****************************************************************
+****************************************************************/
+
 static bool libnet_join_create_keytab(TALLOC_CTX *mem_ctx,
                                      struct libnet_JoinCtx *r)
 {
@@ -690,9 +809,10 @@ static ADS_STATUS 
libnet_join_post_processing_ads(TALLOC_CTX *mem_ctx,
                                                  struct libnet_JoinCtx *r)
 {
        ADS_STATUS status;
+       bool need_etype_update = false;
 
        if (!r->in.ads) {
-               status = libnet_join_connect_ads(mem_ctx, r);
+               status = libnet_join_connect_ads_user(mem_ctx, r);
                if (!ADS_ERR_OK(status)) {
                        return status;
                }
@@ -724,6 +844,56 @@ static ADS_STATUS 
libnet_join_post_processing_ads(TALLOC_CTX *mem_ctx,
                return status;
        }
 
+       status = libnet_join_find_machine_acct(mem_ctx, r);
+       if (!ADS_ERR_OK(status)) {
+               return status;
+       }
+
+       if (r->in.desired_encryption_types != r->out.set_encryption_types) {
+               uint32_t func_level = 0;
+
+               status = ads_domain_func_level(r->in.ads, &func_level);
+               if (!ADS_ERR_OK(status)) {
+                       libnet_join_set_error_string(mem_ctx, r,
+                               "failed to query domain controller functional 
level: %s",
+                               ads_errstr(status));
+                       return status;
+               }
+
+               if (func_level >= DS_DOMAIN_FUNCTION_2008) {
+                       need_etype_update = true;
+               }
+       }
+
+       if (need_etype_update) {
+               /*
+                * We need to reconnect as machine account in order
+                * to update msDS-SupportedEncryptionTypes reliable
+                */
+
+               if (r->in.ads->auth.ccache_name != NULL) {
+                       ads_kdestroy(r->in.ads->auth.ccache_name);
+               }
+
+               ads_destroy(&r->in.ads);
+
+               status = libnet_join_connect_ads_machine(mem_ctx, r);
+               if (!ADS_ERR_OK(status)) {
+                       libnet_join_set_error_string(mem_ctx, r,
+                               "Failed to connect as machine account: %s",
+                               ads_errstr(status));
+                       return status;
+               }
+
+               status = libnet_join_set_etypes(mem_ctx, r);
+               if (!ADS_ERR_OK(status)) {
+                       libnet_join_set_error_string(mem_ctx, r,
+                               "failed to set machine kerberos encryption 
types: %s",
+                               ads_errstr(status));
+                       return status;
+               }
+       }
+
        if (!libnet_join_derive_salting_principal(mem_ctx, r)) {
                return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
        }
@@ -2026,6 +2196,16 @@ WERROR libnet_init_JoinCtx(TALLOC_CTX *mem_ctx,
 
        ctx->in.secure_channel_type = SEC_CHAN_WKSTA;
 
+       ctx->in.desired_encryption_types = ENC_CRC32 |
+                                          ENC_RSA_MD5 |
+                                          ENC_RC4_HMAC_MD5;
+#ifdef HAVE_ENCTYPE_AES128_CTS_HMAC_SHA1_96
+       ctx->in.desired_encryption_types |= ENC_HMAC_SHA1_96_AES128;
+#endif
+#ifdef HAVE_ENCTYPE_AES256_CTS_HMAC_SHA1_96
+       ctx->in.desired_encryption_types |= ENC_HMAC_SHA1_96_AES256;
+#endif
+
        *r = ctx;
 
        return WERR_OK;
@@ -2262,16 +2442,36 @@ static WERROR libnet_DomainJoin(TALLOC_CTX *mem_ctx,
                r->out.dns_domain_name, r->out.netbios_domain_name,
                NULL, smbXcli_conn_remote_sockaddr(cli->conn));
 
-       if (r->out.domain_is_ad && r->in.account_ou &&
+       if (r->out.domain_is_ad &&
            !(r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_UNSECURE)) {
 
-               ads_status = libnet_join_connect_ads(mem_ctx, r);
+               const char *initial_account_ou = r->in.account_ou;
+
+               /*
+                * we want to create the msDS-SupportedEncryptionTypes attribute
+                * as early as possible so always try an LDAP create as the user
+                * first. We copy r->in.account_ou because it may be changed
+                * during the machine pre-creation.
+                */
+
+               ads_status = libnet_join_connect_ads_user(mem_ctx, r);
                if (!ADS_ERR_OK(ads_status)) {
                        return WERR_DEFAULT_JOIN_REQUIRED;
                }
 
                ads_status = libnet_join_precreate_machine_acct(mem_ctx, r);
-               if (!ADS_ERR_OK(ads_status)) {
+               if (ADS_ERR_OK(ads_status)) {
+
+                       /*
+                        * LDAP object create succeeded, now go to the rpc
+                        * password set routines
+                        */
+
+                       r->in.join_flags &= ~WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE;
+                       goto rpc_join;
+               }
+
+               if (initial_account_ou != NULL) {
                        libnet_join_set_error_string(mem_ctx, r,
                                "failed to precreate account in ou %s: %s",
                                r->in.account_ou,
@@ -2279,10 +2479,12 @@ static WERROR libnet_DomainJoin(TALLOC_CTX *mem_ctx,
                        return WERR_DEFAULT_JOIN_REQUIRED;
                }
 
-               r->in.join_flags &= ~WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE;
+               DEBUG(5, ("failed to precreate account in ou %s: %s",
+                       r->in.account_ou, ads_errstr(ads_status)));
        }
 #endif /* HAVE_ADS */
 
+ rpc_join:
        if ((r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_UNSECURE) &&
            (r->in.join_flags & WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED)) {
                status = libnet_join_joindomain_rpc_unsecure(mem_ctx, r, cli);
diff --git a/source3/librpc/idl/libnet_join.idl 
b/source3/librpc/idl/libnet_join.idl
index 61c117e..63ea1df 100644
--- a/source3/librpc/idl/libnet_join.idl
+++ b/source3/librpc/idl/libnet_join.idl
@@ -43,6 +43,7 @@ interface libnetjoin
                [in] boolean8 use_kerberos,
                [in] netr_SchannelType secure_channel_type,
                [in,noprint] messaging_context *msg_ctx,
+               [in] uint32 desired_encryption_types,
                [out] string account_name,
                [out] string netbios_domain_name,
                [out] string dns_domain_name,
@@ -51,7 +52,8 @@ interface libnetjoin
                [out] dom_sid *domain_sid,
                [out] boolean8 modified_config,
                [out] string error_string,
-               [out] boolean8 domain_is_ad
+               [out] boolean8 domain_is_ad,
+               [out] uint32 set_encryption_types
                );
 
        [nopush,nopull,noopnum] WERROR libnet_UnjoinCtx(


-- 
Samba Shared Repository

Reply via email to