The branch, v4-13-stable has been updated via 6df178003a3 VERSION: Disable GIT_SNAPSHOT for the 4.13.5 release. via 7eb253a4221 Revert "wscript: use --as-needed only if tested successfully" via 5d765d7358d WHATSNEW: Add release notes for Samba 4.13.5. via 6c5e6046345 g_lock: Fix uninitalized variable reads via efd3ee23123 locking: Fix an uninitialized variable read via a04f19ecdd3 s3:modules:vfs_virusfilter: Recent talloc changes cause infinite start-up failure via eebf510fbd8 wscript: use --as-needed only if tested successfully via 0eb58c2d68b s3: VFS: nfs4_acls. Add missing TALLOC_FREE(frame) in error path. via 4917b5e93d1 script/autobuild.py: let cleanup() ignore errors from rmdir_force() by default via 6d93064e188 script/autobuild.py: split out a rmdir_force() helper function via 35dc71bbc19 selftest: make/use a copy of GNUPGHOME via 70a46568228 s4:selftest: use plansmbtorture4testsuite() for 'rpc.echo' via 01a0a619adf s3:selftest: run test_smbclient_tarmode.pl with a fixed subdirectory name via 86c7854a1bb selftest/Samba4: allow get_cmd_env_vars() to take an overwrite dictionary via 8f95912a5d3 selftest/Samba4: correctly pass KRB5CCNAME to provision via 98051444a58 selftest/Samba4: make more use of get_cmd_env_vars() via 7a72dc8cd36 selftest:Samba4: avoid File::Path 'make_path' in setup_dns_hub_internal() via 57994ca68f2 selftest: allow a prefix under /m/username/ via aa9a1644f41 Makefile: add support for 'make testonly' via 9806b67ee4c s3: fix fcntl waf configure check via 331e4d8363f smbd: In conn_force_tdis_done() when forcing a connection closed force a full reload of services. via 55400f08000 dbcheck: Check Deleted Objects and reduce noise in reports about expired tombstones via 02b4ddcaed8 selftest: Confirm that we fix any errors on the Deleted Objects container itself via ac0e7f6a0cd classicupgrade: treat old never expires value right via 5957cf2e2ca s3:pysmbd: fix fd leak in py_smbd_create_file() via 780fbc30041 HEIMDAL: krb5_storage_free(NULL) should work via cf9066b2153 lib:util: Avoid free'ing our own pointer via a3fa41c7429 lib:util: Add cache oversize test for memcache via 32d62beae34 lib:util: Add basic memcache unit test via 4914efd0cc4 s3: libsmb: Add missing cli_tdis() in error path if encryption setup failed on temp proxy connection. via d78648963ed s3: libsmb: cli_state_save_tcon(). Don't deepcopy tcon struct when temporarily swapping out a connection on a cli_state. via 1b609f04661 s3: torture: Change the SMB1-only UID-REGRESSION-TEST to do an explicit copy of the tcon struct in use. via 643fcfd5566 s3: smbtorture3: Ensure run_tcon_test() always replaces any saved tcon and shuts down correctly even in error paths. via 2a6ba7ab9eb s3: smbtorture3: Ensure we *always* replace the saved saved_tcon even in an error condition. via 47581202cf3 s3: tests: Add regression test for bug 13992. via f6e5fe6f122 smbd: use fsp->conn->session_info for the initial delete-on-close token via ba12f0c3ae0 selftest: add a test that verifies unlink works when "force user" is set via 35eddb388f2 selftest: add force_user_error_inject share in maptoguest env via 483c1dc818e vfs_error_inject: add unlinkat hook via 2c0987d6564 s3/auth: implement "winbind:ignore domains" via b236cbcf9d2 winbind: check for allowed domains in winbindd_pam_auth_pac_verify() via f0225b0adcb winbind: check for allowed domains in winbindd_dual_pam_chauthtok() via 888e1d67229 winbind: check for allowed domains in winbindd_dual_pam_chng_pswd_auth_crap() via 7878dec1da0 winbind: check for allowed domains in winbindd_dual_pam_auth_crap() via c983012811e winbind: check for allowed domains in winbindd_dual_pam_auth() via 86a96954c1f winbind: move "winbind:ignore domain" logic to a seperate function via 2e2e854f04e selftest: add a test for "winbind:ignore domains" via 27dc8f4e90b winbind: handle MSG_SMB_CONF_UPDATED in the winbinds children via 3b5fa17d9bd winbind: set logfile after reloading config via 19f39e67942 winbind: move config-reloading code to winbindd_dual.c via 7003d050b0c selftest: use correct DNS domain name for wrapper hosts file via 670eddc646a VERSION: Bump version up to 4.13.5... from 19965edb713 VERSION: Disable GIT_SNAPSHOT for the 4.13.4 release.
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-13-stable - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: Makefile | 3 + VERSION | 2 +- WHATSNEW.txt | 79 ++++++++- lib/util/memcache.c | 19 ++- lib/util/tests/test_memcache.c | 161 ++++++++++++++++++ lib/util/wscript_build | 8 +- python/samba/dbchecker.py | 25 ++- python/samba/upgrade.py | 2 +- script/autobuild.py | 38 ++++- selftest/selftest.pl | 7 +- selftest/target/Samba.pm | 26 +++ selftest/target/Samba3.pm | 25 ++- selftest/target/Samba4.pm | 183 +++++++++------------ selftest/tests.py | 2 + source3/auth/auth_util.c | 8 + source3/include/proto.h | 1 + source3/lib/g_lock.c | 4 +- source3/lib/util_names.c | 20 +++ source3/libsmb/clidfs.c | 1 + source3/libsmb/clientgen.c | 30 +++- source3/locking/share_mode_lock.c | 2 +- source3/modules/nfs4_acls.c | 1 + source3/modules/vfs_error_inject.c | 37 +++++ source3/modules/vfs_virusfilter.c | 157 ++++++++++-------- source3/script/tests/test_force_user_unlink.sh | 40 +++++ .../tests/test_net_rpc_share_allowedusers.sh | 20 +++ .../script/tests/test_winbind_ignore_domains.sh | 104 ++++++++++++ source3/selftest/tests.py | 12 +- source3/smbd/close.c | 25 +-- source3/smbd/conn_idle.c | 10 +- source3/smbd/pysmbd.c | 3 + source3/torture/test_smb2.c | 2 +- source3/torture/torture.c | 27 ++- source3/winbindd/winbindd.c | 29 +--- source3/winbindd/winbindd_dual.c | 37 +++++ source3/winbindd/winbindd_pam.c | 44 +++++ source3/winbindd/winbindd_proto.h | 7 + source3/winbindd/winbindd_util.c | 10 +- source3/wscript | 10 +- source4/heimdal/lib/krb5/store.c | 2 + ...cted-dbcheck-link-output-lost-deleted-user3.txt | 16 +- source4/selftest/tests.py | 3 +- testprogs/blackbox/dbcheck-links.sh | 2 +- testprogs/blackbox/dbcheck-oldrelease.sh | 12 ++ 44 files changed, 981 insertions(+), 275 deletions(-) create mode 100644 lib/util/tests/test_memcache.c create mode 100755 source3/script/tests/test_force_user_unlink.sh create mode 100755 source3/script/tests/test_winbind_ignore_domains.sh Changeset truncated at 500 lines: 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.ad...@gmail.com> + * BUG 14634: s3:modules:vfs_virusfilter: Recent talloc changes cause infinite + start-up failure. + +o Jeremy Allison <j...@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 <abart...@samba.org> + * BUG 14593: dbcheck: Check Deleted Objects and reduce noise in reports about + expired tombstones. + +o Ralph Boehme <s...@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 <p...@lysator.liu.se> + * BUG 14648: s3: VFS: nfs4_acls. Add missing TALLOC_FREE(frame) in error + path. + +o Björn Jacke <b...@sernet.de> + * BUG 14624: classicupgrade: Treat old never expires value right. + +o Volker Lendecke <v...@samba.org> + * BUG 14636: g_lock: Fix uninitalized variable reads. + +o Stefan Metzmacher <me...@samba.org> + * BUG 13898: s3:pysmbd: Fix fd leak in py_smbd_create_file(). + +o Andreas Schneider <a...@samba.org> + * BUG 14625: lib:util: Avoid free'ing our own pointer. + +o Paul Wise <pa...@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 <a...@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 -- Samba Shared Repository