The branch, master has been updated via ce0e96e6f48 Add net-ads-join dnshostname=fqdn option via 2b62bd51373 Add msDS-AdditionalDnsHostName entries to the keytab via 97cd636dbc9 Add a test for msDS-AdditionalDnsHostName entries in keytab via 1df7604b4e9 Refactor ads_keytab_add_entry() to make it iterable via aa0985324af Fix accidental overwrite of dnsHostName by the last netbios alias via b0b73253658 Add a test to check dNSHostName with netbios aliases from d18c76666f8 smbd: Protect smbd_smb2_getinfo_send() against invalid quota files
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit ce0e96e6f48e059b1ceeacaa10de7cab54a466af Author: Isaac Boukris <ibouk...@gmail.com> Date: Wed May 27 15:54:12 2020 +0200 Add net-ads-join dnshostname=fqdn option BUG: https://bugzilla.samba.org/show_bug.cgi?id=14396 Signed-off-by: Isaac Boukris <ibouk...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> Autobuild-User(master): Andreas Schneider <a...@cryptomilk.org> Autobuild-Date(master): Fri May 29 13:33:28 UTC 2020 on sn-devel-184 commit 2b62bd51373040047f872ffd10431b926fd0da4b Author: Isaac Boukris <ibouk...@gmail.com> Date: Wed May 27 15:36:28 2020 +0200 Add msDS-AdditionalDnsHostName entries to the keytab BUG: https://bugzilla.samba.org/show_bug.cgi?id=14396 Signed-off-by: Isaac Boukris <ibouk...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 97cd636dbc933f7696e97e9fe1836cb7600b4844 Author: Isaac Boukris <ibouk...@gmail.com> Date: Wed May 27 17:55:12 2020 +0200 Add a test for msDS-AdditionalDnsHostName entries in keytab BUG: https://bugzilla.samba.org/show_bug.cgi?id=14396 Signed-off-by: Isaac Boukris <ibouk...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 1df7604b4e9b7585cb32749f792ec618dff930b0 Author: Isaac Boukris <ibouk...@gmail.com> Date: Wed May 27 13:25:17 2020 +0200 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 <ibouk...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit aa0985324afc00f5351fcf69e81b18632b93e494 Author: Isaac Boukris <ibouk...@gmail.com> Date: Wed May 27 15:52:46 2020 +0200 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 <ibouk...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit b0b7325365843c13062588258070424574040991 Author: Isaac Boukris <ibouk...@gmail.com> Date: Wed May 27 16:50:45 2020 +0200 Add a test to check dNSHostName with netbios aliases BUG: https://bugzilla.samba.org/show_bug.cgi?id=14396 Signed-off-by: Isaac Boukris <ibouk...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> ----------------------------------------------------------------------- Summary of changes: docs-xml/manpages/net.8.xml | 7 +- source3/libads/ads_proto.h | 5 + source3/libads/kerberos_keytab.c | 218 ++++++++++++++++++++++--------------- source3/libads/ldap.c | 45 ++++++++ source3/libnet/libnet_join.c | 12 +- source3/librpc/idl/libnet_join.idl | 1 + source3/utils/net_ads.c | 9 +- testprogs/blackbox/test_net_ads.sh | 38 +++++++ 8 files changed, 240 insertions(+), 95 deletions(-) Changeset truncated at 500 lines: diff --git a/docs-xml/manpages/net.8.xml b/docs-xml/manpages/net.8.xml index 37dd30b7864..cbab9c63a5e 100644 --- a/docs-xml/manpages/net.8.xml +++ b/docs-xml/manpages/net.8.xml @@ -481,7 +481,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> @@ -496,6 +496,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/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 bc35d5edbe4..da363741d10 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[4] = { #ifdef HAVE_ENCTYPE_AES256_CTS_HMAC_SHA1_96 ENCTYPE_AES256_CTS_HMAC_SHA1_96, #endif @@ -249,65 +247,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, '@')) { @@ -356,22 +296,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 */ @@ -381,11 +305,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; } @@ -397,12 +321,126 @@ 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; + char **hostnames_array = NULL; + size_t num_hostnames = 0; + + 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; + } + + 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; } } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 0caa1044645..eb5fef0c7f3 100755 --- 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", @@ -3668,6 +3669,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; diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c index 9fdc18c4994..34938603606 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; @@ -545,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); @@ -587,11 +593,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; 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 9d9bc5f7982..d4bf5fa12b3 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -1711,6 +1711,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" @@ -1831,6 +1833,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; @@ -1871,7 +1874,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]); } @@ -1939,6 +1945,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 95c0cf76f90..85257f445d8 100755 --- a/testprogs/blackbox/test_net_ads.sh +++ b/testprogs/blackbox/test_net_ads.sh @@ -217,6 +217,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` +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` + +# 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` @@ -254,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` -- Samba Shared Repository