The branch, v4-22-test has been updated via 6ee4a2bfcbd s3:net: Pass down the server from cmdline to sync_pw2keytabs() via 0034b13f23a tests: Add test for 'net ads join' to a preferred DC via b26cc594a1e selftest: Add the short name for localvampiredc to hosts file via 69fddebd507 s3:net: fix "net ads group" via 91031b72149 smbd: return correct reparse tag DFS when listing directories via 4f959e0dc36 CI: add Python test samba.tests.dcerpc.dfs.DfsTests.test_dfs_reparse_tag via cced6a07d87 python/tests: also populate self.server in calls LibsmbTests setup() via 51fa56ad96c pylibsmb: add SMB2_FIND_ID_BOTH_DIRECTORY_INFO via 0ec18e6bc39 vfs_xattr_tdb: fix dangling symlink detection via 15ab604ef1c s3/rpc_server/dfs: fix creating a DFS link from 31b82351af1 VERSION: Bump version up to Samba 4.22.5...
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-22-test - Log ----------------------------------------------------------------- commit 6ee4a2bfcbdd432687a96caab69914b8b92abdbd Author: Andreas Schneider <a...@samba.org> Date: Mon Jul 28 10:43:36 2025 +0200 s3:net: Pass down the server from cmdline to sync_pw2keytabs() This makes sure that during 'net ads join' the keytab create code - sync_pw2keytabs() talks to the same DC at what the machine account was created. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15905 Signed-off-by: Andreas Schneider <a...@samba.org> Signed-off-by: Pavel Filipenský <pfilipen...@samba.org> Pair-Programmed-With: Pavel Filipenský <pfilipen...@samba.org> Reviewed-by: Alexander Bokovoy <a...@samba.org> Autobuild-User(master): Pavel Filipensky <pfilipen...@samba.org> Autobuild-Date(master): Fri Sep 5 13:38:33 UTC 2025 on atb-devel-224 (cherry picked from commit 5d1d3a8b568b5a07ed1ed537d20aa93820cecc14) Autobuild-User(v4-22-test): Jule Anger <jan...@samba.org> Autobuild-Date(v4-22-test): Thu Sep 11 11:06:53 UTC 2025 on atb-devel-224 commit 0034b13f23ab9d16d62dbf0619e24233c520dae3 Author: Pavel Filipenský <pfilipen...@samba.org> Date: Mon Aug 4 11:20:54 2025 +0200 tests: Add test for 'net ads join' to a preferred DC BUG: https://bugzilla.samba.org/show_bug.cgi?id=15905 Signed-off-by: Pavel Filipenský <pfilipen...@samba.org> Reviewed-by: Alexander Bokovoy <a...@samba.org> (backported from commit 36f6ac547c09f492d1dcab11570e8bcbd377cf26) commit b26cc594a1e4e787a98164ded77be7b2ef152cb9 Author: Pavel Filipenský <pfilipen...@samba.org> Date: Tue Jul 29 11:19:07 2025 +0200 selftest: Add the short name for localvampiredc to hosts file BUG: https://bugzilla.samba.org/show_bug.cgi?id=15905 Signed-off-by: Pavel Filipenský <pfilipen...@samba.org> Reviewed-by: Alexander Bokovoy <a...@samba.org> (cherry picked from commit 5d2f60ae5aa96751b74901ae5384291ef338b152) commit 69fddebd5079fdbe53b0c3ed114fbd80f1029d10 Author: MikeLiu <mike...@qnap.com> Date: Fri Aug 29 17:31:36 2025 +0800 s3:net: fix "net ads group" BUG: https://bugzilla.samba.org/show_bug.cgi?id=15900 Signed-off-by: MikeLiu <mike...@qnap.com> Reviewed-by: Volker Lendecke <v...@samba.org> Reviewed-by: Noel Power <npo...@samba.org> Autobuild-User(master): Volker Lendecke <v...@samba.org> Autobuild-Date(master): Thu Sep 4 09:33:27 UTC 2025 on atb-devel-224 (cherry picked from commit 8738fa1cc42d913e3ab2b54fe1e75ca4da37073f) commit 91031b7214945b7df7e4d6872c3742828118074e Author: Ralph Boehme <s...@samba.org> Date: Fri Aug 15 10:13:33 2025 +0200 smbd: return correct reparse tag DFS when listing directories BUG: https://bugzilla.samba.org/show_bug.cgi?id=15843 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> Autobuild-User(master): Volker Lendecke <v...@samba.org> Autobuild-Date(master): Fri Aug 15 15:37:05 UTC 2025 on atb-devel-224 (cherry picked from commit 0be53d7ac0a39d6a48c6c5e2144f342c0d406781) commit 4f959e0dc36709e0a4679c4d326390eb828b85ab Author: Ralph Boehme <s...@samba.org> Date: Thu Aug 14 17:18:08 2025 +0200 CI: add Python test samba.tests.dcerpc.dfs.DfsTests.test_dfs_reparse_tag BUG: https://bugzilla.samba.org/show_bug.cgi?id=15843 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> (cherry picked from commit 43ee86c0c757e95712ed52bd336d2085485498ba) commit cced6a07d877e6a9c47cc3deeda69195c6b20f87 Author: Ralph Boehme <s...@samba.org> Date: Fri Aug 15 11:49:27 2025 +0200 python/tests: also populate self.server in calls LibsmbTests setup() BUG: https://bugzilla.samba.org/show_bug.cgi?id=15843 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> (cherry picked from commit 5f7b31927733b0ff3e1207be242f1ddb2cb699bd) commit 51fa56ad96c4240699fa2108af05df86c6a024ea Author: Ralph Boehme <s...@samba.org> Date: Fri Aug 15 10:14:53 2025 +0200 pylibsmb: add SMB2_FIND_ID_BOTH_DIRECTORY_INFO BUG: https://bugzilla.samba.org/show_bug.cgi?id=15843 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> (cherry picked from commit 698a0195f72a091e9ed6b0448160c79e37761840) commit 0ec18e6bc39595af2b25fe566c1ee140e02a6592 Author: Ralph Boehme <s...@samba.org> Date: Fri Aug 15 11:50:26 2025 +0200 vfs_xattr_tdb: fix dangling symlink detection The caller might not have called stat on smb_fname. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15843 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> (cherry picked from commit 2e88ba4b4de146327c19682d59bbe34d68158bf7) commit 15ab604ef1cbcd2c342a0ffd746cb1ff74d716f7 Author: Ralph Boehme <s...@samba.org> Date: Thu Aug 14 19:20:02 2025 +0200 s3/rpc_server/dfs: fix creating a DFS link If there's no existing link, get_referred_path() returns NT_STATUS_OBJECT_PATH_NOT_FOUND. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15843 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> (cherry picked from commit 2cb2991ccdd5d4f63e4c5b3ccc4454a6b39d6afe) ----------------------------------------------------------------------- Summary of changes: python/samba/tests/dcerpc/dfs.py | 48 +++++++++++++++++ python/samba/tests/libsmb.py | 1 + selftest/target/Samba4.pm | 2 +- source3/include/secrets.h | 25 +++++---- source3/libads/ads_proto.h | 2 +- source3/libads/kerberos_keytab.c | 24 +++++++-- source3/libads/trusts_util.c | 15 +++--- source3/libads/util.c | 10 ++-- source3/libnet/libnet_join.c | 2 +- source3/libsmb/pylibsmb.c | 1 + source3/modules/vfs_xattr_tdb.c | 13 +++-- source3/passdb/machine_account_secrets.c | 10 ++-- source3/rpc_server/dfs/srv_dfs_nt.c | 4 +- source3/smbd/dir.c | 2 + source3/utils/net.c | 10 ++-- source3/utils/net_ads.c | 4 +- source4/selftest/tests.py | 2 + .../blackbox/test_net_ads_join_to_preferred_dc.sh | 61 ++++++++++++++++++++++ 18 files changed, 192 insertions(+), 44 deletions(-) create mode 100644 python/samba/tests/dcerpc/dfs.py create mode 100755 testprogs/blackbox/test_net_ads_join_to_preferred_dc.sh Changeset truncated at 500 lines: diff --git a/python/samba/tests/dcerpc/dfs.py b/python/samba/tests/dcerpc/dfs.py new file mode 100644 index 00000000000..0fcce324e55 --- /dev/null +++ b/python/samba/tests/dcerpc/dfs.py @@ -0,0 +1,48 @@ +# +# Unix SMB/CIFS implementation. +# Copyright Ralph Boehme <s...@samba.org> 2025 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +"""Tests for samba.dcerpc.dfs""" + +import os +import logging +import samba +from samba.dcerpc import dfs +from samba.tests import RpcInterfaceTestCase +from samba.logger import get_samba_logger +from samba.credentials import Credentials +from samba.samba3 import libsmb_samba_internal as libsmb +import samba.tests.libsmb +from samba.samba3 import param as s3param + +logger = get_samba_logger(name=__name__) + +class DfsTests(samba.tests.libsmb.LibsmbTests): + def setUp(self): + super().setUp() + self.dfs = dfs.netdfs('ncacn_np:%s[/pipe/netdfs]' % self.server, self.lp, self.creds) + self.c = libsmb.Conn(self.server_ip, "msdfs-share", self.lp, self.creds) + + def tearDown(self): + super().tearDown() + + def test_dfs_reparse_tag(self): + self.dfs.Add('\\\\%s\\msdfs-share\\dfslink' % self.server, self.server, 'tmp', 'comment', 0) + l = self.c.list('', info_level=libsmb.SMB2_FIND_ID_BOTH_DIRECTORY_INFO) + files = {i['name']: i for i in l} + self.assertEqual(files['dfslink']['reparse_tag'], libsmb.IO_REPARSE_TAG_DFS) + self.dfs.Remove('\\\\%s\\msdfs-share\\dfslink' % self.server, self.server, 'tmp') diff --git a/python/samba/tests/libsmb.py b/python/samba/tests/libsmb.py index 3ac1b68a59b..e3683901df2 100644 --- a/python/samba/tests/libsmb.py +++ b/python/samba/tests/libsmb.py @@ -43,6 +43,7 @@ class LibsmbTests(samba.tests.TestCase): server_conf_dir = os.path.dirname(server_conf) self.global_inject = os.path.join(server_conf_dir, "global_inject.conf") + self.server = samba.tests.env_get_var_value("SERVER") self.server_ip = samba.tests.env_get_var_value("SERVER_IP") def clean_file(self, conn, filename): diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index 9da339f6239..af0434a8e6b 100755 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -878,7 +878,7 @@ nogroup:x:65534:nobody my $hostname = lc($ctx->{hostname}); open(HOSTS, ">>$ctx->{nsswrap_hosts}"); - if ($hostname eq "localdc") { + if ($hostname eq "localdc" || $hostname eq "localvampiredc") { print HOSTS "$ctx->{ipv4} ${hostname}.$ctx->{dnsname} $ctx->{dnsname} ${hostname}\n"; print HOSTS "$ctx->{ipv6} ${hostname}.$ctx->{dnsname} $ctx->{dnsname} ${hostname}\n"; } else { diff --git a/source3/include/secrets.h b/source3/include/secrets.h index a454c8bb8ff..061b9c6ef34 100644 --- a/source3/include/secrets.h +++ b/source3/include/secrets.h @@ -125,12 +125,15 @@ char *secrets_domain_info_string(TALLOC_CTX *mem_ctx, const struct secrets_domai NTSTATUS secrets_fetch_or_upgrade_domain_info(const char *domain, TALLOC_CTX *mem_ctx, struct secrets_domain_info1 **pinfo); -NTSTATUS secrets_prepare_password_change(const char *domain, const char *dcname, - const char *cleartext_unix, - TALLOC_CTX *mem_ctx, - struct secrets_domain_info1 **pinfo, - struct secrets_domain_info1_change **pprev, - NTSTATUS (*sync_pw2keytabs_fn)(void)); +NTSTATUS secrets_prepare_password_change( + const char *domain, + const char *dcname, + const char *cleartext_unix, + TALLOC_CTX *mem_ctx, + struct secrets_domain_info1 **pinfo, + struct secrets_domain_info1_change **pprev, + NTSTATUS (*sync_pw2keytabs_fn)(const char *), + const char *opt_host); NTSTATUS secrets_failed_password_change(const char *change_server, NTSTATUS local_status, NTSTATUS remote_status, @@ -139,10 +142,12 @@ NTSTATUS secrets_defer_password_change(const char *change_server, NTSTATUS local_status, NTSTATUS remote_status, const struct secrets_domain_info1 *info); -NTSTATUS secrets_finish_password_change(const char *change_server, - NTTIME change_time, - const struct secrets_domain_info1 *info, - NTSTATUS (*sync_pw2keytabs_fn)(void)); +NTSTATUS secrets_finish_password_change( + const char *change_server, + NTTIME change_time, + const struct secrets_domain_info1 *info, + NTSTATUS (*sync_pw2keytabs_fn)(const char *), + const char *prefer_dc); bool secrets_delete_machine_password_ex(const char *domain, const char *realm); bool secrets_delete_domain_sid(const char *domain); char *secrets_fetch_prev_machine_password(const char *domain); diff --git a/source3/libads/ads_proto.h b/source3/libads/ads_proto.h index 8440c35e46d..2e67eef155c 100644 --- a/source3/libads/ads_proto.h +++ b/source3/libads/ads_proto.h @@ -230,6 +230,6 @@ struct spn_struct { /* parse a windows style SPN, returns NULL if parsing fails */ struct spn_struct *parse_spn(TALLOC_CTX *ctx, const char *srvprinc); -NTSTATUS sync_pw2keytabs(void); +NTSTATUS sync_pw2keytabs(const char *prefer_dc); #endif /* _LIBADS_ADS_PROTO_H_ */ diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index 49a892e5a55..1d4f9c12e1d 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -84,6 +84,7 @@ struct pw2kt_global_state { char *ad_upn; char *ad_sam_account; char **ad_spn_array; + const char *prefer_dc; size_t ad_num_spns; /* This is from secrets.db */ struct secrets_domain_info1 *info; @@ -869,8 +870,11 @@ static ADS_STATUS pw2kt_get_dc_info(struct pw2kt_global_state *state) int count; bool ok; TALLOC_CTX *tmp_ctx = talloc_stackframe(); - ADS_STRUCT *ads = ads_init( - tmp_ctx, lp_realm(), lp_workgroup(), NULL, ADS_SASL_SIGN); + ADS_STRUCT *ads = ads_init(tmp_ctx, + lp_realm(), + lp_workgroup(), + state->prefer_dc, + ADS_SASL_SIGN); if (ads == NULL) { DBG_ERR("ads_init() failed\n"); @@ -1029,7 +1033,20 @@ static bool pw2kt_default_keytab_name(char *name_str, size_t name_size) return true; } -NTSTATUS sync_pw2keytabs(void) +/** + * @internal + * + * @brief Sync machine password from secrets to keytab + * + * @param prefer_dc The DC we should talk to. This is especially important + * during domain join. Pass NULL if we should pick a random + * one. + * + * @return An NTSTATUS error code. + * + * @see NT_STATUS_IS_OK() + */ +NTSTATUS sync_pw2keytabs(const char *prefer_dc) { TALLOC_CTX *frame = talloc_stackframe(); const struct loadparm_substitution *lp_sub = @@ -1055,6 +1072,7 @@ NTSTATUS sync_pw2keytabs(void) TALLOC_FREE(frame); return NT_STATUS_NO_MEMORY; } + state->prefer_dc = prefer_dc; lp_ptr = lp_sync_machine_password_to_keytab(); if (lp_ptr == NULL) { diff --git a/source3/libads/trusts_util.c b/source3/libads/trusts_util.c index 6a39f32f350..c51c556e86b 100644 --- a/source3/libads/trusts_util.c +++ b/source3/libads/trusts_util.c @@ -360,10 +360,11 @@ NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context, &info, &prev, #ifdef HAVE_ADS - sync_pw2keytabs); + sync_pw2keytabs, #else - NULL); + NULL, #endif + NULL /* opt_host */); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("secrets_prepare_password_change() failed for domain %s!\n", domain)); @@ -610,10 +611,11 @@ NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context, prev->password->change_time, info, #ifdef HAVE_ADS - sync_pw2keytabs); + sync_pw2keytabs, #else - NULL); + NULL, #endif + prev->password->change_server); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("secrets_prepare_password_change() failed for domain %s!\n", domain)); @@ -759,10 +761,11 @@ NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context, info->next_change->change_time, info, #ifdef HAVE_ADS - sync_pw2keytabs); + sync_pw2keytabs, #else - NULL); + NULL, #endif + info->next_change->change_server); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("secrets_finish_password_change() failed for domain %s!\n", domain)); diff --git a/source3/libads/util.c b/source3/libads/util.c index 243dd09f3d0..360e556ab9b 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -59,10 +59,11 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip &info, &prev, #ifdef HAVE_ADS - sync_pw2keytabs); + sync_pw2keytabs, #else - NULL); + NULL, #endif + ads->auth.kdc_server); if (!NT_STATUS_IS_OK(status)) { return ADS_ERROR_NT(status); } @@ -138,10 +139,11 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip now, info, #ifdef HAVE_ADS - sync_pw2keytabs); + sync_pw2keytabs, #else - NULL); + NULL, #endif + ads->auth.kdc_server); if (!NT_STATUS_IS_OK(status)) { DEBUG(1,("Failed to save machine password\n")); return ADS_ERROR_NT(status); diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c index 5796c68e2e0..cb997dcbe23 100644 --- a/source3/libnet/libnet_join.c +++ b/source3/libnet/libnet_join.c @@ -867,7 +867,7 @@ static ADS_STATUS libnet_join_set_etypes(TALLOC_CTX *mem_ctx, static bool libnet_join_create_keytab(TALLOC_CTX *mem_ctx, struct libnet_JoinCtx *r) { - NTSTATUS ntstatus = sync_pw2keytabs(); + NTSTATUS ntstatus = sync_pw2keytabs(r->in.dc_name); return NT_STATUS_IS_OK(ntstatus); } diff --git a/source3/libsmb/pylibsmb.c b/source3/libsmb/pylibsmb.c index 97ae69ef50e..c901715e182 100644 --- a/source3/libsmb/pylibsmb.c +++ b/source3/libsmb/pylibsmb.c @@ -3448,6 +3448,7 @@ MODULE_INIT_FUNC(libsmb_samba_cwrapper) ADD_STRING(SMB2_CREATE_TAG_APP_INSTANCE_ID); ADD_STRING(SVHDX_OPEN_DEVICE_CONTEXT); ADD_STRING(SMB2_CREATE_TAG_POSIX); + ADD_FLAGS(SMB2_FIND_ID_BOTH_DIRECTORY_INFO); ADD_FLAGS(SMB2_FIND_POSIX_INFORMATION); ADD_FLAGS(FILE_SUPERSEDE); ADD_FLAGS(FILE_OPEN); diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c index 447d868924d..19331d0de4f 100644 --- a/source3/modules/vfs_xattr_tdb.c +++ b/source3/modules/vfs_xattr_tdb.c @@ -604,13 +604,12 @@ static int xattr_tdb_unlinkat(vfs_handle_struct *handle, } else { ret = SMB_VFS_NEXT_STAT(handle, full_fname); if (ret == -1 && (errno == ENOENT || errno == ELOOP)) { - if (VALID_STAT(smb_fname->st) && - S_ISLNK(smb_fname->st.st_ex_mode)) { - /* - * Original name was a link - Could be - * trying to remove a dangling symlink. - */ - ret = SMB_VFS_NEXT_LSTAT(handle, full_fname); + /* + * Could be trying to remove a dangling symlink. + */ + ret = SMB_VFS_NEXT_LSTAT(handle, full_fname); + if (ret == 0 && !S_ISLNK(full_fname->st.st_ex_mode)) { + ret = -1; } } } diff --git a/source3/passdb/machine_account_secrets.c b/source3/passdb/machine_account_secrets.c index 0679535f026..568d77a3892 100644 --- a/source3/passdb/machine_account_secrets.c +++ b/source3/passdb/machine_account_secrets.c @@ -1674,7 +1674,8 @@ NTSTATUS secrets_prepare_password_change(const char *domain, const char *dcname, TALLOC_CTX *mem_ctx, struct secrets_domain_info1 **pinfo, struct secrets_domain_info1_change **pprev, - NTSTATUS (*sync_pw2keytabs_fn)(void)) + NTSTATUS (*sync_pw2keytabs_fn)(const char *), + const char *opt_host) { TALLOC_CTX *frame = talloc_stackframe(); struct db_context *db = NULL; @@ -1770,7 +1771,7 @@ NTSTATUS secrets_prepare_password_change(const char *domain, const char *dcname, } if (prev == NULL && sync_pw2keytabs_fn != NULL) { - status = sync_pw2keytabs_fn(); + status = sync_pw2keytabs_fn(opt_host); if (!NT_STATUS_IS_OK(status)) { DBG_ERR("Sync of machine password failed.\n"); dbwrap_transaction_cancel(db); @@ -2023,7 +2024,8 @@ NTSTATUS secrets_defer_password_change(const char *change_server, NTSTATUS secrets_finish_password_change(const char *change_server, NTTIME change_time, const struct secrets_domain_info1 *cookie, - NTSTATUS (*sync_pw2keytabs_fn)(void)) + NTSTATUS (*sync_pw2keytabs_fn)(const char *), + const char *prefer_dc) { const char *domain = cookie->domain_info.name.string; TALLOC_CTX *frame = talloc_stackframe(); @@ -2102,7 +2104,7 @@ NTSTATUS secrets_finish_password_change(const char *change_server, } if (sync_pw2keytabs_fn != NULL) { - status = sync_pw2keytabs_fn(); + status = sync_pw2keytabs_fn(prefer_dc); if (!NT_STATUS_IS_OK(status)) { DBG_ERR("Sync of machine password failed.\n"); TALLOC_FREE(frame); diff --git a/source3/rpc_server/dfs/srv_dfs_nt.c b/source3/rpc_server/dfs/srv_dfs_nt.c index 8eaa59a8b0e..d8aeb76a1fb 100644 --- a/source3/rpc_server/dfs/srv_dfs_nt.c +++ b/source3/rpc_server/dfs/srv_dfs_nt.c @@ -97,7 +97,9 @@ WERROR _dfs_Add(struct pipes_struct *p, struct dfs_Add *r) remote_address, local_address, jn, &consumedcnt, &self_ref); - if(!NT_STATUS_IS_OK(status)) { + if(!NT_STATUS_IS_OK(status) && + !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) + { return ntstatus_to_werror(status); } diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index afc9c74dfdd..b44b5df2ea2 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -640,6 +640,8 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, smb_fname->st.st_ex_mode = (smb_fname->st.st_ex_mode & ~S_IFMT) | S_IFDIR; + smb_fname->fsp->fsp_name->st.st_ex_mode = + smb_fname->st.st_ex_mode; mode = dos_mode_msdfs(conn, dname, &smb_fname->st); get_dosmode = false; diff --git a/source3/utils/net.c b/source3/utils/net.c index 7ce93ced79e..ecabd980d0c 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -235,10 +235,11 @@ static int net_changesecretpw(struct net_context *c, int argc, &info, &prev, #ifdef HAVE_ADS - sync_pw2keytabs); + sync_pw2keytabs, #else - NULL); + NULL, #endif + c->opt_host); if (!NT_STATUS_IS_OK(status)) { d_fprintf(stderr, _("Unable to write the machine account password in the secrets database")); @@ -261,10 +262,11 @@ static int net_changesecretpw(struct net_context *c, int argc, now, info, #ifdef HAVE_ADS - sync_pw2keytabs); + sync_pw2keytabs, #else - NULL); + NULL, #endif + c->opt_host); if (!NT_STATUS_IS_OK(status)) { d_fprintf(stderr, _("Unable to write the machine account password in the secrets database")); diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 46531210411..6f7d3085290 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -1359,7 +1359,7 @@ int net_ads_group(struct net_context *c, int argc, const char **argv) char *disp_fields[2] = {NULL, NULL}; int ret = -1; - if (argc >= 0) { + if (argc > 0) { TALLOC_FREE(tmp_ctx); return net_run_function(c, argc, argv, "net ads group", func); } @@ -2965,7 +2965,7 @@ static int net_ads_keytab_create(struct net_context *c, int argc, const char **a net_use_krb_machine_account(c); } - ntstatus = sync_pw2keytabs(); + ntstatus = sync_pw2keytabs(c->opt_host); ret = NT_STATUS_IS_OK(ntstatus) ? 0 : 1; return ret; } diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 9c5e85e428a..33e112119e3 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -902,6 +902,7 @@ plantestsuite("samba4.blackbox.rfc2307_mapping", plantestsuite("samba4.blackbox.chgdcpass", "chgdcpass", [os.path.join(bbdir, "test_chgdcpass.sh"), '$SERVER', r"CHGDCPASS\$", '$REALM', '$DOMAIN', '$PREFIX/chgdcpass', "aes256-cts-hmac-sha1-96", '$PREFIX/chgdcpass', smbclient3]) plantestsuite("samba4.blackbox.samba_upgradedns(chgdcpass:local)", "chgdcpass:local", [os.path.join(bbdir, "test_samba_upgradedns.sh"), '$SERVER', '$REALM', '$PREFIX', '$SELFTEST_PREFIX/chgdcpass']) plantestsuite("samba4.blackbox.net_ads", "ad_dc:client", [os.path.join(bbdir, "test_net_ads.sh"), '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD', '$PREFIX_ABS']) +plantestsuite("samba4.blackbox.net_ads_join", "vampire_dc:client", [os.path.join(bbdir, "test_net_ads_join_to_preferred_dc.sh"), '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD', '$PREFIX']) plantestsuite("samba4.blackbox.net_offlinejoin", "ad_dc:client", [os.path.join(bbdir, "test_net_offline.sh"), '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD', '$PREFIX_ABS']) plantestsuite("samba4.blackbox.client_etypes_all(ad_dc:client)", "ad_dc:client", [os.path.join(bbdir, "test_client_etypes.sh"), '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD', '$PREFIX_ABS', 'all', '17_18_23']) plantestsuite("samba4.blackbox.client_etypes_legacy(ad_dc:client)", "ad_dc:client", [os.path.join(bbdir, "test_client_etypes.sh"), '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD', '$PREFIX_ABS', 'legacy', '23']) @@ -2237,6 +2238,7 @@ planoldpythontestsuite("proclimitdc", planoldpythontestsuite("none", "samba.tests.usage") planpythontestsuite("fileserver", "samba.tests.dcerpc.mdssvc") +planpythontestsuite("fileserver", "samba.tests.dcerpc.dfs") planoldpythontestsuite("none", "samba.tests.compression") planpythontestsuite("none", "samba.tests.security_descriptors") diff --git a/testprogs/blackbox/test_net_ads_join_to_preferred_dc.sh b/testprogs/blackbox/test_net_ads_join_to_preferred_dc.sh new file mode 100755 index 00000000000..1bebc2f4dbe --- /dev/null +++ b/testprogs/blackbox/test_net_ads_join_to_preferred_dc.sh @@ -0,0 +1,61 @@ +if [ $# -lt 4 ]; then + cat <<EOF +Usage: test_net_ads.sh DC_SERVER DC_USERNAME DC_PASSWORD BASEDIR +EOF + exit 1 +fi + +DC_SERVER=$1 +DC_USERNAME=$2 +DC_PASSWORD=$3 +BASEDIR=$4 + +HOSTNAME=$(dd if=/dev/urandom bs=1 count=32 2>/dev/null | sha1sum | cut -b 1-10) + +RUNDIR=$(pwd) +cd $BASEDIR +WORKDIR=$(mktemp -d -p .) +WORKDIR=$(basename $WORKDIR) +cp -a client/* $WORKDIR/ +sed -ri "s@(dir|directory) = (.*)/client/@\1 = \2/$WORKDIR/@" $WORKDIR/client.conf +sed -ri "s/netbios name = .*/netbios name = $HOSTNAME/" $WORKDIR/client.conf +rm -f $WORKDIR/private/secrets.tdb +cd $RUNDIR + +failed=0 + +net_tool="$BINDIR/net --configfile=$BASEDIR/$WORKDIR/client.conf --option=security=ads" + +# Load test functions +. $(dirname $0)/subunit.sh +. "$(dirname "${0}")/common_test_fns.inc" + +# This test is run in environment with two DCs ('localdc' and 'localvampiredc') -- Samba Shared Repository