From 0ef46723cad274d0fe7948a67b33f9f20fab3f0d Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <ab@samba.org>
Date: Tue, 7 Jan 2020 19:25:53 +0200
Subject: [PATCH 1/7] s3-rpcserver: fix security level check for
DsRGetForestTrustInformation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Harmonize _netr_DsRGetForestTrustInformation with source4/ logic which
didn't change since DCE RPC channel refactoring.
With the current code we return RPC faul as can be seen in the logs:
2019/12/11 17:12:55.463081, 1, pid=20939, effective(1284200000, 1284200000), real(1284200000, 0), class=rpc_parse] ../librpc/ndr/ndr.c:471(ndr_print_function_debug)
netr_DsRGetForestTrustInformation: struct netr_DsRGetForestTrustInformation
in: struct netr_DsRGetForestTrustInformation
server_name : *
server_name : '\\some-dc.example.com'
trusted_domain_name : NULL
flags : 0x00000000 (0)
[2019/12/11 17:12:55.463122, 4, pid=20939, effective(1284200000, 1284200000), real(1284200000, 0), class=rpc_srv] ../source3/rpc_server/srv_pipe.c:1561(api_rpcTNP)
api_rpcTNP: fault(5) return.
This is due to this check in processing a request:
if (!(p->pipe_bound && (p->auth.auth_type != DCERPC_AUTH_TYPE_NONE)
&& (p->auth.auth_level != DCERPC_AUTH_LEVEL_NONE))) {
p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
return WERR_ACCESS_DENIED;
}
and since we get AuthZ response,
Successful AuthZ: [netlogon,ncacn_np] user [EXAMPLE]\[admin] [S-1-5-21-1234567-890123456-500] at [Wed, 11 Dec 2019 17:12:55.461164 UTC]
Remote host [ipv4:Y.Y.Y.Y:59017] local host [ipv4:X.X.X.X:445]
[2019/12/11 17:12:55.461584, 4, pid=20939, effective(0, 0), real(0, 0)] ../lib/audit_logging/audit_logging.c:141(audit_log_json)
JSON Authorization: {"timestamp": "2019-12-11T17:12:55.461491+0000",
"type": "Authorization", "Authorization": {"version": {"major": 1, "minor": 1},
"localAddress": "ipv4:X.X.X.X:445", "remoteAddress": "ipv4:Y.Y.Y.Y:59017",
"serviceDescription": "netlogon", "authType": "ncacn_np",
"domain": "EXAMPLE", "account": "admin", "sid": "S-1-5-21-1234567-890123456-500",
"sessionId": "c5a2386f-f2cc-4241-9a9e-d104cf5859d5", "logonServer": "SOME-DC",
"transportProtection": "SMB", "accountFlags": "0x00000010"}}
this means we are actually getting anonymous DCE/RPC access to netlogon
on top of authenticated SMB connection. In such case we have exactly
auth_type set to DCERPC_AUTH_TYPE_NONE and auth_level set to
DCERPC_AUTH_LEVEL_NONE in the pipe->auth. Thus, returning an error.
Update the code to follow the same security level check as in s4 variant
of the call.
Signed-off-by: Alexander Bokovoy <ab@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
Autobuild-User(master): Günther Deschner <gd@samba.org>
Autobuild-Date(master): Mon Jan 13 15:05:28 UTC 2020 on sn-devel-184
(cherry picked from commit c6d880a115095c336b8b74f45854a99abb1bbb87)
---
source3/rpc_server/netlogon/srv_netlog_nt.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
index d799ba4feef..87613b99fde 100644
--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
@@ -2425,10 +2425,10 @@ WERROR _netr_DsRGetForestTrustInformation(struct pipes_struct *p,
{
NTSTATUS status;
struct lsa_ForestTrustInformation *info, **info_ptr;
+ enum security_user_level security_level;
- if (!(p->pipe_bound && (p->auth.auth_type != DCERPC_AUTH_TYPE_NONE)
- && (p->auth.auth_level != DCERPC_AUTH_LEVEL_NONE))) {
- p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
+ security_level = security_session_user_level(p->session_info, NULL);
+ if (security_level < SECURITY_USER) {
return WERR_ACCESS_DENIED;
}
--
2.26.2
From 67c40147a3c1da49a8d407282e1917ed3be511b0 Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Wed, 27 May 2020 16:50:45 +0200
Subject: [PATCH 2/7] Add a test to check dNSHostName with netbios aliases
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14396
Signed-off-by: Isaac Boukris <iboukris@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
---
selftest/knownfail.d/nb_alias_dnshostname | 2 ++
testprogs/blackbox/test_net_ads.sh | 14 ++++++++++++++
2 files changed, 16 insertions(+)
create mode 100644 selftest/knownfail.d/nb_alias_dnshostname
diff --git a/selftest/knownfail.d/nb_alias_dnshostname b/selftest/knownfail.d/nb_alias_dnshostname
new file mode 100644
index 00000000000..3c14e9931b9
--- /dev/null
+++ b/selftest/knownfail.d/nb_alias_dnshostname
@@ -0,0 +1,2 @@
+^samba4.blackbox.net_ads.nb_alias check dNSHostName
+^samba4.blackbox.net_ads.nb_alias check main SPN
diff --git a/testprogs/blackbox/test_net_ads.sh b/testprogs/blackbox/test_net_ads.sh
index 95c0cf76f90..6073ea972f9 100755
--- a/testprogs/blackbox/test_net_ads.sh
+++ b/testprogs/blackbox/test_net_ads.sh
@@ -220,6 +220,20 @@ testit_grep "dns alias addl" $dns_alias2 $VALGRIND $net_tool ads search -P samac
##Goodbye...
testit "leave" $VALGRIND $net_tool ads leave -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1`
+# netbios aliases tests
+testit "join nb_alias" $VALGRIND $net_tool --option=netbiosaliases=nb_alias1,nb_alias2 ads join -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1`
+
+testit "testjoin nb_alias" $VALGRIND $net_tool ads testjoin || failed=`expr $failed + 1`
+
+testit_grep "nb_alias check dNSHostName" $fqdn $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ dNSHostName || failed=`expr $failed + 1`
+testit_grep "nb_alias check main SPN" ${uc_netbios}.${lc_realm} $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ servicePrincipalName || failed=`expr $failed + 1`
+
+testit_grep "nb_alias1 SPN" nb_alias1 $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ servicePrincipalName || failed=`expr $failed + 1`
+testit_grep "nb_alias2 SPN" nb_alias2 $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ servicePrincipalName || failed=`expr $failed + 1`
+
+##Goodbye...
+testit "leave" $VALGRIND $net_tool ads leave -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1`
+
#
# Test createcomputer option of 'net ads join'
#
--
2.26.2
From b3e19ea4f4f366e7f6b99114c71f65c303402ef8 Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Wed, 27 May 2020 15:52:46 +0200
Subject: [PATCH 3/7] Fix accidental overwrite of dnsHostName by the last
netbios alias
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14396
Signed-off-by: Isaac Boukris <iboukris@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
---
selftest/knownfail.d/nb_alias_dnshostname | 2 --
source3/libnet/libnet_join.c | 5 +++--
2 files changed, 3 insertions(+), 4 deletions(-)
delete mode 100644 selftest/knownfail.d/nb_alias_dnshostname
diff --git a/selftest/knownfail.d/nb_alias_dnshostname b/selftest/knownfail.d/nb_alias_dnshostname
deleted file mode 100644
index 3c14e9931b9..00000000000
--- a/selftest/knownfail.d/nb_alias_dnshostname
+++ /dev/null
@@ -1,2 +0,0 @@
-^samba4.blackbox.net_ads.nb_alias check dNSHostName
-^samba4.blackbox.net_ads.nb_alias check main SPN
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index 9d4f656ffec..a31011b0ff8 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -507,6 +507,7 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
ADS_STATUS status;
ADS_MODLIST mods;
fstring my_fqdn;
+ fstring my_alias;
const char **spn_array = NULL;
size_t num_spns = 0;
char *spn = NULL;
@@ -587,11 +588,11 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
/*
* Add HOST/netbiosname.domainname
*/
- fstr_sprintf(my_fqdn, "%s.%s",
+ fstr_sprintf(my_alias, "%s.%s",
*netbios_aliases,
lp_dnsdomain());
- spn = talloc_asprintf(frame, "HOST/%s", my_fqdn);
+ spn = talloc_asprintf(frame, "HOST/%s", my_alias);
if (spn == NULL) {
status = ADS_ERROR_LDAP(LDAP_NO_MEMORY);
goto done;
--
2.26.2
From 134c761913dcf84c8c18751a8ba9cc3652995138 Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Thu, 24 Oct 2019 19:04:51 +0300
Subject: [PATCH 4/7] Refactor ads_keytab_add_entry() to make it iterable
so we can more easily add msDS-AdditionalDnsHostName entries.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14396
Signed-off-by: Isaac Boukris <iboukris@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
---
source3/libads/kerberos_keytab.c | 197 +++++++++++++++++--------------
1 file changed, 107 insertions(+), 90 deletions(-)
diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c
index 97d5535041c..0f450a09df5 100644
--- a/source3/libads/kerberos_keytab.c
+++ b/source3/libads/kerberos_keytab.c
@@ -228,18 +228,16 @@ out:
return ok;
}
-/**********************************************************************
- Adds a single service principal, i.e. 'host' to the system keytab
-***********************************************************************/
-
-int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, bool update_ads)
+static int add_kt_entry_etypes(krb5_context context, TALLOC_CTX *tmpctx,
+ ADS_STRUCT *ads, const char *salt_princ_s,
+ krb5_keytab keytab, krb5_kvno kvno,
+ const char *srvPrinc, const char *my_fqdn,
+ krb5_data *password, bool update_ads)
{
krb5_error_code ret = 0;
- krb5_context context = NULL;
- krb5_keytab keytab = NULL;
- krb5_data password;
- krb5_kvno kvno;
- krb5_enctype enctypes[6] = {
+ char *princ_s = NULL;
+ char *short_princ_s = NULL;
+ krb5_enctype enctypes[6] = {
ENCTYPE_DES_CBC_CRC,
ENCTYPE_DES_CBC_MD5,
#ifdef HAVE_ENCTYPE_AES128_CTS_HMAC_SHA1_96
@@ -251,65 +249,7 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, bool update_ads)
ENCTYPE_ARCFOUR_HMAC,
0
};
- char *princ_s = NULL;
- char *short_princ_s = NULL;
- char *salt_princ_s = NULL;
- char *password_s = NULL;
- char *my_fqdn;
- TALLOC_CTX *tmpctx = NULL;
- int i;
-
- ret = smb_krb5_init_context_common(&context);
- if (ret) {
- DBG_ERR("kerberos init context failed (%s)\n",
- error_message(ret));
- return -1;
- }
-
- ret = ads_keytab_open(context, &keytab);
- if (ret != 0) {
- goto out;
- }
-
- /* retrieve the password */
- if (!secrets_init()) {
- DEBUG(1, (__location__ ": secrets_init failed\n"));
- ret = -1;
- goto out;
- }
- password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
- if (!password_s) {
- DEBUG(1, (__location__ ": failed to fetch machine password\n"));
- ret = -1;
- goto out;
- }
- ZERO_STRUCT(password);
- password.data = password_s;
- password.length = strlen(password_s);
-
- /* we need the dNSHostName value here */
- tmpctx = talloc_init(__location__);
- if (!tmpctx) {
- DEBUG(0, (__location__ ": talloc_init() failed!\n"));
- ret = -1;
- goto out;
- }
-
- my_fqdn = ads_get_dnshostname(ads, tmpctx, lp_netbios_name());
- if (!my_fqdn) {
- DEBUG(0, (__location__ ": unable to determine machine "
- "account's dns name in AD!\n"));
- ret = -1;
- goto out;
- }
-
- /* make sure we have a single instance of a the computer account */
- if (!ads_has_samaccountname(ads, tmpctx, lp_netbios_name())) {
- DEBUG(0, (__location__ ": unable to determine machine "
- "account's short name in AD!\n"));
- ret = -1;
- goto out;
- }
+ size_t i;
/* Construct our principal */
if (strchr_m(srvPrinc, '@')) {
@@ -358,22 +298,6 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, bool update_ads)
}
}
- kvno = (krb5_kvno)ads_get_machine_kvno(ads, lp_netbios_name());
- if (kvno == -1) {
- /* -1 indicates failure, everything else is OK */
- DEBUG(1, (__location__ ": ads_get_machine_kvno failed to "
- "determine the system's kvno.\n"));
- ret = -1;
- goto out;
- }
-
- salt_princ_s = kerberos_secrets_fetch_salt_princ();
- if (salt_princ_s == NULL) {
- DBG_WARNING("kerberos_secrets_fetch_salt_princ() failed\n");
- ret = -1;
- goto out;
- }
-
for (i = 0; enctypes[i]; i++) {
/* add the fqdn principal to the keytab */
@@ -383,11 +307,11 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, bool update_ads)
princ_s,
salt_princ_s,
enctypes[i],
- &password,
+ password,
false,
false);
if (ret) {
- DEBUG(1, (__location__ ": Failed to add entry to keytab\n"));
+ DBG_WARNING("Failed to add entry to keytab\n");
goto out;
}
@@ -399,16 +323,109 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, bool update_ads)
short_princ_s,
salt_princ_s,
enctypes[i],
- &password,
+ password,
false,
false);
if (ret) {
- DEBUG(1, (__location__
- ": Failed to add short entry to keytab\n"));
+ DBG_WARNING("Failed to add short entry to keytab\n");
goto out;
}
}
}
+out:
+ return ret;
+}
+
+/**********************************************************************
+ Adds a single service principal, i.e. 'host' to the system keytab
+***********************************************************************/
+
+int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, bool update_ads)
+{
+ krb5_error_code ret = 0;
+ krb5_context context = NULL;
+ krb5_keytab keytab = NULL;
+ krb5_data password;
+ krb5_kvno kvno;
+ char *salt_princ_s = NULL;
+ char *password_s = NULL;
+ char *my_fqdn;
+ TALLOC_CTX *tmpctx = NULL;
+
+ ret = smb_krb5_init_context_common(&context);
+ if (ret) {
+ DBG_ERR("kerberos init context failed (%s)\n",
+ error_message(ret));
+ return -1;
+ }
+
+ ret = ads_keytab_open(context, &keytab);
+ if (ret != 0) {
+ goto out;
+ }
+
+ /* retrieve the password */
+ if (!secrets_init()) {
+ DBG_WARNING("secrets_init failed\n");
+ ret = -1;
+ goto out;
+ }
+ password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
+ if (!password_s) {
+ DBG_WARNING("failed to fetch machine password\n");
+ ret = -1;
+ goto out;
+ }
+ ZERO_STRUCT(password);
+ password.data = password_s;
+ password.length = strlen(password_s);
+
+ /* we need the dNSHostName value here */
+ tmpctx = talloc_init(__location__);
+ if (!tmpctx) {
+ DBG_ERR("talloc_init() failed!\n");
+ ret = -1;
+ goto out;
+ }
+
+ my_fqdn = ads_get_dnshostname(ads, tmpctx, lp_netbios_name());
+ if (!my_fqdn) {
+ DBG_ERR("unable to determine machine account's dns name in "
+ "AD!\n");
+ ret = -1;
+ goto out;
+ }
+
+ /* make sure we have a single instance of a the computer account */
+ if (!ads_has_samaccountname(ads, tmpctx, lp_netbios_name())) {
+ DBG_ERR("unable to determine machine account's short name in "
+ "AD!\n");
+ ret = -1;
+ goto out;
+ }
+
+ kvno = (krb5_kvno)ads_get_machine_kvno(ads, lp_netbios_name());
+ if (kvno == -1) {
+ /* -1 indicates failure, everything else is OK */
+ DBG_WARNING("ads_get_machine_kvno failed to determine the "
+ "system's kvno.\n");
+ ret = -1;
+ goto out;
+ }
+
+ salt_princ_s = kerberos_secrets_fetch_salt_princ();
+ if (salt_princ_s == NULL) {
+ DBG_WARNING("kerberos_secrets_fetch_salt_princ() failed\n");
+ ret = -1;
+ goto out;
+ }
+
+ ret = add_kt_entry_etypes(context, tmpctx, ads, salt_princ_s, keytab,
+ kvno, srvPrinc, my_fqdn, &password,
+ update_ads);
+ if (ret != 0) {
+ goto out;
+ }
out:
SAFE_FREE(salt_princ_s);
--
2.26.2
From 7b2295db8683bb9432f49e2f09912799e65e2e6b Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Wed, 27 May 2020 17:55:12 +0200
Subject: [PATCH 5/7] Add a test for msDS-AdditionalDnsHostName entries in
keytab
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14396
Signed-off-by: Isaac Boukris <iboukris@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
---
selftest/knownfail.d/dns_alias_keytab | 2 ++
testprogs/blackbox/test_net_ads.sh | 9 +++++++++
2 files changed, 11 insertions(+)
create mode 100644 selftest/knownfail.d/dns_alias_keytab
diff --git a/selftest/knownfail.d/dns_alias_keytab b/selftest/knownfail.d/dns_alias_keytab
new file mode 100644
index 00000000000..216592e1210
--- /dev/null
+++ b/selftest/knownfail.d/dns_alias_keytab
@@ -0,0 +1,2 @@
+^samba4.blackbox.net_ads.dns alias1 check keytab
+^samba4.blackbox.net_ads.dns alias2 check keytab
diff --git a/testprogs/blackbox/test_net_ads.sh b/testprogs/blackbox/test_net_ads.sh
index 6073ea972f9..a40b477a173 100755
--- a/testprogs/blackbox/test_net_ads.sh
+++ b/testprogs/blackbox/test_net_ads.sh
@@ -217,6 +217,15 @@ testit_grep "dns alias SPN" $dns_alias2 $VALGRIND $net_tool ads search -P samacc
testit_grep "dns alias addl" $dns_alias1 $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ msDS-AdditionalDnsHostName || failed=`expr $failed + 1`
testit_grep "dns alias addl" $dns_alias2 $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ msDS-AdditionalDnsHostName || failed=`expr $failed + 1`
+dedicated_keytab_file="$PREFIX_ABS/test_dns_aliases_dedicated_krb5.keytab"
+
+testit "dns alias create_keytab" $VALGRIND $net_tool ads keytab create --option="kerberosmethod=dedicatedkeytab" --option="dedicatedkeytabfile=$dedicated_keytab_file" || failed=`expr $failed + 1`
+
+testit_grep "dns alias1 check keytab" "host/${dns_alias1}@$REALM" $net_tool ads keytab list --option="kerberosmethod=dedicatedkeytab" --option="dedicatedkeytabfile=$dedicated_keytab_file" || failed=`expr $failed + 1`
+testit_grep "dns alias2 check keytab" "host/${dns_alias2}@$REALM" $net_tool ads keytab list --option="kerberosmethod=dedicatedkeytab" --option="dedicatedkeytabfile=$dedicated_keytab_file" || failed=`expr $failed + 1`
+
+rm -f $dedicated_keytab_file
+
##Goodbye...
testit "leave" $VALGRIND $net_tool ads leave -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1`
--
2.26.2
From ca89f163524c317b6a2fffeb527194b34ede526d Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Wed, 27 May 2020 15:36:28 +0200
Subject: [PATCH 6/7] Add msDS-AdditionalDnsHostName entries to the keytab
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14396
Signed-off-by: Isaac Boukris <iboukris@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
---
selftest/knownfail.d/dns_alias_keytab | 2 --
source3/libads/ads_proto.h | 5 +++
source3/libads/kerberos_keytab.c | 21 +++++++++++++
source3/libads/ldap.c | 45 +++++++++++++++++++++++++++
4 files changed, 71 insertions(+), 2 deletions(-)
delete mode 100644 selftest/knownfail.d/dns_alias_keytab
diff --git a/selftest/knownfail.d/dns_alias_keytab b/selftest/knownfail.d/dns_alias_keytab
deleted file mode 100644
index 216592e1210..00000000000
--- a/selftest/knownfail.d/dns_alias_keytab
+++ /dev/null
@@ -1,2 +0,0 @@
-^samba4.blackbox.net_ads.dns alias1 check keytab
-^samba4.blackbox.net_ads.dns alias2 check keytab
diff --git a/source3/libads/ads_proto.h b/source3/libads/ads_proto.h
index 495ef5d3325..cd9c1082681 100644
--- a/source3/libads/ads_proto.h
+++ b/source3/libads/ads_proto.h
@@ -137,6 +137,11 @@ ADS_STATUS ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx,
enum ads_extended_dn_flags flags,
struct dom_sid *sid);
char* ads_get_dnshostname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name );
+ADS_STATUS ads_get_additional_dns_hostnames(TALLOC_CTX *mem_ctx,
+ ADS_STRUCT *ads,
+ const char *machine_name,
+ char ***hostnames_array,
+ size_t *num_hostnames);
char* ads_get_upn( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name );
bool ads_has_samaccountname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name );
ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name,
diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c
index 0f450a09df5..818ec884a03 100644
--- a/source3/libads/kerberos_keytab.c
+++ b/source3/libads/kerberos_keytab.c
@@ -351,6 +351,8 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, bool update_ads)
char *password_s = NULL;
char *my_fqdn;
TALLOC_CTX *tmpctx = NULL;
+ char **hostnames_array = NULL;
+ size_t num_hostnames = 0;
ret = smb_krb5_init_context_common(&context);
if (ret) {
@@ -427,6 +429,25 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, bool update_ads)
goto out;
}
+ if (ADS_ERR_OK(ads_get_additional_dns_hostnames(tmpctx, ads,
+ lp_netbios_name(),
+ &hostnames_array,
+ &num_hostnames))) {
+ size_t i;
+
+ for (i = 0; i < num_hostnames; i++) {
+
+ ret = add_kt_entry_etypes(context, tmpctx, ads,
+ salt_princ_s, keytab,
+ kvno, srvPrinc,
+ hostnames_array[i],
+ &password, update_ads);
+ if (ret != 0) {
+ goto out;
+ }
+ }
+ }
+
out:
SAFE_FREE(salt_princ_s);
TALLOC_FREE(tmpctx);
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index db2b72ab1b5..02a628ee0e6 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -1377,6 +1377,7 @@ char *ads_parent_dn(const char *dn)
"unicodePwd",
/* Additional attributes Samba checks */
+ "msDS-AdditionalDnsHostName",
"msDS-SupportedEncryptionTypes",
"nTSecurityDescriptor",
@@ -3663,6 +3664,50 @@ out:
/********************************************************************
********************************************************************/
+ADS_STATUS ads_get_additional_dns_hostnames(TALLOC_CTX *mem_ctx,
+ ADS_STRUCT *ads,
+ const char *machine_name,
+ char ***hostnames_array,
+ size_t *num_hostnames)
+{
+ ADS_STATUS status;
+ LDAPMessage *res = NULL;
+ int count;
+
+ status = ads_find_machine_acct(ads,
+ &res,
+ machine_name);
+ if (!ADS_ERR_OK(status)) {
+ DEBUG(1,("Host Account for %s not found... skipping operation.\n",
+ machine_name));
+ return status;
+ }
+
+ count = ads_count_replies(ads, res);
+ if (count != 1) {
+ status = ADS_ERROR(LDAP_NO_SUCH_OBJECT);
+ goto done;
+ }
+
+ *hostnames_array = ads_pull_strings(ads, mem_ctx, res,
+ "msDS-AdditionalDnsHostName",
+ num_hostnames);
+ if (*hostnames_array == NULL) {
+ DEBUG(1, ("Host account for %s does not have msDS-AdditionalDnsHostName.\n",
+ machine_name));
+ status = ADS_ERROR(LDAP_NO_SUCH_OBJECT);
+ goto done;
+ }
+
+done:
+ ads_msgfree(ads, res);
+
+ return status;
+}
+
+/********************************************************************
+********************************************************************/
+
char* ads_get_upn( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name )
{
LDAPMessage *res = NULL;
--
2.26.2
From 48d6a35118f2c8e51bbe3f31c1500f8ab097498e Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Wed, 27 May 2020 15:54:12 +0200
Subject: [PATCH 7/7] Add net-ads-join dnshostname=fqdn option
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14396
Signed-off-by: Isaac Boukris <iboukris@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org>
Autobuild-Date(master): Fri May 29 13:33:28 UTC 2020 on sn-devel-184
---
docs-xml/manpages/net.8.xml | 7 ++++++-
source3/libnet/libnet_join.c | 7 ++++++-
source3/librpc/idl/libnet_join.idl | 1 +
source3/utils/net_ads.c | 9 ++++++++-
testprogs/blackbox/test_net_ads.sh | 15 +++++++++++++++
5 files changed, 36 insertions(+), 3 deletions(-)
diff --git a/docs-xml/manpages/net.8.xml b/docs-xml/manpages/net.8.xml
index 37dfa2af694..69e18df8b6c 100644
--- a/docs-xml/manpages/net.8.xml
+++ b/docs-xml/manpages/net.8.xml
@@ -454,7 +454,7 @@ The remote server must be specified with the -S option.
<refsect2>
<title>[RPC|ADS] JOIN [TYPE] [--no-dns-updates] [-U username[%password]]
-[createupn=UPN] [createcomputer=OU] [machinepass=PASS]
+[dnshostname=FQDN] [createupn=UPN] [createcomputer=OU] [machinepass=PASS]
[osName=string osVer=string] [options]</title>
<para>
@@ -469,6 +469,11 @@ be created.</para>
joining the domain.
</para>
+<para>
+[FQDN] (ADS only) set the dnsHosName attribute during the join.
+The default format is netbiosname.dnsdomain.
+</para>
+
<para>
[UPN] (ADS only) set the principalname attribute during the join. The default
format is host/netbiosname@REALM.
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index a31011b0ff8..de558be4f91 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -546,7 +546,12 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
goto done;
}
- fstr_sprintf(my_fqdn, "%s.%s", r->in.machine_name, lp_dnsdomain());
+ if (r->in.dnshostname != NULL) {
+ fstr_sprintf(my_fqdn, "%s", r->in.dnshostname);
+ } else {
+ fstr_sprintf(my_fqdn, "%s.%s", r->in.machine_name,
+ lp_dnsdomain());
+ }
if (!strlower_m(my_fqdn)) {
status = ADS_ERROR_LDAP(LDAP_NO_MEMORY);
diff --git a/source3/librpc/idl/libnet_join.idl b/source3/librpc/idl/libnet_join.idl
index e45034d40da..03d919863b5 100644
--- a/source3/librpc/idl/libnet_join.idl
+++ b/source3/librpc/idl/libnet_join.idl
@@ -37,6 +37,7 @@ interface libnetjoin
[in] string os_servicepack,
[in] boolean8 create_upn,
[in] string upn,
+ [in] string dnshostname,
[in] boolean8 modify_config,
[in,unique] ads_struct *ads,
[in] boolean8 debug,
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
index 07a22098fb1..3cf8fbbf7c8 100644
--- a/source3/utils/net_ads.c
+++ b/source3/utils/net_ads.c
@@ -1710,6 +1710,8 @@ static int net_ads_join_usage(struct net_context *c, int argc, const char **argv
{
d_printf(_("net ads join [--no-dns-updates] [options]\n"
"Valid options:\n"));
+ d_printf(_(" dnshostname=FQDN Set the dnsHostName attribute during the join.\n"
+ " The default is in the form netbiosname.dnsdomain\n"));
d_printf(_(" createupn[=UPN] Set the userPrincipalName attribute during the join.\n"
" The default UPN is in the form host/netbiosname@REALM.\n"));
d_printf(_(" createcomputer=OU Precreate the computer account in a specific OU.\n"
@@ -1830,6 +1832,7 @@ int net_ads_join(struct net_context *c, int argc, const char **argv)
const char *domain = lp_realm();
WERROR werr = WERR_NERR_SETUPNOTJOINED;
bool createupn = false;
+ const char *dnshostname = NULL;
const char *machineupn = NULL;
const char *machine_password = NULL;
const char *create_in_ou = NULL;
@@ -1870,7 +1873,10 @@ int net_ads_join(struct net_context *c, int argc, const char **argv)
/* process additional command line args */
for ( i=0; i<argc; i++ ) {
- if ( !strncasecmp_m(argv[i], "createupn", strlen("createupn")) ) {
+ if ( !strncasecmp_m(argv[i], "dnshostname", strlen("dnshostname")) ) {
+ dnshostname = get_string_param(argv[i]);
+ }
+ else if ( !strncasecmp_m(argv[i], "createupn", strlen("createupn")) ) {
createupn = true;
machineupn = get_string_param(argv[i]);
}
@@ -1938,6 +1944,7 @@ int net_ads_join(struct net_context *c, int argc, const char **argv)
r->in.domain_name_type = domain_name_type;
r->in.create_upn = createupn;
r->in.upn = machineupn;
+ r->in.dnshostname = dnshostname;
r->in.account_ou = create_in_ou;
r->in.os_name = os_name;
r->in.os_version = os_version;
diff --git a/testprogs/blackbox/test_net_ads.sh b/testprogs/blackbox/test_net_ads.sh
index a40b477a173..85257f445d8 100755
--- a/testprogs/blackbox/test_net_ads.sh
+++ b/testprogs/blackbox/test_net_ads.sh
@@ -277,6 +277,21 @@ rm -f $dedicated_keytab_file
testit "leave+createupn" $VALGRIND $net_tool ads leave -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1`
+#
+# Test dnshostname option of 'net ads join'
+#
+testit "join+dnshostname" $VALGRIND $net_tool ads join -U$DC_USERNAME%$DC_PASSWORD dnshostname="alt.hostname.$HOSTNAME" || failed=`expr $failed + 1`
+
+testit_grep "check dnshostname opt" "dNSHostName: alt.hostname.$HOSTNAME" $ldbsearch -U$DC_USERNAME%$DC_PASSWORD -H ldap://$SERVER.$REALM -s base -b "CN=$HOSTNAME,CN=Computers,$base_dn" || failed=`expr $failed + 1`
+
+testit "create_keytab+dnshostname" $VALGRIND $net_tool ads keytab create --option="kerberosmethod=dedicatedkeytab" --option="dedicatedkeytabfile=$dedicated_keytab_file" || failed=`expr $failed + 1`
+
+testit_grep "check dnshostname+keytab" "host/alt.hostname.$HOSTNAME@$REALM" $net_tool ads keytab list --option="kerberosmethod=dedicatedkeytab" --option="dedicatedkeytabfile=$dedicated_keytab_file" || failed=`expr $failed + 1`
+
+rm -f $dedicated_keytab_file
+
+testit "leave+dnshostname" $VALGRIND $net_tool ads leave -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1`
+
rm -rf $BASEDIR/$WORKDIR
exit $failed
--
2.26.2