From 0ef46723cad274d0fe7948a67b33f9f20fab3f0d Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Tue, 7 Jan 2020 19:25:53 +0200 Subject: [PATCH 01/11] 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 Reviewed-by: Guenther Deschner Autobuild-User(master): Günther Deschner 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.25.4 From 67c40147a3c1da49a8d407282e1917ed3be511b0 Mon Sep 17 00:00:00 2001 From: Isaac Boukris Date: Wed, 27 May 2020 16:50:45 +0200 Subject: [PATCH 02/11] Add a test to check dNSHostName with netbios aliases BUG: https://bugzilla.samba.org/show_bug.cgi?id=14396 Signed-off-by: Isaac Boukris Reviewed-by: Andreas Schneider --- 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.25.4 From b3e19ea4f4f366e7f6b99114c71f65c303402ef8 Mon Sep 17 00:00:00 2001 From: Isaac Boukris Date: Wed, 27 May 2020 15:52:46 +0200 Subject: [PATCH 03/11] 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 Reviewed-by: Andreas Schneider --- 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.25.4 From 134c761913dcf84c8c18751a8ba9cc3652995138 Mon Sep 17 00:00:00 2001 From: Isaac Boukris Date: Thu, 24 Oct 2019 19:04:51 +0300 Subject: [PATCH 04/11] 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 Reviewed-by: Andreas Schneider --- 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.25.4 From 7b2295db8683bb9432f49e2f09912799e65e2e6b Mon Sep 17 00:00:00 2001 From: Isaac Boukris Date: Wed, 27 May 2020 17:55:12 +0200 Subject: [PATCH 05/11] Add a test for msDS-AdditionalDnsHostName entries in keytab BUG: https://bugzilla.samba.org/show_bug.cgi?id=14396 Signed-off-by: Isaac Boukris Reviewed-by: Andreas Schneider --- 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.25.4 From ca89f163524c317b6a2fffeb527194b34ede526d Mon Sep 17 00:00:00 2001 From: Isaac Boukris Date: Wed, 27 May 2020 15:36:28 +0200 Subject: [PATCH 06/11] Add msDS-AdditionalDnsHostName entries to the keytab BUG: https://bugzilla.samba.org/show_bug.cgi?id=14396 Signed-off-by: Isaac Boukris Reviewed-by: Andreas Schneider --- 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.25.4 From 48d6a35118f2c8e51bbe3f31c1500f8ab097498e Mon Sep 17 00:00:00 2001 From: Isaac Boukris Date: Wed, 27 May 2020 15:54:12 +0200 Subject: [PATCH 07/11] Add net-ads-join dnshostname=fqdn option BUG: https://bugzilla.samba.org/show_bug.cgi?id=14396 Signed-off-by: Isaac Boukris Reviewed-by: Andreas Schneider Autobuild-User(master): Andreas Schneider 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. [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] @@ -469,6 +469,11 @@ be created. joining the domain. + +[FQDN] (ADS only) set the dnsHosName attribute during the join. +The default format is netbiosname.dnsdomain. + + [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; iin.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.25.4 From 8cd52f39772bf6b9c008a4e281c3a75f150a043b Mon Sep 17 00:00:00 2001 From: Isaac Boukris Date: Thu, 11 Jun 2020 21:05:07 +0300 Subject: [PATCH 08/11] Fix a typo in recent net man page changes BUG: https://bugzilla.samba.org/show_bug.cgi?id=14406 Signed-off-by: Isaac Boukris Reviewed-by: Andreas Schneider --- docs-xml/manpages/net.8.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-xml/manpages/net.8.xml b/docs-xml/manpages/net.8.xml index 69e18df8b6c..9b1d4458acc 100644 --- a/docs-xml/manpages/net.8.xml +++ b/docs-xml/manpages/net.8.xml @@ -470,7 +470,7 @@ joining the domain. -[FQDN] (ADS only) set the dnsHosName attribute during the join. +[FQDN] (ADS only) set the dnsHostName attribute during the join. The default format is netbiosname.dnsdomain. -- 2.25.4 From 2741058ea556296869d8895eb4adc30a07ecd59a Mon Sep 17 00:00:00 2001 From: Isaac Boukris Date: Tue, 16 Jun 2020 22:01:49 +0300 Subject: [PATCH 09/11] selftest: add tests for binary msDS-AdditionalDnsHostName Like the short names added implicitly by Windows DC. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14406 Signed-off-by: Isaac Boukris Reviewed-by: Andreas Schneider --- selftest/knownfail.d/binary_addl_hostname | 3 +++ testprogs/blackbox/test_net_ads.sh | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 selftest/knownfail.d/binary_addl_hostname diff --git a/selftest/knownfail.d/binary_addl_hostname b/selftest/knownfail.d/binary_addl_hostname new file mode 100644 index 00000000000..559db1df507 --- /dev/null +++ b/selftest/knownfail.d/binary_addl_hostname @@ -0,0 +1,3 @@ +^samba4.blackbox.net_ads.dns alias1 check keytab +^samba4.blackbox.net_ads.dns alias2 check keytab +^samba4.blackbox.net_ads.addl short check keytab diff --git a/testprogs/blackbox/test_net_ads.sh b/testprogs/blackbox/test_net_ads.sh index 85257f445d8..eef4a31a6a7 100755 --- a/testprogs/blackbox/test_net_ads.sh +++ b/testprogs/blackbox/test_net_ads.sh @@ -41,6 +41,11 @@ if [ -x "$BINDIR/ldbdel" ]; then ldbdel="$BINDIR/ldbdel" fi +ldbmodify="ldbmodify" +if [ -x "$BINDIR/ldbmodify" ]; then + ldbmodify="$BINDIR/ldbmodify" +fi + # Load test functions . `dirname $0`/subunit.sh @@ -217,12 +222,29 @@ 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` +# Test binary msDS-AdditionalDnsHostName like ones added by Windows DC +short_alias_file="$PREFIX_ABS/short_alias_file" +printf 'short_alias\0$' > $short_alias_file +cat > $PREFIX_ABS/tmpldbmodify < Date: Thu, 11 Jun 2020 16:51:27 +0300 Subject: [PATCH 10/11] Properly handle msDS-AdditionalDnsHostName returned from Windows DC Windows DC adds short names for each specified msDS-AdditionalDnsHostName attribute, but these have a suffix of "\0$" and thus fail with ldap_get_values(), use ldap_get_values_len() instead. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14406 Signed-off-by: Isaac Boukris Reviewed-by: Andreas Schneider --- selftest/knownfail.d/binary_addl_hostname | 3 -- source3/libads/ldap.c | 38 +++++++++++++++++++++-- 2 files changed, 35 insertions(+), 6 deletions(-) delete mode 100644 selftest/knownfail.d/binary_addl_hostname diff --git a/selftest/knownfail.d/binary_addl_hostname b/selftest/knownfail.d/binary_addl_hostname deleted file mode 100644 index 559db1df507..00000000000 --- a/selftest/knownfail.d/binary_addl_hostname +++ /dev/null @@ -1,3 +0,0 @@ -^samba4.blackbox.net_ads.dns alias1 check keytab -^samba4.blackbox.net_ads.dns alias2 check keytab -^samba4.blackbox.net_ads.addl short check keytab diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 02a628ee0e6..2684bba63ec 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3664,6 +3664,40 @@ out: /******************************************************************** ********************************************************************/ +static char **get_addl_hosts(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, + LDAPMessage *msg, size_t *num_values) +{ + const char *field = "msDS-AdditionalDnsHostName"; + struct berval **values = NULL; + char **ret = NULL; + size_t i, converted_size; + + values = ldap_get_values_len(ads->ldap.ld, msg, field); + if (values == NULL) { + return NULL; + } + + *num_values = ldap_count_values_len(values); + + ret = talloc_array(mem_ctx, char *, *num_values + 1); + if (ret == NULL) { + ldap_value_free_len(values); + return NULL; + } + + for (i = 0; i < *num_values; i++) { + if (!pull_utf8_talloc(mem_ctx, &ret[i], values[i]->bv_val, + &converted_size)) { + ldap_value_free_len(values); + return NULL; + } + } + ret[i] = NULL; + + ldap_value_free_len(values); + return ret; +} + ADS_STATUS ads_get_additional_dns_hostnames(TALLOC_CTX *mem_ctx, ADS_STRUCT *ads, const char *machine_name, @@ -3689,9 +3723,7 @@ ADS_STATUS ads_get_additional_dns_hostnames(TALLOC_CTX *mem_ctx, goto done; } - *hostnames_array = ads_pull_strings(ads, mem_ctx, res, - "msDS-AdditionalDnsHostName", - num_hostnames); + *hostnames_array = get_addl_hosts(ads, mem_ctx, res, num_hostnames); if (*hostnames_array == NULL) { DEBUG(1, ("Host account for %s does not have msDS-AdditionalDnsHostName.\n", machine_name)); -- 2.25.4 From 05dc94412f1f9809a3c84f4335c157258ee31273 Mon Sep 17 00:00:00 2001 From: Isaac Boukris Date: Sat, 20 Jun 2020 17:17:33 +0200 Subject: [PATCH 11/11] Fix usage of ldap_get_values_len for msDS-AdditionalDnsHostName BUG: https://bugzilla.samba.org/show_bug.cgi?id=14406 Signed-off-by: Isaac Boukris Reviewed-by: Andreas Schneider Autobuild-User(master): Andreas Schneider Autobuild-Date(master): Mon Jun 22 09:59:04 UTC 2020 on sn-devel-184 --- source3/libads/ldap.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2684bba63ec..d1ce9cee2f0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3686,8 +3686,12 @@ static char **get_addl_hosts(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, } for (i = 0; i < *num_values; i++) { - if (!pull_utf8_talloc(mem_ctx, &ret[i], values[i]->bv_val, - &converted_size)) { + ret[i] = NULL; + if (!convert_string_talloc(mem_ctx, CH_UTF8, CH_UNIX, + values[i]->bv_val, + strnlen(values[i]->bv_val, + values[i]->bv_len), + &ret[i], &converted_size)) { ldap_value_free_len(values); return NULL; } -- 2.25.4