--- Begin Message ---
Package: release.debian.org
User: release.debian.org@packages.debian.org
Usertags: unblock
Severity: normal
Please unblock package samba
This is an update from 4.13.4 to 4.13.5 (requested in #984863).
[ Reason ]
This is a stability fixes release.
Full list of changes:
o Trever L. Adams <trever.adams@gmail.com>
* BUG 14634: s3:modules:vfs_virusfilter: Recent talloc changes cause infinite
start-up failure.
o Jeremy Allison <jra@samba.org>
* BUG 13992: s3: libsmb: Add missing cli_tdis() in error path if encryption
setup failed on temp proxy connection.
* BUG 14604: smbd: In conn_force_tdis_done() when forcing a connection closed
force a full reload of services.
o Andrew Bartlett <abartlet@samba.org>
* BUG 14593: dbcheck: Check Deleted Objects and reduce noise in reports about
expired tombstones.
o Ralph Boehme <slow@samba.org
* BUG 14503: s3: Fix fcntl waf configure check.
* BUG 14602: s3/auth: Implement "winbind:ignore domains".
* BUG 14617: smbd: Use fsp->conn->session_info for the initial
delete-on-close token.
o Peter Eriksson <pen@lysator.liu.se>
* BUG 14648: s3: VFS: nfs4_acls. Add missing TALLOC_FREE(frame) in error
path.
o Björn Jacke <bj@sernet.de>
* BUG 14624: classicupgrade: Treat old never expires value right.
o Volker Lendecke <vl@samba.org>
* BUG 14636: g_lock: Fix uninitalized variable reads.
o Stefan Metzmacher <metze@samba.org>
* BUG 13898: s3:pysmbd: Fix fd leak in py_smbd_create_file().
o Andreas Schneider <asn@samba.org>
* BUG 14625: lib:util: Avoid free'ing our own pointer.
o Paul Wise <pabs3@bonedaddy.net>
* BUG 12505: HEIMDAL: krb5_storage_free(NULL) should work.
[ Impact ]
At least Paul Wise is affected. See:
https://bugzilla.samba.org/show_bug.cgi?id=13992
https://bugzilla.samba.org/show_bug.cgi?id=12505
[ Tests ]
As is every samba release, the testsuite is improved.
I've also tested the package.
[ Risks ]
[ Checklist ]
[ ] all changes are documented in the d/changelog
I forgot samba was a key package, so the changelog is not complete.
The missing pieces are above.
[x] I reviewed all changes and I approve them
[x] attach debdiff against the package in testing
Attached are releavant changes (removing diff in the doc about the version).
[ Other info ]
I may ask another unblock request before the bullseye release if samba
4.13.6+ is released.
unblock samba/2:4.13.5+dfsg-1
diff --git a/Makefile b/Makefile
index 0b7b0ae8866..7f5960d5191 100644
--- a/Makefile
+++ b/Makefile
@@ -15,6 +15,9 @@ uninstall:
test:
$(WAF) test $(TEST_OPTIONS)
+testonly:
+ $(WAF) testonly $(TEST_OPTIONS)
+
perftest:
$(WAF) test --perf-test $(TEST_OPTIONS)
diff --git a/VERSION b/VERSION
index 130087004f0..c24df6ba32e 100644
--- a/VERSION
+++ b/VERSION
@@ -25,7 +25,7 @@
########################################################
SAMBA_VERSION_MAJOR=4
SAMBA_VERSION_MINOR=13
-SAMBA_VERSION_RELEASE=4
+SAMBA_VERSION_RELEASE=5
########################################################
# If a official release has a serious bug #
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 544f4377bfd..8b8c349eaa5 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,3 +1,79 @@
+ ==============================
+ Release Notes for Samba 4.13.5
+ March 09, 2021
+ ==============================
+
+
+This is the latest stable release of the Samba 4.13 release series.
+
+
+Changes since 4.13.4
+--------------------
+
+o Trever L. Adams <trever.adams@gmail.com>
+ * BUG 14634: s3:modules:vfs_virusfilter: Recent talloc changes cause infinite
+ start-up failure.
+
+o Jeremy Allison <jra@samba.org>
+ * BUG 13992: s3: libsmb: Add missing cli_tdis() in error path if encryption
+ setup failed on temp proxy connection.
+ * BUG 14604: smbd: In conn_force_tdis_done() when forcing a connection closed
+ force a full reload of services.
+
+o Andrew Bartlett <abartlet@samba.org>
+ * BUG 14593: dbcheck: Check Deleted Objects and reduce noise in reports about
+ expired tombstones.
+
+o Ralph Boehme <slow@samba.org
+ * BUG 14503: s3: Fix fcntl waf configure check.
+ * BUG 14602: s3/auth: Implement "winbind:ignore domains".
+ * BUG 14617: smbd: Use fsp->conn->session_info for the initial
+ delete-on-close token.
+
+o Peter Eriksson <pen@lysator.liu.se>
+ * BUG 14648: s3: VFS: nfs4_acls. Add missing TALLOC_FREE(frame) in error
+ path.
+
+o Björn Jacke <bj@sernet.de>
+ * BUG 14624: classicupgrade: Treat old never expires value right.
+
+o Volker Lendecke <vl@samba.org>
+ * BUG 14636: g_lock: Fix uninitalized variable reads.
+
+o Stefan Metzmacher <metze@samba.org>
+ * BUG 13898: s3:pysmbd: Fix fd leak in py_smbd_create_file().
+
+o Andreas Schneider <asn@samba.org>
+ * BUG 14625: lib:util: Avoid free'ing our own pointer.
+
+o Paul Wise <pabs3@bonedaddy.net>
+ * BUG 12505: HEIMDAL: krb5_storage_free(NULL) should work.
+
+
+#######################################
+Reporting bugs & Development Discussion
+#######################################
+
+Please discuss this release on the samba-technical mailing list or by
+joining the #samba-technical IRC channel on irc.freenode.net.
+
+If you do report problems then please try to send high quality
+feedback. If you don't provide vital information to help us track down
+the problem then you will probably be ignored. All bug reports should
+be filed under the Samba 4.1 and newer product in the project's Bugzilla
+database (https://bugzilla.samba.org/).
+
+
+======================================================================
+== Our Code, Our Bugs, Our Responsibility.
+== The Samba Team
+======================================================================
+
+
+Release notes for older releases follow:
+----------------------------------------
+
+
==============================
Release Notes for Samba 4.13.4
January 26, 2021
@@ -65,8 +141,7 @@ database (https://bugzilla.samba.org/).
======================================================================
-Release notes for older releases follow:
-----------------------------------------
+----------------------------------------------------------------------
==============================
diff --git a/lib/util/memcache.c b/lib/util/memcache.c
index 1e616bd0e9a..7b0b27eaddb 100644
--- a/lib/util/memcache.c
+++ b/lib/util/memcache.c
@@ -223,14 +223,25 @@ static void memcache_delete_element(struct memcache *cache,
TALLOC_FREE(e);
}
-static void memcache_trim(struct memcache *cache)
+static void memcache_trim(struct memcache *cache, struct memcache_element *e)
{
+ struct memcache_element *tail = NULL;
+
if (cache->max_size == 0) {
return;
}
- while ((cache->size > cache->max_size) && DLIST_TAIL(cache->mru)) {
- memcache_delete_element(cache, DLIST_TAIL(cache->mru));
+ for (tail = DLIST_TAIL(cache->mru);
+ (cache->size > cache->max_size) && (tail != NULL);
+ tail = DLIST_TAIL(cache->mru))
+ {
+ if (tail == e) {
+ tail = DLIST_PREV(tail);
+ if (tail == NULL) {
+ break;
+ }
+ }
+ memcache_delete_element(cache, tail);
}
}
@@ -351,7 +362,7 @@ void memcache_add(struct memcache *cache, enum memcache_number n,
memcpy(&mtv, cache_value.data, sizeof(mtv));
cache->size += mtv.len;
}
- memcache_trim(cache);
+ memcache_trim(cache, e);
}
void memcache_add_talloc(struct memcache *cache, enum memcache_number n,
diff --git a/lib/util/tests/test_memcache.c b/lib/util/tests/test_memcache.c
new file mode 100644
index 00000000000..8a3997817c1
--- /dev/null
+++ b/lib/util/tests/test_memcache.c
@@ -0,0 +1,161 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Copyright (C) 2021 Andreas Schneider <asn@samba.org>
+ *
+ * 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/>.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include "lib/replace/replace.h"
+#include "lib/util/talloc_stack.h"
+#include "lib/util/memcache.h"
+
+static int setup_talloc_context(void **state)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+
+ *state = frame;
+ return 0;
+}
+
+static int teardown_talloc_context(void **state)
+{
+ TALLOC_CTX *frame = *state;
+ TALLOC_FREE(frame);
+ return 0;
+}
+
+static void torture_memcache_init(void **state)
+{
+ TALLOC_CTX *mem_ctx = *state;
+ struct memcache *cache = NULL;
+
+ cache = memcache_init(mem_ctx, 0);
+ assert_non_null(cache);
+
+ TALLOC_FREE(cache);
+
+ cache = memcache_init(mem_ctx, 10);
+ assert_non_null(cache);
+
+ TALLOC_FREE(cache);
+}
+
+static void torture_memcache_add_lookup_delete(void **state)
+{
+ TALLOC_CTX *mem_ctx = *state;
+ struct memcache *cache = NULL;
+ DATA_BLOB key1, key2;
+ char *path1 = NULL, *path2 = NULL;
+
+ cache = memcache_init(mem_ctx, 0);
+ assert_non_null(cache);
+
+ key1 = data_blob_const("key1", 4);
+ path1 = talloc_strdup(mem_ctx, "/tmp/one");
+ assert_non_null(path1);
+
+ key2 = data_blob_const("key2", 4);
+ path2 = talloc_strdup(mem_ctx, "/tmp/two");
+ assert_non_null(path1);
+
+ memcache_add_talloc(cache, GETWD_CACHE, key1, &path1);
+ assert_null(path1);
+
+ memcache_add_talloc(cache, GETWD_CACHE, key2, &path2);
+ assert_null(path2);
+
+ path1 = memcache_lookup_talloc(cache, GETWD_CACHE, key1);
+ assert_non_null(path1);
+ assert_string_equal(path1, "/tmp/one");
+
+ path2 = memcache_lookup_talloc(cache, GETWD_CACHE, key2);
+ assert_non_null(path2);
+ assert_string_equal(path2, "/tmp/two");
+
+ memcache_delete(cache, GETWD_CACHE, key1);
+ path1 = memcache_lookup_talloc(cache, GETWD_CACHE, key1);
+ assert_null(path1);
+
+ memcache_flush(cache, GETWD_CACHE);
+ path2 = memcache_lookup_talloc(cache, GETWD_CACHE, key2);
+ assert_null(path2);
+
+ TALLOC_FREE(path1);
+ TALLOC_FREE(path2);
+ TALLOC_FREE(cache);
+}
+
+static void torture_memcache_add_oversize(void **state)
+{
+ TALLOC_CTX *mem_ctx = *state;
+ struct memcache *cache = NULL;
+ DATA_BLOB key1, key2;
+ char *path1 = NULL, *path2 = NULL;
+
+ cache = memcache_init(mem_ctx, 10);
+ assert_non_null(cache);
+
+ key1 = data_blob_const("key1", 4);
+ path1 = talloc_strdup(mem_ctx, "/tmp/one");
+ assert_non_null(path1);
+
+ key2 = data_blob_const("key2", 4);
+ path2 = talloc_strdup(mem_ctx, "/tmp/two");
+ assert_non_null(path1);
+
+ memcache_add_talloc(cache, GETWD_CACHE, key1, &path1);
+ assert_null(path1);
+
+ memcache_add_talloc(cache, GETWD_CACHE, key2, &path2);
+ assert_null(path2);
+
+ path1 = memcache_lookup_talloc(cache, GETWD_CACHE, key1);
+ assert_null(path1);
+
+ path2 = memcache_lookup_talloc(cache, GETWD_CACHE, key2);
+ assert_non_null(path2);
+ assert_string_equal(path2, "/tmp/two");
+
+ TALLOC_FREE(path1);
+ TALLOC_FREE(path2);
+ TALLOC_FREE(cache);
+}
+
+int main(int argc, char *argv[])
+{
+ int rc;
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(torture_memcache_init),
+ cmocka_unit_test(torture_memcache_add_lookup_delete),
+ cmocka_unit_test(torture_memcache_add_oversize),
+ };
+
+ if (argc == 2) {
+ cmocka_set_test_filter(argv[1]);
+ }
+ cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
+
+ rc = cmocka_run_group_tests(tests,
+ setup_talloc_context,
+ teardown_talloc_context);
+
+ return rc;
+}
diff --git a/lib/util/wscript_build b/lib/util/wscript_build
index bf3e44bf1d2..5a8a04965ec 100644
--- a/lib/util/wscript_build
+++ b/lib/util/wscript_build
@@ -310,4 +310,10 @@ else:
source='tests/test_util.c',
deps='cmocka replace talloc samba-util',
local_include=False,
- for_selftest=True);
+ for_selftest=True)
+
+ bld.SAMBA_BINARY('test_memcache',
+ source='tests/test_memcache.c',
+ deps='cmocka replace talloc samba-util',
+ local_include=False,
+ for_selftest=True)
diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py
index 593aa8cf6d2..d12833d9390 100644
--- a/python/samba/dbchecker.py
+++ b/python/samba/dbchecker.py
@@ -1819,6 +1819,11 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
# old static provision dumps
return False
+ if dn in self.deleted_objects_containers:
+ # The Deleted Objects container will look like an expired
+ # tombstone
+ return False
+
repl = ndr_unpack(drsblobs.replPropertyMetaDataBlob, repl_val)
isDeleted = self.find_repl_attid(repl, drsuapi.DRSUAPI_ATTID_isDeleted)
@@ -1832,7 +1837,25 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
if delta <= tombstone_delta:
return False
- self.report("SKIPING: object %s is an expired tombstone" % dn)
+ expunge_time = delete_time + tombstone_delta
+
+ delta_days = delta / (24 * 60 * 60)
+
+ if delta_days <= 2:
+ self.report("SKIPPING additional checks on object "
+ "%s which very recently "
+ "became an expired tombstone (normal)" % dn)
+ self.report("INFO: it is expected this will be expunged "
+ "by the next daily task some time after %s, "
+ "%d hours ago"
+ % (time.ctime(expunge_time), delta // (60 * 60)))
+ else:
+ self.report("SKIPPING: object %s is an expired tombstone" % dn)
+ self.report("INFO: it was expected this object would have "
+ "been expunged soon after"
+ "%s, %d days ago"
+ % (time.ctime(expunge_time), delta_days))
+
self.report("isDeleted: attid=0x%08x version=%d invocation=%s usn=%s (local=%s) at %s" % (
isDeleted.attid,
isDeleted.version,
diff --git a/python/samba/upgrade.py b/python/samba/upgrade.py
index 8511bed2868..dff856a8d7c 100644
--- a/python/samba/upgrade.py
+++ b/python/samba/upgrade.py
@@ -74,7 +74,7 @@ def import_sam_policy(samdb, policy, logger):
if 'maximum password age' in policy:
max_pw_age_unix = policy['maximum password age']
- if max_pw_age_unix == -1 or max_pw_age_unix == 0:
+ if max_pw_age_unix == -1 or max_pw_age_unix == 0 or max_pw_age_unix == 0xFFFFFFFF:
max_pw_age_nt = -0x8000000000000000
else:
max_pw_age_nt = int(-max_pw_age_unix * (1e7))
diff --git a/script/autobuild.py b/script/autobuild.py
index 0ab04eb7c26..0f837d0c109 100755
--- a/script/autobuild.py
+++ b/script/autobuild.py
@@ -4,7 +4,7 @@
# released under GNU GPL v3 or later
from __future__ import print_function
-from subprocess import call, check_call, check_output, Popen, PIPE
+from subprocess import call, check_call, check_output, Popen, PIPE, CalledProcessError
import os
import tarfile
import sys
@@ -860,6 +860,17 @@ def run_cmd(cmd, dir=".", show=None, output=False, checkfail=True):
else:
return call(cmd, shell=True, cwd=dir)
+def rmdir_force(dirname, re_raise=True):
+ try:
+ run_cmd("test -d %s && chmod -R +w %s; rm -rf %s" % (
+ dirname, dirname, dirname), output=True, show=True)
+ except CalledProcessError as e:
+ do_print("Failed: '%s'" % (str(e)))
+ run_cmd("tree %s" % dirname, output=True, show=True)
+ if re_raise:
+ raise
+ return False
+ return True
class builder(object):
'''handle build of one directory'''
@@ -882,8 +893,8 @@ class builder(object):
self.test_source_dir = "%s/%s" % (testbase, self.tag)
self.cwd = "%s/%s" % (self.test_source_dir, self.dir)
self.prefix = "%s/%s" % (test_prefix, self.tag)
- run_cmd("rm -rf %s" % self.test_source_dir)
- run_cmd("rm -rf %s" % self.prefix)
+ rmdir_force(self.test_source_dir)
+ rmdir_force(self.prefix)
if cp:
run_cmd("cp -R -a -l %s %s" % (test_master, self.test_source_dir), dir=test_master, show=True)
else:
@@ -893,8 +904,8 @@ class builder(object):
def start_next(self):
if self.next == len(self.sequence):
if not options.nocleanup:
- run_cmd("rm -rf %s" % self.test_source_dir)
- run_cmd("rm -rf %s" % self.prefix)
+ rmdir_force(self.test_source_dir)
+ rmdir_force(self.prefix)
do_print('%s: Completed OK' % self.name)
self.done = True
return
@@ -1018,7 +1029,7 @@ class buildlist(object):
'df -m %s' % testbase]:
try:
out = run_cmd(cmd, output=True, checkfail=False)
- except subprocess.CalledProcessError as e:
+ except CalledProcessError as e:
out = "<failed: %s>" % str(e)
print('### %s' % cmd, file=f)
print(out, file=f)
@@ -1048,14 +1059,23 @@ class buildlist(object):
self.tail_proc = Popen(cmd, close_fds=True)
-def cleanup():
+def cleanup(do_raise=False):
if options.nocleanup:
return
run_cmd("stat %s || true" % test_tmpdir, show=True)
run_cmd("stat %s" % testbase, show=True)
do_print("Cleaning up %r" % cleanup_list)
for d in cleanup_list:
- run_cmd("rm -rf %s" % d)
+ ok = rmdir_force(d, re_raise=False)
+ if ok:
+ continue
+ if os.path.isdir(d):
+ do_print("Killing, waiting and retry")
+ run_cmd("killbysubdir %s > /dev/null 2>&1" % d, checkfail=False)
+ else:
+ do_print("Waiting and retry")
+ time.sleep(1)
+ rmdir_force(d, re_raise=do_raise)
def daemonize(logfile):
@@ -1321,7 +1341,7 @@ while True:
(status, failed_task, failed_stage, failed_tag, errstr) = blist.run()
if status != 0 or errstr != "retry":
break
- cleanup()
+ cleanup(do_raise=True)
except Exception:
cleanup()
raise
diff --git a/selftest/selftest.pl b/selftest/selftest.pl
index d14df92a11c..258a8437922 100755
--- a/selftest/selftest.pl
+++ b/selftest/selftest.pl
@@ -280,7 +280,7 @@ my $bindir_abs = abs_path($bindir);
my $torture_maxtime = ($ENV{TORTURE_MAXTIME} or 1200);
$prefix =~ s+//+/+;
-$prefix =~ s+/./+/+;
+$prefix =~ s+/\./+/+;
$prefix =~ s+/$++;
die("using an empty prefix isn't allowed") unless $prefix ne "";
@@ -312,7 +312,6 @@ $ENV{PREFIX} = $prefix;
$ENV{PREFIX_ABS} = $prefix_abs;
$ENV{SRCDIR} = $srcdir;
$ENV{SRCDIR_ABS} = $srcdir_abs;
-$ENV{GNUPGHOME} = "$srcdir_abs/selftest/gnupg";
$ENV{BINDIR} = $bindir_abs;
my $tls_enabled = not $opt_quick;
@@ -693,6 +692,9 @@ $ENV{RESOLV_CONF} = "${selftest_resolv_conf_path}.global";
my $selftest_krbt_ccache_path = "$tmpdir_abs/selftest.krb5_ccache";
$ENV{KRB5CCNAME} = "FILE:${selftest_krbt_ccache_path}.global";
+my $selftest_gnupghome_path = "$tmpdir_abs/selftest.no.gnupg";
+$ENV{GNUPGHOME} = "${selftest_gnupghome_path}.global";
+
my @available = ();
foreach my $fn (@testlists) {
foreach (read_testlist($fn)) {
@@ -829,6 +831,7 @@ sub setup_env($$)
$ENV{RESOLV_CONF} = "${selftest_resolv_conf_path}.${envname}/ignore";
$ENV{KRB5CCNAME} = "FILE:${selftest_krbt_ccache_path}.${envname}/ignore";
+ $ENV{GNUPGHOME} = "${selftest_gnupghome_path}.${envname}/ignore";
if (defined(get_running_env($envname))) {
$testenv_vars = get_running_env($envname);
diff --git a/selftest/target/Samba.pm b/selftest/target/Samba.pm
index 6118f2e243a..d47f933376e 100644
--- a/selftest/target/Samba.pm
+++ b/selftest/target/Samba.pm
@@ -280,6 +280,30 @@ EOF
umask $oldumask;
}
+sub copy_gnupg_home($)
+{
+ my ($ctx) = @_;
+
+ my $gnupg_srcdir = "$ENV{SRCDIR_ABS}/selftest/gnupg";
+ my @files = (
+ "gpg.conf",
+ "pubring.gpg",
+ "secring.gpg",
+ "trustdb.gpg",
+ );
+
+ my $oldumask = umask;
+ umask 0077;
+ mkdir($ctx->{gnupghome}, 0777);
+ umask 0177;
+ foreach my $file (@files) {
+ my $srcfile = "${gnupg_srcdir}/${file}";
+ my $dstfile = "$ctx->{gnupghome}/${file}";
+ copy_file_content(${srcfile}, ${dstfile});
+ }
+ umask $oldumask;
+}
+
sub mk_krb5_conf($$)
{
my ($ctx) = @_;
@@ -672,6 +696,7 @@ sub get_env_for_process
RESOLV_CONF => $env_vars->{RESOLV_CONF},
KRB5_CONFIG => $env_vars->{KRB5_CONFIG},
KRB5CCNAME => "$env_vars->{KRB5_CCACHE}.$proc_name",
+ GNUPGHOME => $env_vars->{GNUPGHOME},
SELFTEST_WINBINDD_SOCKET_DIR => $env_vars->{SELFTEST_WINBINDD_SOCKET_DIR},
NMBD_SOCKET_DIR => $env_vars->{NMBD_SOCKET_DIR},
NSS_WRAPPER_PASSWD => $env_vars->{NSS_WRAPPER_PASSWD},
@@ -857,6 +882,7 @@ my @exported_envvars = (
# misc stuff
"KRB5_CONFIG",
"KRB5CCNAME",
+ "GNUPGHOME",
"SELFTEST_WINBINDD_SOCKET_DIR",
"NMBD_SOCKET_DIR",
"LOCAL_PATH",
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index e141f102ef1..c15057fa80b 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -723,6 +723,7 @@ sub provision_ad_member
my $ret = $self->provision(
prefix => $prefix,
domain => $dcvars->{DOMAIN},
+ realm => $dcvars->{REALM},
server => "LOCALADMEMBER",
password => "loCalMemberPass",
extra_options => $member_options,
@@ -873,6 +874,7 @@ sub setup_ad_member_rfc2307
my $ret = $self->provision(
prefix => $prefix,
domain => $dcvars->{DOMAIN},
+ realm => $dcvars->{REALM},
server => "RFC2307MEMBER",
password => "loCalMemberPass",
extra_options => $member_options,
@@ -970,6 +972,7 @@ sub setup_ad_member_idmap_rid
my $ret = $self->provision(
prefix => $prefix,
domain => $dcvars->{DOMAIN},
+ realm => $dcvars->{REALM},
server => "IDMAPRIDMEMBER",
password => "loCalMemberPass",
extra_options => $member_options,
@@ -1067,6 +1070,7 @@ sub setup_ad_member_idmap_ad
my $ret = $self->provision(
prefix => $prefix,
domain => $dcvars->{DOMAIN},
+ realm => $dcvars->{REALM},
server => "IDMAPADMEMBER",
password => "loCalMemberPass",
extra_options => $member_options,
@@ -1727,12 +1731,22 @@ $ret->{USERNAME} = KTEST\\Administrator
sub setup_maptoguest
{
my ($self, $path) = @_;
+ my $prefix_abs = abs_path($path);
+ my $libdir="$prefix_abs/lib";
+ my $share_dir="$prefix_abs/share";
+ my $errorinjectconf="$libdir/error_inject.conf";
print "PROVISIONING maptoguest...";
my $options = "
map to guest = bad user
ntlm auth = yes
+
+[force_user_error_inject]
+ path = $share_dir
+ vfs objects = acl_xattr fake_acls xattr_tdb error_inject
+ force user = user1
+ include = $errorinjectconf
";
my $vars = $self->provision(
@@ -1930,6 +1944,7 @@ sub provision($$)
my $prefix = $args{prefix};
my $domain = $args{domain};
+ my $realm = $args{realm};
my $server = $args{server};
my $password = $args{password};
my $extra_options = $args{extra_options};
@@ -1947,6 +1962,12 @@ sub provision($$)
my %createuser_env = ();
my $server_ip = Samba::get_ipv4_addr($server);
my $server_ipv6 = Samba::get_ipv6_addr($server);
+ my $dns_domain;
+ if (defined($realm)) {
+ $dns_domain = lc($realm);
+ } else {
+ $dns_domain = "samba.example.com";
+ }
my $unix_name = ($ENV{USER} or $ENV{LOGNAME} or `PATH=/usr/ucb:$ENV{PATH} whoami`);
chomp $unix_name;
@@ -2926,8 +2947,8 @@ force_user:x:$gid_force_user:
warn("Unable to open $nss_wrapper_hosts");
return undef;
}
- print HOSTS "${server_ip} ${hostname}.samba.example.com ${hostname}\n";
- print HOSTS "${server_ipv6} ${hostname}.samba.example.com ${hostname}\n";
+ print HOSTS "${server_ip} ${hostname}.${dns_domain} ${hostname}\n";
+ print HOSTS "${server_ipv6} ${hostname}.${dns_domain} ${hostname}\n";
close(HOSTS);
$resolv_conf = "$privatedir/no_resolv.conf" unless defined($resolv_conf);
diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index 649e923ff9a..77bd741d476 100755
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -17,7 +17,6 @@ use SocketWrapper;
use target::Samba;
use target::Samba3;
use Archive::Tar;
-use File::Path 'make_path';
sub new($$$$$) {
my ($classname, $SambaCtx, $bindir, $srcdir, $server_maxtime) = @_;
@@ -161,19 +160,7 @@ sub wait_for_start($$)
my $max_wait = 60;
# Add hosts file for name lookups
- my $cmd = "NSS_WRAPPER_HOSTS='$testenv_vars->{NSS_WRAPPER_HOSTS}' ";
- if (defined($testenv_vars->{RESOLV_WRAPPER_CONF})) {
- $cmd .= "RESOLV_WRAPPER_CONF='$testenv_vars->{RESOLV_WRAPPER_CONF}' ";
- } else {
- $cmd .= "RESOLV_WRAPPER_HOSTS='$testenv_vars->{RESOLV_WRAPPER_HOSTS}' ";
- }
- $cmd .= "RESOLV_CONF='$testenv_vars->{RESOLV_CONF}' ";
- if (defined($testenv_vars->{GNUTLS_FORCE_FIPS_MODE})) {
- $cmd .= "GNUTLS_FORCE_FIPS_MODE=$testenv_vars->{GNUTLS_FORCE_FIPS_MODE} ";
- }
- if (defined($testenv_vars->{OPENSSL_FORCE_FIPS_MODE})) {
- $cmd .= "OPENSSL_FORCE_FIPS_MODE=$testenv_vars->{OPENSSL_FORCE_FIPS_MODE} ";
- }
+ my $cmd = $self->get_cmd_env_vars($testenv_vars);
$cmd .= "$ldbsearch ";
$cmd .= "$testenv_vars->{CONFIGURATION} ";
@@ -281,7 +268,7 @@ sub setup_dns_hub_internal($$$)
my ($self, $hostname, $prefix) = @_;
my $STDIN_READER;
- unless(-d $prefix or make_path($prefix, 0777)) {
+ unless(-d $prefix or mkdir($prefix, 0777)) {
warn("Unable to create $prefix");
return undef;
}
@@ -356,6 +343,10 @@ sub setup_dns_hub
my $hostname = "rootdnsforwarder";
+ unless(-d $prefix or mkdir($prefix, 0777)) {
+ warn("Unable to create $prefix");
+ return undef;
+ }
my $env = $self->setup_dns_hub_internal("$hostname", "$prefix/$hostname");
$self->{dns_hub_env} = $env;
@@ -375,10 +366,44 @@ sub get_dns_hub_env($)
return undef;
}
+sub return_env_value
+{
+ my ($env, $overwrite, $key) = @_;
+
+ if (defined($overwrite) and defined($overwrite->{$key})) {
+ return $overwrite->{$key};
+ }
+
+ if (defined($env->{$key})) {
+ return $env->{$key};
+ }
+
+ return undef;
+}
+
# Returns the environmental variables that we pass to samba-tool commands
sub get_cmd_env_vars
{
- my ($self, $localenv) = @_;
+ my ($self, $givenenv, $overwrite) = @_;
+
+ my @keys = (
+ "NSS_WRAPPER_HOSTS",
+ "SOCKET_WRAPPER_DEFAULT_IFACE",
+ "RESOLV_CONF",
+ "RESOLV_WRAPPER_CONF",
+ "RESOLV_WRAPPER_HOSTS",
+ "GNUTLS_FORCE_FIPS_MODE",
+ "OPENSSL_FORCE_FIPS_MODE",
+ "KRB5_CONFIG",
+ "KRB5_CCACHE",
+ "GNUPGHOME",
+ );
+
+ my $localenv = undef;
+ foreach my $key (@keys) {
+ my $v = return_env_value($givenenv, $overwrite, $key);
+ $localenv->{$key} = $v if defined($v);
+ }
my $cmd_env = "NSS_WRAPPER_HOSTS='$localenv->{NSS_WRAPPER_HOSTS}' ";
$cmd_env .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$localenv->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
@@ -393,9 +418,10 @@ sub get_cmd_env_vars
if (defined($localenv->{OPENSSL_FORCE_FIPS_MODE})) {
$cmd_env .= "OPENSSL_FORCE_FIPS_MODE=$localenv->{OPENSSL_FORCE_FIPS_MODE} ";
}
- $cmd_env .= " KRB5_CONFIG=\"$localenv->{KRB5_CONFIG}\" ";
+ $cmd_env .= "KRB5_CONFIG=\"$localenv->{KRB5_CONFIG}\" ";
$cmd_env .= "KRB5CCNAME=\"$localenv->{KRB5_CCACHE}\" ";
$cmd_env .= "RESOLV_CONF=\"$localenv->{RESOLV_CONF}\" ";
+ $cmd_env .= "GNUPGHOME=\"$localenv->{GNUPGHOME}\" ";
return $cmd_env;
}
@@ -565,6 +591,7 @@ sub provision_raw_prepare($$$$$$$$$$$$$$)
$ctx->{krb5_conf} = "$ctx->{etcdir}/krb5.conf";
$ctx->{krb5_ccache} = "$prefix_abs/krb5_ccache";
$ctx->{mitkdc_conf} = "$ctx->{etcdir}/mitkdc.conf";
+ $ctx->{gnupghome} = "$prefix_abs/gnupg";
$ctx->{privatedir} = "$prefix_abs/private";
$ctx->{binddnsdir} = "$prefix_abs/bind-dns";
$ctx->{ncalrpcdir} = "$prefix_abs/ncalrpc";
@@ -608,8 +635,9 @@ sub provision_raw_prepare($$$$$$$$$$$$$$)
$ctx->{smb_conf_extra_options} = "";
my @provision_options = ();
+ push (@provision_options, "GNUPGHOME=\"$ctx->{gnupghome}\"");
push (@provision_options, "KRB5_CONFIG=\"$ctx->{krb5_conf}\"");
- push (@provision_options, "KRB5_CCACHE=\"$ctx->{krb5_ccache}\"");
+ push (@provision_options, "KRB5CCNAME=\"$ctx->{krb5_ccache}\"");
push (@provision_options, "NSS_WRAPPER_PASSWD=\"$ctx->{nsswrap_passwd}\"");
push (@provision_options, "NSS_WRAPPER_GROUP=\"$ctx->{nsswrap_group}\"");
push (@provision_options, "NSS_WRAPPER_HOSTS=\"$ctx->{nsswrap_hosts}\"");
@@ -700,6 +728,7 @@ sub provision_raw_step1($$)
return undef;
}
+ Samba::copy_gnupg_home($ctx);
Samba::prepare_keyblobs($ctx);
my $crlfile = "$ctx->{tlsdir}/crl.pem";
$crlfile = "" unless -e ${crlfile};
@@ -843,6 +872,7 @@ nogroup:x:65534:nobody
# Note that we have SERVER_X and DC_SERVER_X variables (which have the same
# value initially). In a 2 DC setup, $DC_SERVER_X will always be the PDC.
my $ret = {
+ GNUPGHOME => $ctx->{gnupghome},
KRB5_CONFIG => $ctx->{krb5_conf},
KRB5_CCACHE => $ctx->{krb5_ccache},
MITKDC_CONFIG => $ctx->{mitkdc_conf},
@@ -922,11 +952,10 @@ sub provision_raw_step2($$$)
return undef;
}
+ my $cmd_env = $self->get_cmd_env_vars($ret);
+
my $testallowed_account = "testallowed";
- my $samba_tool_cmd = "";
- $samba_tool_cmd .= "RESOLV_CONF=\"$ret->{RESOLV_CONF}\" ";
- $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
- $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
+ my $samba_tool_cmd = ${cmd_env};
$samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
. " user create --configfile=$ctx->{smb_conf} $testallowed_account $ctx->{password}";
unless (system($samba_tool_cmd) == 0) {
@@ -935,10 +964,7 @@ sub provision_raw_step2($$$)
}
my $srv_account = "srv_account";
- $samba_tool_cmd = "";
- $samba_tool_cmd .= "RESOLV_CONF=\"$ret->{RESOLV_CONF}\" ";
- $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
- $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
+ $samba_tool_cmd = ${cmd_env};
$samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
. " user create --configfile=$ctx->{smb_conf} $srv_account $ctx->{password}";
unless (system($samba_tool_cmd) == 0) {
@@ -946,10 +972,7 @@ sub provision_raw_step2($$$)
return undef;
}
- $samba_tool_cmd = "";
- $samba_tool_cmd .= "RESOLV_CONF=\"$ret->{RESOLV_CONF}\" ";
- $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
- $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
+ $samba_tool_cmd = ${cmd_env};
$samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
. " spn add HOST/$srv_account --configfile=$ctx->{smb_conf} $srv_account";
unless (system($samba_tool_cmd) == 0) {
@@ -957,10 +980,7 @@ sub provision_raw_step2($$$)
return undef;
}
- my $ldbmodify = "";
- $ldbmodify .= "RESOLV_CONF=\"$ret->{RESOLV_CONF}\" ";
- $ldbmodify .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
- $ldbmodify .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
+ my $ldbmodify = ${cmd_env};
$ldbmodify .= Samba::bindir_path($self, "ldbmodify");
$ldbmodify .= " --configfile=$ctx->{smb_conf}";
my $base_dn = "DC=".join(",DC=", split(/\./, $ctx->{realm}));
@@ -991,10 +1011,7 @@ servicePrincipalName: host/testallowed
";
close(LDIF);
- $samba_tool_cmd = "";
- $samba_tool_cmd .= "RESOLV_CONF=\"$ret->{RESOLV_CONF}\" ";
- $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
- $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
+ $samba_tool_cmd = ${cmd_env};
$samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
. " user create --configfile=$ctx->{smb_conf} testdenied $ctx->{password}";
unless (system($samba_tool_cmd) == 0) {
@@ -1012,10 +1029,7 @@ userPrincipalName: testdenied_upn\@$ctx->{realm}.upn
";
close(LDIF);
- $samba_tool_cmd = "";
- $samba_tool_cmd .= "RESOLV_CONF=\"$ret->{RESOLV_CONF}\" ";
- $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
- $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
+ $samba_tool_cmd = ${cmd_env};
$samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
. " user create --configfile=$ctx->{smb_conf} testupnspn $ctx->{password}";
unless (system($samba_tool_cmd) == 0) {
@@ -1035,10 +1049,7 @@ servicePrincipalName: http/testupnspn.$ctx->{dnsname}
";
close(LDIF);
- $samba_tool_cmd = "";
- $samba_tool_cmd .= "RESOLV_CONF=\"$ret->{RESOLV_CONF}\" ";
- $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
- $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
+ $samba_tool_cmd = ${cmd_env};
$samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
. " group addmembers --configfile=$ctx->{smb_conf} 'Allowed RODC Password Replication Group' '$testallowed_account'";
unless (system($samba_tool_cmd) == 0) {
@@ -1050,11 +1061,8 @@ servicePrincipalName: http/testupnspn.$ctx->{dnsname}
my $user_account_array = ["alice", "bob", "jane", "joe"];
foreach my $user_account (@{$user_account_array}) {
- my $samba_tool_cmd = "";
+ my $samba_tool_cmd = ${cmd_env};
- $samba_tool_cmd .= "RESOLV_CONF=\"$ret->{RESOLV_CONF}\" ";
- $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
- $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
$samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
. " user create --configfile=$ctx->{smb_conf} $user_account Secret007";
unless (system($samba_tool_cmd) == 0) {
@@ -1066,10 +1074,8 @@ servicePrincipalName: http/testupnspn.$ctx->{dnsname}
my $group_array = ["Samba Users"];
foreach my $group (@{$group_array}) {
- my $samba_tool_cmd = "";
+ my $samba_tool_cmd = ${cmd_env};
- $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
- $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
$samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
. " group add --configfile=$ctx->{smb_conf} \"$group\"";
unless (system($samba_tool_cmd) == 0) {
@@ -1079,12 +1085,10 @@ servicePrincipalName: http/testupnspn.$ctx->{dnsname}
}
# Add user joe to group "Samba Users"
- $samba_tool_cmd = "";
my $group = "Samba Users";
my $user_account = "joe";
- $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
- $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
+ $samba_tool_cmd = ${cmd_env};
$samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
. " group addmembers --configfile=$ctx->{smb_conf} \"$group\" $user_account";
unless (system($samba_tool_cmd) == 0) {
@@ -1092,12 +1096,10 @@ servicePrincipalName: http/testupnspn.$ctx->{dnsname}
return undef;
}
- $samba_tool_cmd = "";
$group = "Samba Users";
$user_account = "joe";
- $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
- $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
+ $samba_tool_cmd = ${cmd_env};
$samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
. " user setprimarygroup --configfile=$ctx->{smb_conf} $user_account \"$group\"";
unless (system($samba_tool_cmd) == 0) {
@@ -1106,10 +1108,7 @@ servicePrincipalName: http/testupnspn.$ctx->{dnsname}
}
# Change the userPrincipalName for jane
- $ldbmodify = "";
- $ldbmodify .= "RESOLV_CONF=\"$ret->{RESOLV_CONF}\" ";
- $ldbmodify .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
- $ldbmodify .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
+ $ldbmodify = ${cmd_env};
$ldbmodify .= Samba::bindir_path($self, "ldbmodify");
$ldbmodify .= " --configfile=$ctx->{smb_conf}";
$base_dn = "DC=".join(",DC=", split(/\./, $ctx->{realm}));
@@ -1409,12 +1408,13 @@ sub provision_rpc_proxy($$$)
return undef;
}
+ # Prepare a context of the DC, but using the local CCACHE.
+ my $overwrite = undef;
+ $overwrite->{KRB5_CCACHE} = $ret->{KRB5_CCACHE};
+ my $dc_cmd_env = $self->get_cmd_env_vars($dcvars, $overwrite);
+
# Setting up delegation runs in the context of the DC for now
- $cmd = "";
- $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$dcvars->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
- $cmd .= "KRB5_CONFIG=\"$dcvars->{KRB5_CONFIG}\" ";
- $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
- $cmd .= "RESOLV_CONF=\"$dcvars->{RESOLV_CONF}\" ";
+ $cmd = $dc_cmd_env;
$cmd .= "$samba_tool delegation for-any-protocol '$ret->{NETBIOSNAME}\$' on";
$cmd .= " $dcvars->{CONFIGURATION}";
print $cmd;
@@ -1425,11 +1425,7 @@ sub provision_rpc_proxy($$$)
}
# Setting up delegation runs in the context of the DC for now
- $cmd = "";
- $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$dcvars->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
- $cmd .= "KRB5_CONFIG=\"$dcvars->{KRB5_CONFIG}\" ";
- $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
- $cmd .= "RESOLV_CONF=\"$dcvars->{RESOLV_CONF}\" ";
+ $cmd = $dc_cmd_env;
$cmd .= "$samba_tool delegation add-service '$ret->{NETBIOSNAME}\$' cifs/$dcvars->{SERVER}";
$cmd .= " $dcvars->{CONFIGURATION}";
@@ -1824,9 +1820,7 @@ sub provision_rodc($$$)
# This ensures deterministic behaviour for tests that want to have the 'testallowed account'
# user password verified on the RODC
my $testallowed_account = "testallowed account";
- $cmd = "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
- $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
- $cmd .= "RESOLV_CONF=\"$ret->{RESOLV_CONF}\" ";
+ $cmd = $self->get_cmd_env_vars($ret);
$cmd .= "$samba_tool rodc preload '$testallowed_account' $ret->{CONFIGURATION}";
$cmd .= " --server=$dcvars->{DC_SERVER}";
@@ -2502,14 +2496,10 @@ sub setup_promoted_dc
# force source and replicated DC to update repsTo/repsFrom
# for vampired partitions
my $samba_tool = Samba::bindir_path($self, "samba-tool");
- my $cmd = "NSS_WRAPPER_HOSTS='$env->{NSS_WRAPPER_HOSTS}' ";
+ my $cmd = $self->get_cmd_env_vars($env);
# as 'vampired' dc may add data in its local replica
# we need to synchronize data between DCs
my $base_dn = "DC=".join(",DC=", split(/\./, $dc_vars->{REALM}));
- $cmd = "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
- $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
- $cmd .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
- $cmd .= "RESOLV_CONF=\"$env->{RESOLV_CONF}\" ";
$cmd .= " $samba_tool drs replicate $env->{DC_SERVER} $env->{SERVER}";
$cmd .= " $dc_vars->{CONFIGURATION}";
$cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
@@ -2545,14 +2535,9 @@ sub setup_rodc
}
my $samba_tool = Samba::bindir_path($self, "samba-tool");
- my $cmd = "";
+ my $cmd = $self->get_cmd_env_vars($env);
my $base_dn = "DC=".join(",DC=", split(/\./, $dc_vars->{REALM}));
- $cmd .= "NSS_WRAPPER_HOSTS='$env->{NSS_WRAPPER_HOSTS}' ";
- $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
- $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
- $cmd .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
- $cmd .= "RESOLV_CONF=\"$env->{RESOLV_CONF}\" ";
$cmd .= " $samba_tool drs replicate $env->{SERVER} $env->{DC_SERVER}";
$cmd .= " $dc_vars->{CONFIGURATION}";
$cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
@@ -2857,16 +2842,7 @@ sub setup_schema_pair_dc
"");
my $samba_tool = Samba::bindir_path($self, "samba-tool");
- my $cmd_vars = "NSS_WRAPPER_HOSTS='$env->{NSS_WRAPPER_HOSTS}' ";
- $cmd_vars .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
- if (defined($env->{RESOLV_WRAPPER_CONF})) {
- $cmd_vars .= "RESOLV_WRAPPER_CONF=\"$env->{RESOLV_WRAPPER_CONF}\" ";
- } else {
- $cmd_vars .= "RESOLV_WRAPPER_HOSTS=\"$env->{RESOLV_WRAPPER_HOSTS}\" ";
- }
- $cmd_vars .= "KRB5_CONFIG=\"$env->{KRB5_CONFIG}\" ";
- $cmd_vars .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
- $cmd_vars .= "RESOLV_CONF=\"$env->{RESOLV_CONF}\" ";
+ my $cmd_vars = $self->get_cmd_env_vars($env);
my $join_cmd = $cmd_vars;
$join_cmd .= "$samba_tool domain join $env->{CONFIGURATION} $dcvars->{REALM} DC --realm=$dcvars->{REALM}";
@@ -3008,17 +2984,10 @@ sub create_backup
my ($self, $env, $dcvars, $backupdir, $backup_cmd) = @_;
# get all the env variables we pass in with the samba-tool command
- my $cmd_env = "NSS_WRAPPER_HOSTS='$env->{NSS_WRAPPER_HOSTS}' ";
- $cmd_env .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
- if (defined($env->{RESOLV_WRAPPER_CONF})) {
- $cmd_env .= "RESOLV_WRAPPER_CONF=\"$env->{RESOLV_WRAPPER_CONF}\" ";
- } else {
- $cmd_env .= "RESOLV_WRAPPER_HOSTS=\"$env->{RESOLV_WRAPPER_HOSTS}\" ";
- }
- $cmd_env .= "RESOLV_CONF=\"$env->{RESOLV_CONF}\" ";
# Note: use the backupfrom-DC's krb5.conf to do the backup
- $cmd_env .= " KRB5_CONFIG=\"$dcvars->{KRB5_CONFIG}\" ";
- $cmd_env .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
+ my $overwrite = undef;
+ $overwrite->{KRB5_CONFIG} = $dcvars->{KRB5_CONFIG};
+ my $cmd_env = $self->get_cmd_env_vars($env, $overwrite);
# use samba-tool to create a backup from the 'backupfromdc' DC
my $cmd = "";
diff --git a/selftest/tests.py b/selftest/tests.py
index 6918e1306c3..2b65943b2ed 100644
--- a/selftest/tests.py
+++ b/selftest/tests.py
@@ -398,6 +398,8 @@ plantestsuite("samba.unittests.util_paths", "none",
[os.path.join(bindir(), "default/lib/util/test_util_paths")])
plantestsuite("samba.unittests.util", "none",
[os.path.join(bindir(), "default/lib/util/test_util")])
+plantestsuite("samba.unittests.memcache", "none",
+ [os.path.join(bindir(), "default/lib/util/test_memcache")])
plantestsuite("samba.unittests.ntlm_check", "none",
[os.path.join(bindir(), "default/libcli/auth/test_ntlm_check")])
plantestsuite("samba.unittests.gnutls", "none",
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index 9427c05f573..4686b29111e 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -485,6 +485,14 @@ NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
return NT_STATUS_LOGON_FAILURE;
}
+ if (!is_allowed_domain(server_info->info3->base.logon_domain.string)) {
+ DBG_NOTICE("Authentication failed for user [%s] "
+ "from firewalled domain [%s]\n",
+ server_info->info3->base.account_name.string,
+ server_info->info3->base.logon_domain.string);
+ return NT_STATUS_AUTHENTICATION_FIREWALL_FAILED;
+ }
+
if (server_info->cached_session_info != NULL) {
session_info = copy_session_info(mem_ctx,
server_info->cached_session_info);
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 12aa392abae..de5d1be5208 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -322,6 +322,7 @@ struct passwd *Get_Pwnam_alloc(TALLOC_CTX *mem_ctx, const char *user);
/* The following definitions come from lib/util_names.c */
const char *get_global_sam_name(void);
const char *my_sam_name(void);
+bool is_allowed_domain(const char *domain_name);
/* The following definitions come from lib/util.c */
diff --git a/source3/lib/g_lock.c b/source3/lib/g_lock.c
index c36539393e1..36b527706da 100644
--- a/source3/lib/g_lock.c
+++ b/source3/lib/g_lock.c
@@ -646,8 +646,8 @@ static void g_lock_lock_retry(struct tevent_req *subreq)
struct g_lock_lock_state *state = tevent_req_data(
req, struct g_lock_lock_state);
struct g_lock_lock_fn_state fn_state;
- struct server_id blocker;
- bool blockerdead;
+ struct server_id blocker = { .pid = 0 };
+ bool blockerdead = false;
NTSTATUS status;
status = dbwrap_watched_watch_recv(subreq, &blockerdead, &blocker);
diff --git a/source3/lib/util_names.c b/source3/lib/util_names.c
index 15236c913df..630a25875c7 100644
--- a/source3/lib/util_names.c
+++ b/source3/lib/util_names.c
@@ -182,3 +182,23 @@ const char *my_sam_name(void)
return lp_workgroup();
}
+
+bool is_allowed_domain(const char *domain_name)
+{
+ const char **ignored_domains = NULL;
+ const char **dom = NULL;
+
+ ignored_domains = lp_parm_string_list(-1,
+ "winbind",
+ "ignore domains",
+ NULL);
+
+ for (dom = ignored_domains; dom != NULL && *dom != NULL; dom++) {
+ if (gen_fnmatch(*dom, domain_name) == 0) {
+ DBG_NOTICE("Ignoring domain '%s'\n", domain_name);
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index 4495a027830..3cc52cc5ac9 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -1230,6 +1230,7 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
if (force_encrypt) {
status = cli_cm_force_encryption_creds(cli, creds, "IPC$");
if (!NT_STATUS_IS_OK(status)) {
+ cli_tdis(cli);
cli_state_restore_tcon(cli, orig_tcon);
return false;
}
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index 4412651f505..8ded372d0ba 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -352,11 +352,37 @@ uint32_t cli_state_set_tid(struct cli_state *cli, uint32_t tid)
struct smbXcli_tcon *cli_state_save_tcon(struct cli_state *cli)
{
+ /*
+ * Note. This used to make a deep copy of either
+ * cli->smb2.tcon or cli->smb1.tcon, but this leaves
+ * the original pointer in place which will then get
+ * TALLOC_FREE()'d when the new connection is made on
+ * this cli_state.
+ *
+ * As there may be pipes open on the old connection with
+ * talloc'ed state allocated using the tcon pointer as a
+ * parent we can't deep copy and then free this as that
+ * closes the open pipes.
+ *
+ * This call is used to temporarily swap out a tcon pointer
+ * to allow a new tcon on the same cli_state.
+ *
+ * Just return the raw pointer and set the old value to NULL.
+ * We know we MUST be calling cli_state_restore_tcon() below
+ * to restore before closing the session.
+ *
+ * See BUG: https://bugzilla.samba.org/show_bug.cgi?id=13992
+ */
+ struct smbXcli_tcon *tcon_ret = NULL;
+
if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
- return smbXcli_tcon_copy(cli, cli->smb2.tcon);
+ tcon_ret = cli->smb2.tcon;
+ cli->smb2.tcon = NULL; /* *Not* TALLOC_FREE(). */
} else {
- return smbXcli_tcon_copy(cli, cli->smb1.tcon);
+ tcon_ret = cli->smb1.tcon;
+ cli->smb1.tcon = NULL; /* *Not* TALLOC_FREE(). */
}
+ return tcon_ret;
}
void cli_state_restore_tcon(struct cli_state *cli, struct smbXcli_tcon *tcon)
diff --git a/source3/locking/share_mode_lock.c b/source3/locking/share_mode_lock.c
index 1c4d3a42221..d4c27e4d654 100644
--- a/source3/locking/share_mode_lock.c
+++ b/source3/locking/share_mode_lock.c
@@ -2256,7 +2256,7 @@ static bool share_mode_entry_do(
struct locking_tdb_data *ltdb = NULL;
size_t idx;
bool found = false;
- bool modified;
+ bool modified = false;
struct share_mode_entry e;
uint8_t *e_ptr = NULL;
bool have_share_modes;
diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c
index 7f32e681694..c7808037a09 100644
--- a/source3/modules/nfs4_acls.c
+++ b/source3/modules/nfs4_acls.c
@@ -997,6 +997,7 @@ NTSTATUS smb_set_nt_acl_nfs4(vfs_handle_struct *handle, files_struct *fsp,
}
if (security_descriptor_with_ms_nfs(psd)) {
+ TALLOC_FREE(frame);
return NT_STATUS_OK;
}
diff --git a/source3/modules/vfs_error_inject.c b/source3/modules/vfs_error_inject.c
index 04880ffd5ab..d8731c29610 100644
--- a/source3/modules/vfs_error_inject.c
+++ b/source3/modules/vfs_error_inject.c
@@ -30,6 +30,7 @@ struct unix_error_map {
{ "ESTALE", ESTALE },
{ "EBADF", EBADF },
{ "EINTR", EINTR },
+ { "EACCES", EACCES },
};
static int find_unix_error_from_string(const char *err_str)
@@ -122,10 +123,46 @@ static int vfs_error_inject_openat(struct vfs_handle_struct *handle,
return SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, flags, mode);
}
+static int vfs_error_inject_unlinkat(struct vfs_handle_struct *handle,
+ struct files_struct *dirfsp,
+ const struct smb_filename *smb_fname,
+ int flags)
+{
+ struct smb_filename *parent_fname = NULL;
+ int error = inject_unix_error("unlinkat", handle);
+ int ret;
+ bool ok;
+
+ if (error == 0) {
+ return SMB_VFS_NEXT_UNLINKAT(handle, dirfsp, smb_fname, flags);
+ }
+
+ ok = parent_smb_fname(talloc_tos(), smb_fname, &parent_fname, NULL);
+ if (!ok) {
+ return -1;
+ }
+
+ ret = SMB_VFS_STAT(handle->conn, parent_fname);
+ if (ret != 0) {
+ TALLOC_FREE(parent_fname);
+ return -1;
+ }
+
+ if (parent_fname->st.st_ex_uid == get_current_uid(dirfsp->conn)) {
+ TALLOC_FREE(parent_fname);
+ return SMB_VFS_NEXT_UNLINKAT(handle, dirfsp, smb_fname, flags);
+ }
+
+ TALLOC_FREE(parent_fname);
+ errno = error;
+ return -1;
+}
+
static struct vfs_fn_pointers vfs_error_inject_fns = {
.chdir_fn = vfs_error_inject_chdir,
.pwrite_fn = vfs_error_inject_pwrite,
.openat_fn = vfs_error_inject_openat,
+ .unlinkat_fn = vfs_error_inject_unlinkat,
};
static_decl_vfs;
diff --git a/source3/modules/vfs_virusfilter.c b/source3/modules/vfs_virusfilter.c
index dc3f040363d..466aec920be 100644
--- a/source3/modules/vfs_virusfilter.c
+++ b/source3/modules/vfs_virusfilter.c
@@ -267,18 +267,21 @@ static int virusfilter_vfs_connect(
infected_file_command = lp_parm_const_string(
snum, "virusfilter", "infected file command", NULL);
- config->infected_file_command = talloc_strdup(config, infected_file_command);
- if (config->infected_file_command == NULL) {
- DBG_ERR("virusfilter-vfs: out of memory!\n");
- return -1;
+ if (infected_file_command != NULL) {
+ config->infected_file_command = talloc_strdup(config, infected_file_command);
+ if (config->infected_file_command == NULL) {
+ DBG_ERR("virusfilter-vfs: out of memory!\n");
+ return -1;
+ }
}
-
scan_error_command = lp_parm_const_string(
snum, "virusfilter", "scan error command", NULL);
- config->scan_error_command = talloc_strdup(config, scan_error_command);
- if (config->scan_error_command == NULL) {
- DBG_ERR("virusfilter-vfs: out of memory!\n");
- return -1;
+ if (scan_error_command != NULL) {
+ config->scan_error_command = talloc_strdup(config, scan_error_command);
+ if (config->scan_error_command == NULL) {
+ DBG_ERR("virusfilter-vfs: out of memory!\n");
+ return -1;
+ }
}
config->block_access_on_error = lp_parm_bool(
@@ -290,10 +293,12 @@ static int virusfilter_vfs_connect(
quarantine_dir = lp_parm_const_string(
snum, "virusfilter", "quarantine directory",
tmp ? tmp : "/tmp/.quarantine");
- config->quarantine_dir = talloc_strdup(config, quarantine_dir);
- if (config->quarantine_dir == NULL) {
- DBG_ERR("virusfilter-vfs: out of memory!\n");
- return -1;
+ if (quarantine_dir != NULL) {
+ config->quarantine_dir = talloc_strdup(config, quarantine_dir);
+ if (config->quarantine_dir == NULL) {
+ DBG_ERR("virusfilter-vfs: out of memory!\n");
+ return -1;
+ }
}
if (tmp != config->quarantine_dir) {
@@ -311,42 +316,50 @@ static int virusfilter_vfs_connect(
quarantine_prefix = lp_parm_const_string(
snum, "virusfilter", "quarantine prefix",
VIRUSFILTER_DEFAULT_QUARANTINE_PREFIX);
- config->quarantine_prefix = talloc_strdup(config, quarantine_prefix);
- if (config->quarantine_prefix == NULL) {
- DBG_ERR("virusfilter-vfs: out of memory!\n");
- return -1;
+ if (quarantine_prefix != NULL) {
+ config->quarantine_prefix = talloc_strdup(config, quarantine_prefix);
+ if (config->quarantine_prefix == NULL) {
+ DBG_ERR("virusfilter-vfs: out of memory!\n");
+ return -1;
+ }
}
quarantine_suffix = lp_parm_const_string(
snum, "virusfilter", "quarantine suffix",
VIRUSFILTER_DEFAULT_QUARANTINE_SUFFIX);
- config->quarantine_suffix = talloc_strdup(config, quarantine_suffix);
- if (config->quarantine_suffix == NULL) {
- DBG_ERR("virusfilter-vfs: out of memory!\n");
- return -1;
+ if (quarantine_suffix != NULL) {
+ config->quarantine_suffix = talloc_strdup(config, quarantine_suffix);
+ if (config->quarantine_suffix == NULL) {
+ DBG_ERR("virusfilter-vfs: out of memory!\n");
+ return -1;
+ }
}
/*
* Make sure prefixes and suffixes do not contain directory
* delimiters
*/
- sret = strstr(config->quarantine_prefix, "/");
- if (sret != NULL) {
- DBG_ERR("quarantine prefix must not contain directory "
- "delimiter(s) such as '/' (%s replaced with %s)\n",
- config->quarantine_prefix,
- VIRUSFILTER_DEFAULT_QUARANTINE_PREFIX);
- config->quarantine_prefix =
- VIRUSFILTER_DEFAULT_QUARANTINE_PREFIX;
- }
- sret = strstr(config->quarantine_suffix, "/");
- if (sret != NULL) {
- DBG_ERR("quarantine suffix must not contain directory "
- "delimiter(s) such as '/' (%s replaced with %s)\n",
- config->quarantine_suffix,
- VIRUSFILTER_DEFAULT_QUARANTINE_SUFFIX);
- config->quarantine_suffix =
- VIRUSFILTER_DEFAULT_QUARANTINE_SUFFIX;
+ if (config->quarantine_prefix != NULL) {
+ sret = strstr(config->quarantine_prefix, "/");
+ if (sret != NULL) {
+ DBG_ERR("quarantine prefix must not contain directory "
+ "delimiter(s) such as '/' (%s replaced with %s)\n",
+ config->quarantine_prefix,
+ VIRUSFILTER_DEFAULT_QUARANTINE_PREFIX);
+ config->quarantine_prefix =
+ VIRUSFILTER_DEFAULT_QUARANTINE_PREFIX;
+ }
+ }
+ if (config->quarantine_suffix != NULL) {
+ sret = strstr(config->quarantine_suffix, "/");
+ if (sret != NULL) {
+ DBG_ERR("quarantine suffix must not contain directory "
+ "delimiter(s) such as '/' (%s replaced with %s)\n",
+ config->quarantine_suffix,
+ VIRUSFILTER_DEFAULT_QUARANTINE_SUFFIX);
+ config->quarantine_suffix =
+ VIRUSFILTER_DEFAULT_QUARANTINE_SUFFIX;
+ }
}
config->quarantine_keep_tree = lp_parm_bool(
@@ -358,42 +371,50 @@ static int virusfilter_vfs_connect(
rename_prefix = lp_parm_const_string(
snum, "virusfilter", "rename prefix",
VIRUSFILTER_DEFAULT_RENAME_PREFIX);
- config->rename_prefix = talloc_strdup(config, rename_prefix);
- if (config->rename_prefix == NULL) {
- DBG_ERR("virusfilter-vfs: out of memory!\n");
- return -1;
+ if (rename_prefix != NULL) {
+ config->rename_prefix = talloc_strdup(config, rename_prefix);
+ if (config->rename_prefix == NULL) {
+ DBG_ERR("virusfilter-vfs: out of memory!\n");
+ return -1;
+ }
}
rename_suffix = lp_parm_const_string(
snum, "virusfilter", "rename suffix",
VIRUSFILTER_DEFAULT_RENAME_SUFFIX);
- config->rename_suffix = talloc_strdup(config, rename_suffix);
- if (config->rename_suffix == NULL) {
- DBG_ERR("virusfilter-vfs: out of memory!\n");
- return -1;
+ if (rename_suffix != NULL) {
+ config->rename_suffix = talloc_strdup(config, rename_suffix);
+ if (config->rename_suffix == NULL) {
+ DBG_ERR("virusfilter-vfs: out of memory!\n");
+ return -1;
+ }
}
/*
* Make sure prefixes and suffixes do not contain directory
* delimiters
*/
- sret = strstr(config->rename_prefix, "/");
- if (sret != NULL) {
- DBG_ERR("rename prefix must not contain directory "
- "delimiter(s) such as '/' (%s replaced with %s)\n",
- config->rename_prefix,
- VIRUSFILTER_DEFAULT_RENAME_PREFIX);
- config->rename_prefix =
- VIRUSFILTER_DEFAULT_RENAME_PREFIX;
- }
- sret = strstr(config->rename_suffix, "/");
- if (sret != NULL) {
- DBG_ERR("rename suffix must not contain directory "
- "delimiter(s) such as '/' (%s replaced with %s)\n",
- config->rename_suffix,
- VIRUSFILTER_DEFAULT_RENAME_SUFFIX);
- config->rename_suffix =
- VIRUSFILTER_DEFAULT_RENAME_SUFFIX;
+ if (config->rename_prefix != NULL) {
+ sret = strstr(config->rename_prefix, "/");
+ if (sret != NULL) {
+ DBG_ERR("rename prefix must not contain directory "
+ "delimiter(s) such as '/' (%s replaced with %s)\n",
+ config->rename_prefix,
+ VIRUSFILTER_DEFAULT_RENAME_PREFIX);
+ config->rename_prefix =
+ VIRUSFILTER_DEFAULT_RENAME_PREFIX;
+ }
+ }
+ if (config->rename_suffix != NULL) {
+ sret = strstr(config->rename_suffix, "/");
+ if (sret != NULL) {
+ DBG_ERR("rename suffix must not contain directory "
+ "delimiter(s) such as '/' (%s replaced with %s)\n",
+ config->rename_suffix,
+ VIRUSFILTER_DEFAULT_RENAME_SUFFIX);
+ config->rename_suffix =
+ VIRUSFILTER_DEFAULT_RENAME_SUFFIX;
+ }
}
config->infected_open_errno = lp_parm_int(
@@ -410,10 +431,12 @@ static int virusfilter_vfs_connect(
socket_path = lp_parm_const_string(
snum, "virusfilter", "socket path", NULL);
- config->socket_path = talloc_strdup(config, socket_path);
- if (config->socket_path == NULL) {
- DBG_ERR("virusfilter-vfs: out of memory!\n");
- return -1;
+ if (socket_path != NULL) {
+ config->socket_path = talloc_strdup(config, socket_path);
+ if (config->socket_path == NULL) {
+ DBG_ERR("virusfilter-vfs: out of memory!\n");
+ return -1;
+ }
}
/* canonicalize socket_path */
diff --git a/source3/script/tests/test_force_user_unlink.sh b/source3/script/tests/test_force_user_unlink.sh
new file mode 100755
index 00000000000..86076535497
--- /dev/null
+++ b/source3/script/tests/test_force_user_unlink.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+#
+# Test unlink on share with "force user"
+#
+# Copyright (C) 2021 Ralph Boehme
+
+incdir=$(dirname $0)/../../../testprogs/blackbox
+. $incdir/subunit.sh
+. $incdir/common_test_fns.inc
+
+smbclient="$BINDIR/smbclient"
+error_inject_conf=$(dirname ${SMB_CONF_PATH})/error_inject.conf
+failed=0
+
+test_forced_user_can_delete() {
+ out=$($smbclient -U $DOMAIN/$USERNAME%$PASSWORD //$SERVER_IP/force_user_error_inject -c "rm dir/file")
+ if [ $? -ne 0 ] ; then
+ echo $out
+ return 1
+ fi
+ tmp=$(echo $out | grep NT_STATUS_ )
+ if [ $? -eq 0 ] ; then
+ return 1
+ fi
+ return 0
+}
+
+echo "error_inject:unlinkat = EACCES" > ${error_inject_conf}
+
+$smbclient -U $DOMAIN/$USERNAME%$PASSWORD //$SERVER_IP/force_user_error_inject -c "mkdir dir" || failed=`expr $failed + 1`
+$smbclient -U $DOMAIN/$USERNAME%$PASSWORD //$SERVER_IP/force_user_error_inject -c "put WHATSNEW.txt dir/file" || failed=`expr $failed + 1`
+
+testit "test_forced_user_can_delete" test_forced_user_can_delete || failed=`expr $failed + 1`
+
+rm ${error_inject_conf}
+
+# Clean up after ourselves.
+$smbclient -U $DOMAIN/$USERNAME%$PASSWORD //$SERVER_IP/force_user_error_inject -c "del dir/file; rmdir dir"
+
+testok $0 $failed
diff --git a/source3/script/tests/test_net_rpc_share_allowedusers.sh b/source3/script/tests/test_net_rpc_share_allowedusers.sh
index 5dd382d4c51..d22c7580681 100755
--- a/source3/script/tests/test_net_rpc_share_allowedusers.sh
+++ b/source3/script/tests/test_net_rpc_share_allowedusers.sh
@@ -26,5 +26,25 @@ testit_grep "net_rpc_share_allowedusers" '^print\$$' $net usersidlist | $VALGRIN
testit_grep "net_rpc_share_allowedusers" '^print\$$' $net usersidlist | $VALGRIND $net rpc share allowedusers -S$SERVER -U$USERNAME%$PASSWORD $ADDARGS - 'print$' || failed=`expr $failed + 1`
# Check user "user1" is allowed to read share "tmp".
testit_grep "net_rpc_share_allowedusers" '^ user1$' $net usersidlist | $VALGRIND $net rpc share allowedusers -S$SERVER -U$USERNAME%$PASSWORD $ADDARGS || failed=`expr $failed + 1`
+#
+# Subtle extra test for bug https://bugzilla.samba.org/show_bug.cgi?id=13992
+#
+# '^ user1$' must appear MORE THAN ONCE, as it can read more than one
+# share. The previous test found user1, but only once as the bug only
+# allows reading the security descriptor for one share, and we were
+# unlucky that the first share security descriptor returned allows
+# user1 to read from it.
+#
+subunit_start_test "net_rpc_share_allowedusers"
+multi_userout=`$net usersidlist | $VALGRIND $net rpc share allowedusers -S$SERVER -U$USERNAME%$PASSWORD $ADDARGS`
+num_matches=`echo "$multi_userout" | grep -c '^ user1$'`
+if [ "$num_matches" -gt "1" ]
+then
+ subunit_pass_test "net_rpc_share_allowedusers"
+else
+ echo "net_rpc_share_allowedusers only found $num_matches shares readable by user1. Should be greater than one.\n"
+ failed=`expr $failed + 1`
+ echo "$multi_userout" | subunit_fail_test "net_rpc_share_allowedusers"
+fi
testok $0 $failed
diff --git a/source3/script/tests/test_winbind_ignore_domains.sh b/source3/script/tests/test_winbind_ignore_domains.sh
new file mode 100755
index 00000000000..adce8abb09c
--- /dev/null
+++ b/source3/script/tests/test_winbind_ignore_domains.sh
@@ -0,0 +1,104 @@
+#!/bin/sh
+
+incdir=`dirname $0`/../../../testprogs/blackbox
+. $incdir/subunit.sh
+. $incdir/common_test_fns.inc
+
+failed=0
+
+smbclient="$BINDIR/smbclient"
+smbcontrol="$BINDIR/smbcontrol"
+ldbmodify="$BINDIR/ldbmodify"
+ldbsearch="$BINDIR/ldbsearch"
+wbinfo="$BINDIR/wbinfo"
+global_inject_conf=$(dirname $SMB_CONF_PATH)/global_inject.conf
+SERVER_FQDN=$(echo "$SERVER.$REALM" | awk '{print tolower($0)}')
+
+TRUST_BASE_DN=$($ldbsearch -H ldap://$TRUST_SERVER -b "" -s base defaultNamingContext | awk '/^defaultNamingContext/ {print $2}')
+if [ $? -ne 0 ] ; then
+ echo "Could not find trusted base DN" | subunit_fail_test "test_idmap_ad"
+ exit 1
+fi
+
+#
+# Add POSIX ids to trusted domain
+#
+add_posix_ids() {
+cat <<EOF | $ldbmodify -H ldap://$TRUST_SERVER \
+ -U "$TRUST_DOMAIN\Administrator%$TRUST_PASSWORD"
+dn: CN=Administrator,CN=Users,$TRUST_BASE_DN
+changetype: modify
+add: uidNumber
+uidNumber: 2500000
+EOF
+
+cat <<EOF | $ldbmodify -H ldap://$TRUST_SERVER \
+ -U "$TRUST_DOMAIN\Administrator%$TRUST_PASSWORD"
+dn: CN=Domain Users,CN=Users,$TRUST_BASE_DN
+changetype: modify
+add: gidNumber
+gidNumber: 2500001
+EOF
+
+cat <<EOF | $ldbmodify -H ldap://$TRUST_SERVER \
+ -U "$TRUST_DOMAIN\Administrator%$TRUST_PASSWORD"
+dn: CN=Domain Admins,CN=Users,$TRUST_BASE_DN
+changetype: modify
+add: gidNumber
+gidNumber: 2500002
+EOF
+}
+
+#
+# Remove POSIX ids from trusted domain
+#
+remove_posix_ids() {
+cat <<EOF | $ldbmodify -H ldap://$TRUST_SERVER \
+ -U "$TRUST_DOMAIN\Administrator%$TRUST_PASSWORD"
+dn: CN=Administrator,CN=Users,$TRUST_BASE_DN
+changetype: modify
+delete: uidNumber
+uidNumber: 2500000
+EOF
+
+cat <<EOF | $ldbmodify -H ldap://$TRUST_SERVER \
+ -U "$TRUST_DOMAIN\Administrator%$TRUST_PASSWORD"
+dn: CN=Domain Users,CN=Users,$TRUST_BASE_DN
+changetype: modify
+delete: gidNumber
+gidNumber: 2500001
+EOF
+
+cat <<EOF | $ldbmodify -H ldap://$TRUST_SERVER \
+ -U "$TRUST_DOMAIN\Administrator%$TRUST_PASSWORD"
+dn: CN=Domain Admins,CN=Users,$TRUST_BASE_DN
+changetype: modify
+delete: gidNumber
+gidNumber: 2500002
+EOF
+}
+
+add_posix_ids
+
+echo "" > $global_inject_conf
+$smbcontrol winbindd reload-config
+$wbinfo -p
+
+test_smbclient "test_winbind_ignore_domains_ok_ntlm_ip" "ls" "//$SERVER_IP/tmp" -U $TRUST_DOMAIN/$TRUST_USERNAME%$TRUST_PASSWORD || failed=`expr $failed + 1`
+test_smbclient "test_winbind_ignore_domains_ok_ntlm_fqdn" "ls" "//$SERVER_FQDN/tmp" -U $TRUST_DOMAIN/$TRUST_USERNAME%$TRUST_PASSWORD || failed=`expr $failed + 1`
+test_smbclient "test_winbind_ignore_domains_ok_krb5" "ls" "//$SERVER_FQDN/tmp" -U $TRUST_USERNAME@$TRUST_REALM%$TRUST_PASSWORD -k || failed=`expr $failed + 1`
+
+echo "winbind:ignore domains = $TRUST_DOMAIN" > $global_inject_conf
+$smbcontrol winbindd reload-config
+$wbinfo -p
+
+test_smbclient_expect_failure "test_winbind_ignore_domains_fail_ntlm_ip" "ls" "//$SERVER_IP/tmp" -U $TRUST_DOMAIN/$TRUST_USERNAME%$TRUST_PASSWORD || failed=`expr $failed + 1`
+test_smbclient_expect_failure "test_winbind_ignore_domains_fail_ntlm_fqdn" "ls" "//$SERVER_FQDN/tmp" -U $TRUST_DOMAIN/$TRUST_USERNAME%$TRUST_PASSWORD || failed=`expr $failed + 1`
+test_smbclient_expect_failure "test_winbind_ignore_domains_fail_krb5" "ls" "//$SERVER_FQDN/tmp" -U $TRUST_USERNAME@$TRUST_REALM%$TRUST_PASSWORD -k || failed=`expr $failed + 1`
+
+echo "" > $global_inject_conf
+$smbcontrol winbindd reload-config
+$wbinfo -p
+remove_posix_ids
+
+testok $0 $failed
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 27dc7587b17..47e914b1009 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -487,13 +487,13 @@ for env in ["fileserver"]:
[os.path.join(samba3srcdir, "script/tests/test_smbclient_tarmode.pl"),
'-n', '$SERVER', '-i', '$SERVER_IP', '-s', 'tarmode2',
'-u', '$USERNAME', '-p', '$PASSWORD', '-l', '$LOCAL_PATH/tarmode2',
- '-d', '$PREFIX', '-b', smbclient3,
+ '-d', 'smbclient_tar.NT1', '-b', smbclient3,
'--subunit', '--', configuration, '-mNT1'])
plantestsuite("samba3.blackbox.smbclient_tar.SMB3", env,
[os.path.join(samba3srcdir, "script/tests/test_smbclient_tarmode.pl"),
'-n', '$SERVER', '-i', '$SERVER_IP', '-s', 'tarmode2',
'-u', '$USERNAME', '-p', '$PASSWORD', '-l', '$LOCAL_PATH/tarmode2',
- '-d', '$PREFIX', '-b', smbclient3,
+ '-d', 'smbclient_tar.SMB3', '-b', smbclient3,
'--subunit', '--', configuration, '-mSMB3'])
for env in ["fileserver:local"]:
@@ -991,6 +991,9 @@ plantestsuite("samba3.blackbox.smbd_no_krb5", "ad_member:local",
[os.path.join(samba3srcdir, "script/tests/test_smbd_no_krb5.sh"),
smbclient3, '$SERVER', "$DC_USERNAME", "$DC_PASSWORD", "$PREFIX"])
+plantestsuite("samba3.blackbox.winbind_ignore_domain", "ad_member_idmap_ad:local",
+ [os.path.join(samba3srcdir, "script/tests/test_winbind_ignore_domains.sh")])
+
plantestsuite("samba3.blackbox.durable_v2_delay", "simpleserver:local",
[os.path.join(samba3srcdir, "script/tests/test_durable_handle_reconnect.sh")])
@@ -1122,6 +1125,11 @@ plantestsuite(
"",
"-b $PREFIX/clusteredmember_smb1/unclists/tmp.txt -N 5 -o 10"])
+plantestsuite("samba3.blackbox.force-user-unlink",
+ "maptoguest:local",
+ [os.path.join(samba3srcdir,
+ "script/tests/test_force_user_unlink.sh")])
+
def planclusteredmembertestsuite(tname, prefix):
'''Define a clustered test for the clusteredmember environment'''
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index 9974877edc2..43762555b35 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -341,21 +341,13 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
if (fsp->fsp_flags.initial_delete_on_close &&
!is_delete_on_close_set(lck, fsp->name_hash)) {
- struct auth_session_info *session_info = NULL;
-
/* Initial delete on close was set and no one else
* wrote a real delete on close. */
- status = smbXsrv_session_info_lookup(conn->sconn->client,
- fsp->vuid,
- &session_info);
- if (!NT_STATUS_IS_OK(status)) {
- return NT_STATUS_INTERNAL_ERROR;
- }
fsp->fsp_flags.delete_on_close = true;
set_delete_on_close_lck(fsp, lck,
- session_info->security_token,
- session_info->unix_token);
+ fsp->conn->session_info->security_token,
+ fsp->conn->session_info->unix_token);
}
delete_file = is_delete_on_close_set(lck, fsp->name_hash) &&
@@ -1176,24 +1168,15 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
}
if (fsp->fsp_flags.initial_delete_on_close) {
- struct auth_session_info *session_info = NULL;
-
/* Initial delete on close was set - for
* directories we don't care if anyone else
* wrote a real delete on close. */
- status = smbXsrv_session_info_lookup(fsp->conn->sconn->client,
- fsp->vuid,
- &session_info);
- if (!NT_STATUS_IS_OK(status)) {
- return NT_STATUS_INTERNAL_ERROR;
- }
-
send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
fsp->fsp_name->base_name);
set_delete_on_close_lck(fsp, lck,
- session_info->security_token,
- session_info->unix_token);
+ fsp->conn->session_info->security_token,
+ fsp->conn->session_info->unix_token);
fsp->fsp_flags.delete_on_close = true;
}
diff --git a/source3/smbd/conn_idle.c b/source3/smbd/conn_idle.c
index ca697383877..56a6ef896fb 100644
--- a/source3/smbd/conn_idle.c
+++ b/source3/smbd/conn_idle.c
@@ -273,5 +273,13 @@ static void conn_force_tdis_done(struct tevent_req *req)
* uid in the meantime. Ensure we're still root.
*/
change_to_root_user();
- reload_services(sconn, conn_snum_used, true);
+ /*
+ * Use 'false' in the last parameter (test) to force
+ * a full reload of services. Prevents
+ * reload_services caching the fact it's
+ * been called multiple times in a row.
+ * See BUG: https://bugzilla.samba.org/show_bug.cgi?id=14604
+ * for details.
+ */
+ reload_services(sconn, conn_snum_used, false);
}
diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c
index dd4a70ca256..2081a75d52c 100644
--- a/source3/smbd/pysmbd.c
+++ b/source3/smbd/pysmbd.c
@@ -1144,9 +1144,12 @@ static PyObject *py_smbd_create_file(PyObject *self, PyObject *args, PyObject *k
if (!NT_STATUS_IS_OK(status)) {
DBG_ERR("init_files_struct failed: %s\n",
nt_errstr(status));
+ } else if (fsp != NULL) {
+ SMB_VFS_CLOSE(fsp);
}
TALLOC_FREE(frame);
+ PyErr_NTSTATUS_NOT_OK_RAISE(status);
Py_RETURN_NONE;
}
diff --git a/source3/torture/test_smb2.c b/source3/torture/test_smb2.c
index d5023d88cfd..3e25a562bd6 100644
--- a/source3/torture/test_smb2.c
+++ b/source3/torture/test_smb2.c
@@ -188,11 +188,11 @@ bool run_smb2_basic(int dummy)
cli->timeout,
cli->smb2.session,
cli->smb2.tcon);
+ cli_state_restore_tcon(cli, saved_tcon);
if (!NT_STATUS_IS_OK(status)) {
printf("smb2cli_tdis returned %s\n", nt_errstr(status));
return false;
}
- cli_state_restore_tcon(cli, saved_tcon);
status = smb2cli_tdis(cli->conn,
cli->timeout,
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 2a3133373e9..5e263797730 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -1343,6 +1343,7 @@ static bool run_tcon_test(int dummy)
if (!NT_STATUS_IS_OK(status)) {
printf("%s refused 2nd tree connect (%s)\n", host,
nt_errstr(status));
+ cli_state_restore_tcon(cli, orig_tcon);
cli_shutdown(cli);
return False;
}
@@ -1395,6 +1396,8 @@ static bool run_tcon_test(int dummy)
status = cli_close(cli, fnum1);
if (!NT_STATUS_IS_OK(status)) {
printf("close failed (%s)\n", nt_errstr(status));
+ cli_state_restore_tcon(cli, orig_tcon);
+ cli_shutdown(cli);
return False;
}
@@ -1403,6 +1406,8 @@ static bool run_tcon_test(int dummy)
status = cli_tdis(cli);
if (!NT_STATUS_IS_OK(status)) {
printf("secondary tdis failed (%s)\n", nt_errstr(status));
+ cli_state_restore_tcon(cli, orig_tcon);
+ cli_shutdown(cli);
return False;
}
@@ -11714,7 +11719,7 @@ static bool run_uid_regression_test(int dummy)
int16_t old_vuid;
int32_t old_cnum;
bool correct = True;
- struct smbXcli_tcon *orig_tcon = NULL;
+ struct smbXcli_tcon *tcon_copy = NULL;
NTSTATUS status;
printf("starting uid regression test\n");
@@ -11755,8 +11760,20 @@ static bool run_uid_regression_test(int dummy)
}
old_cnum = cli_state_get_tid(cli);
- orig_tcon = cli_state_save_tcon(cli);
- if (orig_tcon == NULL) {
+ /*
+ * This is an SMB1-only test.
+ * Copy the tcon, not "save/restore".
+ *
+ * In SMB1 the cli_tdis() below frees
+ * cli->smb1.tcon so we need a copy
+ * of the struct to put back for the
+ * second tdis call with invalid vuid.
+ *
+ * This is a test-only hack. Real client code
+ * uses cli_state_save_tcon()/cli_state_restore_tcon().
+ */
+ tcon_copy = smbXcli_tcon_copy(cli, cli->smb1.tcon);
+ if (tcon_copy == NULL) {
correct = false;
goto out;
}
@@ -11772,11 +11789,11 @@ static bool run_uid_regression_test(int dummy)
} else {
d_printf("First tdis failed (%s)\n", nt_errstr(status));
correct = false;
- cli_state_restore_tcon(cli, orig_tcon);
+ cli->smb1.tcon = tcon_copy;
goto out;
}
- cli_state_restore_tcon(cli, orig_tcon);
+ cli->smb1.tcon = tcon_copy;
cli_state_set_uid(cli, old_vuid);
cli_state_set_tid(cli, old_cnum);
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index 1e08237905a..bc5aec92385 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -102,7 +102,7 @@ struct imessaging_context *winbind_imessaging_context(void)
/* Reload configuration */
-static bool reload_services_file(const char *lfile)
+bool winbindd_reload_services_file(const char *lfile)
{
const struct loadparm_substitution *lp_sub =
loadparm_s3_global_substitution();
@@ -117,15 +117,15 @@ static bool reload_services_file(const char *lfile)
TALLOC_FREE(fname);
}
+ reopen_logs();
+ ret = lp_load_global(get_dyn_CONFIGFILE());
+
/* if this is a child, restore the logfile to the special
name - <domain>, idmap, etc. */
if (lfile && *lfile) {
lp_set_logfile(lfile);
}
- reopen_logs();
- ret = lp_load_global(get_dyn_CONFIGFILE());
-
reopen_logs();
load_interfaces();
winbindd_setup_max_fds();
@@ -156,7 +156,7 @@ static void winbindd_status(void)
/* Flush client cache */
-static void flush_caches(void)
+void winbindd_flush_caches(void)
{
/* We need to invalidate cached user list entries on a SIGHUP
otherwise cached access denied errors due to restrict anonymous
@@ -363,7 +363,7 @@ static void winbindd_sig_hup_handler(struct tevent_context *ev,
DEBUG(1,("Reloading services after SIGHUP\n"));
flush_caches_noinit();
- reload_services_file(file);
+ winbindd_reload_services_file(file);
}
bool winbindd_setup_sig_hup_handler(const char *lfile)
@@ -447,18 +447,6 @@ static bool winbindd_setup_sig_usr2_handler(void)
return true;
}
-/* React on 'smbcontrol winbindd reload-config' in the same way as on SIGHUP*/
-static void msg_reload_services(struct messaging_context *msg,
- void *private_data,
- uint32_t msg_type,
- struct server_id server_id,
- DATA_BLOB *data)
-{
- /* Flush various caches */
- flush_caches();
- reload_services_file((const char *) private_data);
-}
-
/* React on 'smbcontrol winbindd shutdown' in the same way as on SIGTERM*/
static void msg_shutdown(struct messaging_context *msg,
void *private_data,
@@ -1420,7 +1408,8 @@ static void winbindd_register_handlers(struct messaging_context *msg_ctx,
/* React on 'smbcontrol winbindd reload-config' in the same way
as to SIGHUP signal */
messaging_register(msg_ctx, NULL,
- MSG_SMB_CONF_UPDATED, msg_reload_services);
+ MSG_SMB_CONF_UPDATED,
+ winbindd_msg_reload_services_parent);
messaging_register(msg_ctx, NULL,
MSG_SHUTDOWN, msg_shutdown);
@@ -1811,7 +1800,7 @@ int main(int argc, const char **argv)
exit(1);
}
- if (!reload_services_file(NULL)) {
+ if (!winbindd_reload_services_file(NULL)) {
DEBUG(0, ("error opening config file\n"));
exit(1);
}
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
index 47efe988d65..b1c86b2979c 100644
--- a/source3/winbindd/winbindd_dual.c
+++ b/source3/winbindd/winbindd_dual.c
@@ -927,6 +927,39 @@ void winbind_disconnect_dc_parent(struct messaging_context *msg_ctx,
forall_children(winbind_msg_relay_fn, &state);
}
+static void winbindd_msg_reload_services_child(struct messaging_context *msg,
+ void *private_data,
+ uint32_t msg_type,
+ struct server_id server_id,
+ DATA_BLOB *data)
+{
+ DBG_DEBUG("Got reload-config message\n");
+ winbindd_reload_services_file((const char *)private_data);
+}
+
+/* React on 'smbcontrol winbindd reload-config' in the same way as on SIGHUP*/
+void winbindd_msg_reload_services_parent(struct messaging_context *msg,
+ void *private_data,
+ uint32_t msg_type,
+ struct server_id server_id,
+ DATA_BLOB *data)
+{
+ struct winbind_msg_relay_state state = {
+ .msg_ctx = msg,
+ .msg_type = msg_type,
+ .data = data,
+ };
+
+ DBG_DEBUG("Got reload-config message\n");
+
+ /* Flush various caches */
+ winbindd_flush_caches();
+
+ winbindd_reload_services_file((const char *)private_data);
+
+ forall_children(winbind_msg_relay_fn, &state);
+}
+
/* Set our domains as offline and forward the offline message to our children. */
struct winbind_msg_on_offline_state {
@@ -1760,6 +1793,10 @@ static bool fork_domain_child(struct winbindd_child *child)
messaging_register(global_messaging_context(), NULL,
MSG_WINBIND_DISCONNECT_DC,
winbind_msg_disconnect_dc);
+ messaging_register(global_messaging_context(),
+ override_logfile ? NULL : child->logfilename,
+ MSG_SMB_CONF_UPDATED,
+ winbindd_msg_reload_services_child);
primary_domain = find_our_domain();
diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index b5850a33b0f..c49033b375d 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -2403,6 +2403,15 @@ process_result:
goto done;
}
+ if (!is_allowed_domain(info3->base.logon_domain.string)) {
+ DBG_NOTICE("Authentication failed for user [%s] "
+ "from firewalled domain [%s]\n",
+ info3->base.account_name.string,
+ info3->base.logon_domain.string);
+ result = NT_STATUS_AUTHENTICATION_FIREWALL_FAILED;
+ goto done;
+ }
+
result = append_auth_data(state->mem_ctx, state->response,
state->request->flags,
validation_level,
@@ -2756,6 +2765,16 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
goto done;
}
+ if (!is_allowed_domain(info3->base.logon_domain.string)) {
+ DBG_NOTICE("Authentication failed for user [%s] "
+ "from firewalled domain [%s]\n",
+ info3->base.account_name.string,
+ info3->base.logon_domain.string);
+ state->response->data.auth.authoritative = true;
+ result = NT_STATUS_AUTHENTICATION_FIREWALL_FAILED;
+ goto done;
+ }
+
result = append_auth_data(state->mem_ctx, state->response,
state->request->flags,
validation_level,
@@ -2824,6 +2843,14 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact
goto done;
}
+ if (!is_allowed_domain(domain)) {
+ DBG_NOTICE("Authentication failed for user [%s] "
+ "from firewalled domain [%s]\n",
+ user, domain);
+ result = NT_STATUS_AUTHENTICATION_FIREWALL_FAILED;
+ goto done;
+ }
+
/* Change password */
oldpass = state->request->data.chauthtok.oldpass;
@@ -3085,6 +3112,15 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai
fstrcpy(domain,lp_workgroup());
}
+ if (!is_allowed_domain(domain)) {
+ DBG_NOTICE("Authentication failed for user [%s] "
+ "from firewalled domain [%s]\n",
+ state->request->data.chng_pswd_auth_crap.user,
+ domain);
+ result = NT_STATUS_AUTHENTICATION_FIREWALL_FAILED;
+ goto done;
+ }
+
if(!*user) {
fstrcpy(user, state->request->data.chng_pswd_auth_crap.user);
}
@@ -3287,6 +3323,14 @@ NTSTATUS winbindd_pam_auth_pac_verify(struct winbindd_cli_state *state,
return result;
}
+ if (!is_allowed_domain(info6->base.logon_domain.string)) {
+ DBG_NOTICE("Authentication failed for user [%s] "
+ "from firewalled domain [%s]\n",
+ info6->base.account_name.string,
+ info6->base.logon_domain.string);
+ return NT_STATUS_AUTHENTICATION_FIREWALL_FAILED;
+ }
+
result = map_info6_to_validation(state->mem_ctx,
info6,
&validation_level,
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index 2a829b0171a..6d4ffa726f1 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -31,6 +31,8 @@ bool winbindd_setup_sig_hup_handler(const char *lfile);
bool winbindd_use_idmap_cache(void);
bool winbindd_use_cache(void);
char *get_winbind_priv_pipe_dir(void);
+void winbindd_flush_caches(void);
+bool winbindd_reload_services_file(const char *lfile);
/* The following definitions come from winbindd/winbindd_ads.c */
@@ -341,6 +343,11 @@ void winbind_msg_ip_dropped_parent(struct messaging_context *msg_ctx,
uint32_t msg_type,
struct server_id server_id,
DATA_BLOB *data);
+void winbindd_msg_reload_services_parent(struct messaging_context *msg,
+ void *private_data,
+ uint32_t msg_type,
+ struct server_id server_id,
+ DATA_BLOB *data);
NTSTATUS winbindd_reinit_after_fork(const struct winbindd_child *myself,
const char *logfilename);
struct winbindd_domain *wb_child_domain(void);
diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
index c2f02b74211..bec706f87de 100644
--- a/source3/winbindd/winbindd_util.c
+++ b/source3/winbindd/winbindd_util.c
@@ -123,8 +123,6 @@ static NTSTATUS add_trusted_domain(const char *domain_name,
struct winbindd_domain **_d)
{
struct winbindd_domain *domain = NULL;
- const char **ignored_domains = NULL;
- const char **dom = NULL;
int role = lp_server_role();
struct dom_sid_buf buf;
@@ -133,12 +131,8 @@ static NTSTATUS add_trusted_domain(const char *domain_name,
return NT_STATUS_INVALID_PARAMETER;
}
- ignored_domains = lp_parm_string_list(-1, "winbind", "ignore domains", NULL);
- for (dom=ignored_domains; dom && *dom; dom++) {
- if (gen_fnmatch(*dom, domain_name) == 0) {
- DEBUG(2,("Ignoring domain '%s'\n", domain_name));
- return NT_STATUS_NO_SUCH_DOMAIN;
- }
+ if (!is_allowed_domain(domain_name)) {
+ return NT_STATUS_NO_SUCH_DOMAIN;
}
/*
diff --git a/source3/wscript b/source3/wscript
index 9920432a360..563854c1d23 100644
--- a/source3/wscript
+++ b/source3/wscript
@@ -1244,7 +1244,7 @@ err:
int main(void)
{
- uint64_t *hint, get_hint;
+ uint64_t hint, get_hint;
int fd;
fd = open(DATA, O_RDONLY | O_CREAT | O_EXCL);
@@ -1252,8 +1252,8 @@ int main(void)
goto err;
}
- *hint = RWH_WRITE_LIFE_SHORT;
- int ret = fcntl(fd, F_SET_RW_HINT, hint);
+ hint = RWH_WRITE_LIFE_SHORT;
+ int ret = fcntl(fd, F_SET_RW_HINT, &hint);
if (ret == -1) {
goto err;
}
@@ -1267,8 +1267,8 @@ int main(void)
goto err;
}
- *hint = RWH_WRITE_LIFE_EXTREME;
- ret = fcntl(fd, F_SET_FILE_RW_HINT, hint);
+ hint = RWH_WRITE_LIFE_EXTREME;
+ ret = fcntl(fd, F_SET_FILE_RW_HINT, &hint);
if (ret == -1) {
goto err;
}
diff --git a/source4/heimdal/lib/krb5/store.c b/source4/heimdal/lib/krb5/store.c
index 17de78e9e74..31afb23c983 100644
--- a/source4/heimdal/lib/krb5/store.c
+++ b/source4/heimdal/lib/krb5/store.c
@@ -270,6 +270,8 @@ krb5_storage_get_eof_code(krb5_storage *sp)
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_storage_free(krb5_storage *sp)
{
+ if (sp == NULL)
+ return 0;
if(sp->free)
(*sp->free)(sp);
free(sp->data);
diff --git a/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output-lost-deleted-user3.txt b/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output-lost-deleted-user3.txt
index d014bfacae2..ea9b630df08 100644
--- a/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output-lost-deleted-user3.txt
+++ b/source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output-lost-deleted-user3.txt
@@ -1,19 +1,19 @@
Checking 232 objects
-SKIPING: object CN=fred\0ADEL:2301a64c-1122-5566-851e-12d4a711cfb4,OU=removed,DC=release-4-5-0-pre1,DC=samba,DC=corp is an expired tombstone
+SKIPPING: object CN=fred\0ADEL:2301a64c-1122-5566-851e-12d4a711cfb4,OU=removed,DC=release-4-5-0-pre1,DC=samba,DC=corp is an expired tombstone
isDeleted: attid=0x00020030 version=1 invocation=4e4496a3-7fb8-4f97-8a33-d238db8b5e2d usn=3746 (local=3746) at Wed Jun 29 04:36:39 2016
-SKIPING: object CN=fred\0ADEL:2301a64c-5b42-4ca8-851e-12d4a711cfb4,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp is an expired tombstone
+SKIPPING: object CN=fred\0ADEL:2301a64c-5b42-4ca8-851e-12d4a711cfb4,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp is an expired tombstone
isDeleted: attid=0x00020030 version=1 invocation=4e4496a3-7fb8-4f97-8a33-d238db8b5e2d usn=3746 (local=3746) at Wed Jun 29 04:36:39 2016
-SKIPING: object CN=dsg\0ADEL:6d66d0ef-cad7-4e5d-b1b6-4a233a21c269,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp is an expired tombstone
+SKIPPING: object CN=dsg\0ADEL:6d66d0ef-cad7-4e5d-b1b6-4a233a21c269,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp is an expired tombstone
isDeleted: attid=0x00020030 version=1 invocation=4e4496a3-7fb8-4f97-8a33-d238db8b5e2d usn=3734 (local=3734) at Wed Jun 29 04:34:32 2016
-SKIPING: object CN=udg\0ADEL:7cff5537-51b1-4d26-a295-0225dbea8525,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp is an expired tombstone
+SKIPPING: object CN=udg\0ADEL:7cff5537-51b1-4d26-a295-0225dbea8525,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp is an expired tombstone
isDeleted: attid=0x00020030 version=1 invocation=4e4496a3-7fb8-4f97-8a33-d238db8b5e2d usn=3739 (local=3739) at Wed Jun 29 04:34:34 2016
-SKIPING: object CN=usg\0ADEL:d012e8f5-a4bd-40ea-a2a1-68ff2508847d,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp is an expired tombstone
+SKIPPING: object CN=usg\0ADEL:d012e8f5-a4bd-40ea-a2a1-68ff2508847d,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp is an expired tombstone
isDeleted: attid=0x00020030 version=1 invocation=4e4496a3-7fb8-4f97-8a33-d238db8b5e2d usn=3736 (local=3736) at Wed Jun 29 04:34:33 2016
-SKIPING: object CN=ddg\0ADEL:fb8c2fe3-5448-43de-99f9-e1d3b9357cfc,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp is an expired tombstone
+SKIPPING: object CN=ddg\0ADEL:fb8c2fe3-5448-43de-99f9-e1d3b9357cfc,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp is an expired tombstone
isDeleted: attid=0x00020030 version=1 invocation=4e4496a3-7fb8-4f97-8a33-d238db8b5e2d usn=3737 (local=3737) at Wed Jun 29 04:34:34 2016
-SKIPING: object CN=gsg\0ADEL:91aa85cc-fc19-4b8c-9fc7-aaba425439c7,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp is an expired tombstone
+SKIPPING: object CN=gsg\0ADEL:91aa85cc-fc19-4b8c-9fc7-aaba425439c7,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp is an expired tombstone
isDeleted: attid=0x00020030 version=1 invocation=4e4496a3-7fb8-4f97-8a33-d238db8b5e2d usn=3735 (local=3735) at Wed Jun 29 04:34:33 2016
-SKIPING: object CN=gdg\0ADEL:e0f581e7-14ee-4fc2-839c-8f46f581c72a,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp is an expired tombstone
+SKIPPING: object CN=gdg\0ADEL:e0f581e7-14ee-4fc2-839c-8f46f581c72a,CN=Deleted Objects,DC=release-4-5-0-pre1,DC=samba,DC=corp is an expired tombstone
isDeleted: attid=0x00020030 version=1 invocation=4e4496a3-7fb8-4f97-8a33-d238db8b5e2d usn=3738 (local=3738) at Wed Jun 29 04:34:34 2016
NOTICE: found 8 expired tombstones, 'samba' will remove them daily, 'samba-tool domain tombstones expunge' would do that immediately.
Checked 232 objects (0 errors)
diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
index 3a903a7eee0..258c9122edc 100755
--- a/source4/selftest/tests.py
+++ b/source4/selftest/tests.py
@@ -561,7 +561,8 @@ if have_gnutls_crypto_policies:
plantestsuite("samba3.wbinfo_simple.fips.%s" % t, "ad_member_fips:local", [os.path.join(srcdir(), "nsswitch/tests/test_wbinfo_simple.sh"), t])
plantestsuite("samba4.wbinfo_name_lookup.fips", "ad_member_fips", [os.path.join(srcdir(), "nsswitch/tests/test_wbinfo_name_lookup.sh"), '$DOMAIN', '$REALM', '$DC_USERNAME'])
-plantestsuite_loadlist("samba4.rpc.echo against NetBIOS alias", "ad_dc_ntvfs", [valgrindify(smbtorture4), "$LISTOPT", "$LOADLIST", 'ncacn_np:$NETBIOSALIAS', '-U$DOMAIN/$USERNAME%$PASSWORD', 'rpc.echo'])
+plansmbtorture4testsuite('rpc.echo', "ad_dc_ntvfs", ['ncacn_np:$NETBIOSALIAS', '-U$DOMAIN/$USERNAME%$PASSWORD'], "samba4.rpc.echo against NetBIOS alias")
+
# json tests hook into ``chgdcpass'' to make them run in contributor CI on
# gitlab
planpythontestsuite("chgdcpass", "samba.tests.blackbox.netads_json")
diff --git a/testprogs/blackbox/dbcheck-links.sh b/testprogs/blackbox/dbcheck-links.sh
index ead59d691e0..f00fe46c2de 100755
--- a/testprogs/blackbox/dbcheck-links.sh
+++ b/testprogs/blackbox/dbcheck-links.sh
@@ -42,7 +42,7 @@ dbcheck() {
if [ "$?" != "$2" ]; then
return 1
fi
- sort $tmpfile > $tmpfile.sorted
+ sort $tmpfile | grep -v "^INFO:" > $tmpfile.sorted
sort $release_dir/expected-dbcheck-link-output${1}.txt > $tmpfile.expected
diff -u $tmpfile.sorted $tmpfile.expected
if [ "$?" != "0" ]; then
diff --git a/testprogs/blackbox/dbcheck-oldrelease.sh b/testprogs/blackbox/dbcheck-oldrelease.sh
index 9e9924654be..64c08c57981 100755
--- a/testprogs/blackbox/dbcheck-oldrelease.sh
+++ b/testprogs/blackbox/dbcheck-oldrelease.sh
@@ -297,6 +297,17 @@ dbcheck_objectclass() {
fi
}
+# This should 'fail', because it returns the number of wrong records, which it must if we did not skip the deleted objects
+dbcheck_deleted_objects() {
+ if [ x$RELEASE = x"alpha13" ]; then
+ basedn=$($ldbsearch -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb -s base -b "" defaultNamingContext| grep -i defaultNamingContext| cut -d\ -f 2)
+
+ $PYTHON $BINDIR/samba-tool dbcheck -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb "cn=deleted objects,$basedn" --scope base $@
+ else
+ return 1
+ fi
+}
+
# This should 'fail', because it returns the number of modified records
dbcheck() {
$PYTHON $BINDIR/samba-tool dbcheck --selftest-check-expired-tombstones --cross-ncs --fix --yes -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $@
@@ -488,6 +499,7 @@ testit $RELEASE undump || failed=`expr $failed + 1`
testit "reindex" reindex || failed=`expr $failed + 1`
testit "current_version_mod" do_current_version_mod || failed=`expr $failed + 1`
testit "check_expected_before_values" check_expected_before_values || failed=`expr $failed + 1`
+testit_expect_failure "dbcheck_deleted_objects" dbcheck_deleted_objects || failed=`expr $failed + 1`
testit_expect_failure "dbcheck_objectclass" dbcheck_objectclass || failed=`expr $failed + 1`
testit_expect_failure "dbcheck" dbcheck || failed=`expr $failed + 1`
testit "check_expected_after_values" check_expected_after_values || failed=`expr $failed + 1`
--- End Message ---