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 <[email protected]>
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 <[email protected]>
Signed-off-by: Pavel Filipenský <[email protected]>
Pair-Programmed-With: Pavel Filipenský <[email protected]>
Reviewed-by: Alexander Bokovoy <[email protected]>
Autobuild-User(master): Pavel Filipensky <[email protected]>
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 <[email protected]>
Autobuild-Date(v4-22-test): Thu Sep 11 11:06:53 UTC 2025 on atb-devel-224
commit 0034b13f23ab9d16d62dbf0619e24233c520dae3
Author: Pavel Filipenský <[email protected]>
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ý <[email protected]>
Reviewed-by: Alexander Bokovoy <[email protected]>
(backported from commit 36f6ac547c09f492d1dcab11570e8bcbd377cf26)
commit b26cc594a1e4e787a98164ded77be7b2ef152cb9
Author: Pavel Filipenský <[email protected]>
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ý <[email protected]>
Reviewed-by: Alexander Bokovoy <[email protected]>
(cherry picked from commit 5d2f60ae5aa96751b74901ae5384291ef338b152)
commit 69fddebd5079fdbe53b0c3ed114fbd80f1029d10
Author: MikeLiu <[email protected]>
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 <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
Reviewed-by: Noel Power <[email protected]>
Autobuild-User(master): Volker Lendecke <[email protected]>
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 <[email protected]>
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 <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
Autobuild-User(master): Volker Lendecke <[email protected]>
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 <[email protected]>
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 <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
(cherry picked from commit 43ee86c0c757e95712ed52bd336d2085485498ba)
commit cced6a07d877e6a9c47cc3deeda69195c6b20f87
Author: Ralph Boehme <[email protected]>
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 <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
(cherry picked from commit 5f7b31927733b0ff3e1207be242f1ddb2cb699bd)
commit 51fa56ad96c4240699fa2108af05df86c6a024ea
Author: Ralph Boehme <[email protected]>
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 <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
(cherry picked from commit 698a0195f72a091e9ed6b0448160c79e37761840)
commit 0ec18e6bc39595af2b25fe566c1ee140e02a6592
Author: Ralph Boehme <[email protected]>
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 <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
(cherry picked from commit 2e88ba4b4de146327c19682d59bbe34d68158bf7)
commit 15ab604ef1cbcd2c342a0ffd746cb1ff74d716f7
Author: Ralph Boehme <[email protected]>
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 <[email protected]>
Reviewed-by: Volker Lendecke <[email protected]>
(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 <[email protected]> 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