net: fix the order of DC lookup methods when joining a domain
authorUri Simchoni <urisimchoni@gmail.com>
Sun, 28 Jun 2015 11:36:22 +0000 (14:36 +0300)
committerJeremy Allison <jra@samba.org>
Thu, 9 Jul 2015 10:33:25 +0000 (12:33 +0200)
The dsgetdcname() function is able to try just DNS lookup, just NetBIOS,
or start with DNS and fall back to NetBIOS. For "net ads join", we know
most of the time whether the name of the domain we're joining is a DNS
name or a NetBIOS name. In that case, it makes no sense to try both lookup
methods, especially that DNS may fail and we want to fall back from site-aware
DNS lookup to site-less DNS lookup, with no NetBIOS lookup in between.

This change lets "net ads join" tell libnet what is the type of the domain
name, if it is known.

Signed-off-by: Uri Simchoni <urisimchoni@gmail.com>
Reviewed-by: Volker Lendecke <Volker.Lendecke@SerNet.DE>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/libnet/libnet_join.c
source3/librpc/idl/libnet_join.idl
source3/utils/net_ads.c

index 66f302a9b1752375f920aeda69a574a37d7335b7..3e58b18baca4f2cb98327d0f481e4073845e6b14 100644 (file)
@@ -2226,6 +2226,12 @@ static WERROR libnet_DomainJoin(TALLOC_CTX *mem_ctx,
        if (!r->in.dc_name) {
                struct netr_DsRGetDCNameInfo *info;
                const char *dc;
+               uint32_t name_type_flags = 0;
+               if (r->in.domain_name_type == JoinDomNameTypeDNS) {
+                       name_type_flags = DS_IS_DNS_NAME;
+               } else if (r->in.domain_name_type == JoinDomNameTypeNBT) {
+                       name_type_flags = DS_IS_FLAT_NAME;
+               }
                status = dsgetdcname(mem_ctx,
                                     r->in.msg_ctx,
                                     r->in.domain_name,
@@ -2234,7 +2240,8 @@ static WERROR libnet_DomainJoin(TALLOC_CTX *mem_ctx,
                                     DS_FORCE_REDISCOVERY |
                                     DS_DIRECTORY_SERVICE_REQUIRED |
                                     DS_WRITABLE_REQUIRED |
-                                    DS_RETURN_DNS_NAME,
+                                    DS_RETURN_DNS_NAME |
+                                    name_type_flags,
                                     &info);
                if (!NT_STATUS_IS_OK(status)) {
                        libnet_join_set_error_string(mem_ctx, r,
index cb2d9e4dcd922d0591c184f85746dbe9f77c6306..61c117eb3b9a3aae7add2f39fb0b1d2145fbfc66 100644 (file)
@@ -15,10 +15,17 @@ interface libnetjoin
        typedef bitmap wkssvc_joinflags wkssvc_joinflags;
        typedef enum netr_SchannelType netr_SchannelType;
 
+       typedef [public] enum {
+               JoinDomNameTypeUnknown = 0,
+               JoinDomNameTypeDNS = 1,
+               JoinDomNameTypeNBT = 2
+       } libnetjoin_JoinDomNameType;
+
        [nopush,nopull,noopnum] WERROR libnet_JoinCtx(
                [in] string dc_name,
                [in] string machine_name,
                [in,ref] string *domain_name,
+               [in] libnetjoin_JoinDomNameType domain_name_type,
                [in] string account_ou,
                [in] string admin_account,
                [in] string admin_domain,
index a8f3892bb29eb1b0550a6205f3ba7cac3f001b07..28553fcadc87f78f8bd2b81dc7c1dd3396eb526b 100644 (file)
@@ -1439,6 +1439,7 @@ int net_ads_join(struct net_context *c, int argc, const char **argv)
        const char *os_version = NULL;
        const char *os_servicepack = NULL;
        bool modify_config = lp_config_backend_is_registry();
+       enum libnetjoin_JoinDomNameType domain_name_type = JoinDomNameTypeDNS;
 
        if (c->display_usage)
                return net_ads_join_usage(c, argc, argv);
@@ -1511,6 +1512,11 @@ int net_ads_join(struct net_context *c, int argc, const char **argv)
                }
                else {
                        domain = argv[i];
+                       if (strchr(domain, '.') == NULL) {
+                               domain_name_type = JoinDomNameTypeUnknown;
+                       } else {
+                               domain_name_type = JoinDomNameTypeDNS;
+                       }
                }
        }
 
@@ -1530,6 +1536,7 @@ int net_ads_join(struct net_context *c, int argc, const char **argv)
        /* Do the domain join here */
 
        r->in.domain_name       = domain;
+       r->in.domain_name_type  = domain_name_type;
        r->in.create_upn        = createupn;
        r->in.upn               = machineupn;
        r->in.account_ou        = create_in_ou;
@@ -1552,6 +1559,7 @@ int net_ads_join(struct net_context *c, int argc, const char **argv)
        if (W_ERROR_EQUAL(werr, WERR_DCNOTFOUND) &&
            strequal(domain, lp_realm())) {
                r->in.domain_name = lp_workgroup();
+               r->in.domain_name_type = JoinDomNameTypeNBT;
                werr = libnet_Join(ctx, r);
        }
        if (!W_ERROR_IS_OK(werr)) {