The branch, v4-5-test has been updated via ed83c31 ctdb-build: Install CTDB tests correctly from toplevel via cef9a9b s3: VFS: Don't allow symlink, link or rename on already converted paths. via f7c5f02 s3: VFS: shadow_copy2: Fix usage of saved_errno to only set errno on error. via 5c21667 s3: VFS: shadow_copy2: Fix a memory leak in the connectpath function. via d417f2a s3: VFS: shadow_copy2: Fix module to work with variable current working directory. via debe3a3 s3: VFS: Add utility function check_for_converted_path(). via 4bf9875 s3: VFS: Ensure shadow:format cannot contain a / path separator. via f3b5b4c s3: VFS: Allow shadow_copy2_connectpath() to return the cached path derived from $cwd. via 28a4f56 s3: VFS: shadow_copy2: Fix chdir to store off the needed private variables. via 21e16d7 s3: VFS: shadow_copy2: Add two currently unused functions to make pathnames absolute or relative to $cwd. via f87a8a8 s3: VFS: shadow_copy2: Change a parameter name. via 501ff03 s3: VFS: shadow_copy2: Add a wrapper function to call the original shadow_copy2_strip_snapshot(). via 08ae59c s3: VFS: shadow_copy2: Add two new variables to the private data. Not yet used. via 254eb16 s3: VFS: shadow_copy2: Fix length comparison to ensure we don't overstep a length. via aa3365b s3: VFS: shadow_copy2: Ensure pathnames for parameters are correctly relative and terminated. via 9067d6b s3: VFS: shadow_copy2: Correctly initialize timestamp and stripped variables. via 4c81c9b s3: smbd: Make set_conn_connectpath() call canonicalize_absolute_path(). via 7128ea6 s3: smbtorture: Add new local test LOCAL-CANONICALIZE-PATH via ed1d7cb s3: lib: Fix two old, old bugs in set_conn_connectpath(), now in canonicalize_absolute_path(). via 74af6ae s3: lib: Add canonicalize_absolute_path(). via 179e537 s3: smbd: Correctly canonicalize any incoming shadow copy path. via 7b190e1 waf: backport finding of pkg-config via 93c86be dbcheck-links: Test that dbcheck against one-way links does not error via e91260c dbcheck: Do not regard old one-way-links as errors via 1f29fb6 samba_dsdb: Use and maintain compatibleFeatures and requiredFeatures in @SAMBA_DSDB from f4219b7 ctdb-tests: Use replace headers instead of system headers
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-5-test - Log ----------------------------------------------------------------- commit ed83c3122756f96356540db63c1bb6fcc15c42dd Author: Amitay Isaacs <ami...@gmail.com> Date: Wed Feb 1 15:53:47 2017 +1100 ctdb-build: Install CTDB tests correctly from toplevel BUG: https://bugzilla.samba.org/show_bug.cgi?id=12547 Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> Autobuild-User(master): Martin Schwenke <mart...@samba.org> Autobuild-Date(master): Thu Feb 2 08:25:57 CET 2017 on sn-devel-144 (cherry picked from commit ce9b72c17abb156de8185b100f27d1ddd3c89b15) Autobuild-User(v4-5-test): Karolin Seeger <ksee...@samba.org> Autobuild-Date(v4-5-test): Mon Feb 13 20:50:49 CET 2017 on sn-devel-144 commit cef9a9ba3511fbf39e1a664803b3455ed097197e Author: Jeremy Allison <j...@samba.org> Date: Thu Jan 26 17:19:24 2017 -0800 s3: VFS: Don't allow symlink, link or rename on already converted paths. Snapshot paths are a read-only filesystem. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Mon Jan 30 22:26:29 CET 2017 on sn-devel-144 (cherry picked from commit 0e1deb77f2b310ad7e5dd784174207adacf1c981) commit f7c5f022efe7a3039ac56830a068b92c5606c3e4 Author: Jeremy Allison <j...@samba.org> Date: Mon Jan 23 10:20:13 2017 -0800 s3: VFS: shadow_copy2: Fix usage of saved_errno to only set errno on error. Rationale: VFS calls must act like their POSIX equivalents, and the POSIX versions *only* set errno on a failure. There is actually code in the upper smbd layers that depends on errno being correct on a fail return from a VFS call. For a compound VFS module like this, a common pattern is : SMB_VFS_CALL_X() { int ret; syscall1(); ret = syscall2(); syscall3(); return ret; } Where if *any* of the contained syscallX()'s fail, they'll set errno. However, the actual errno we should return is *only* the one returned if syscall2() fails (the others are lstat's checking for existence etc.). So what we should do to correctly return only the errno from syscall2() is: SMB_VFS_CALL_X() { int ret; int saved_errno = 0; syscall1() ret = syscall2(); if (ret == -1) { saved_errno = errno; } syscall3() if (saved_errno != 0) { errno = saved_errno; } return ret; } BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> (cherry picked from commit cda6764f1a8db96182bfd1855440bc6a1ba1abee) commit 5c21667049569f8b272117e9d7c9e2bc2372b174 Author: Jeremy Allison <j...@samba.org> Date: Mon Jan 23 10:06:44 2017 -0800 s3: VFS: shadow_copy2: Fix a memory leak in the connectpath function. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> (cherry picked from commit 4d339a88851f601fae195ac8ff0691cbd3504f41) commit d417f2a68af38ba9c23259610e75c9bfef05d530 Author: Jeremy Allison <j...@samba.org> Date: Thu Jan 26 10:49:51 2017 -0800 s3: VFS: shadow_copy2: Fix module to work with variable current working directory. Completely cleans up the horrible shadow_copy2_strip_snapshot() and adds an explaination of what it's actually trying to do. * This function does two things. * * 1). Checks if an incoming filename is already a * snapshot converted pathname. * If so, it returns the pathname truncated * at the snapshot point which will be used * as the connectpath, and then does an early return. * * 2). Checks if an incoming filename contains an * SMB-layer @GMT- style timestamp. * If so, it strips the timestamp, and returns * both the timestamp and the stripped path * (making it cwd-relative). BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> (cherry picked from commit 128d5f27cd42b0c7efcbe3d28fe3eee881e0734b) commit debe3a3742658239694354d0cf296a2175fcaa64 Author: Jeremy Allison <j...@samba.org> Date: Thu Jan 26 10:35:50 2017 -0800 s3: VFS: Add utility function check_for_converted_path(). Detects an already converted path. Not yet used. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> (cherry picked from commit b94dc85d339c9a10496edd07b85bdd7808d2e332) commit 4bf9875611977ae31d662f1d60e7913884cec045 Author: Jeremy Allison <j...@samba.org> Date: Thu Jan 26 10:24:52 2017 -0800 s3: VFS: Ensure shadow:format cannot contain a / path separator. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> (cherry picked from commit cd4f940162b17e4f7345d392326a31ae478230fa) commit f3b5b4c7e19d716630cbff5427a2688e3eddeb10 Author: Jeremy Allison <j...@samba.org> Date: Fri Jan 20 12:09:08 2017 -0800 s3: VFS: Allow shadow_copy2_connectpath() to return the cached path derived from $cwd. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> (cherry picked from commit 42bd1acad75a6b5ea81fe4b30c067dd82623c042) commit 28a4f561c49fa9dc4d5bbc4393bf21eff0e7d03f Author: Jeremy Allison <j...@samba.org> Date: Fri Jan 20 12:06:55 2017 -0800 s3: VFS: shadow_copy2: Fix chdir to store off the needed private variables. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 This is not yet used, the users of this will be added later. Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> (cherry picked from commit 27340df4b52e4341f134667c59d71656a7a1fdae) commit 21e16d7377752bceee5a254a9e8a2fbb9145ddc7 Author: Jeremy Allison <j...@samba.org> Date: Fri Jan 20 12:00:08 2017 -0800 s3: VFS: shadow_copy2: Add two currently unused functions to make pathnames absolute or relative to $cwd. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> (cherry picked from commit 9d65107b8f2864dba8d41b3316c483b3f36d0697) commit f87a8a895b3ad7f9bb9d2bbea4ac00d23d938bfc Author: Jeremy Allison <j...@samba.org> Date: Fri Jan 20 11:56:21 2017 -0800 s3: VFS: shadow_copy2: Change a parameter name. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 Allows easy substitution later. Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> (cherry picked from commit 2887465108aef5e2e7c64417437ecb86c7460e16) commit 501ff0391642417326e8e2d8b89e10e35bcb56e5 Author: Jeremy Allison <j...@samba.org> Date: Fri Jan 20 11:54:56 2017 -0800 s3: VFS: shadow_copy2: Add a wrapper function to call the original shadow_copy2_strip_snapshot(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 Allows an extra (currently unused) parameter to be added. Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> (cherry picked from commit 5aa1ea95157475dfd2d056f0158b14b2b90895a9) commit 08ae59c48a546cdf84d43a40095d27f9ee767b33 Author: Jeremy Allison <j...@samba.org> Date: Fri Jan 20 11:50:49 2017 -0800 s3: VFS: shadow_copy2: Add two new variables to the private data. Not yet used. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> (cherry picked from commit 72fe2b62e3ee7462e5be855b01943f28b26c36c1) commit 254eb16fc86bd972fcac91e3c43399926d5740cf Author: Jeremy Allison <j...@samba.org> Date: Fri Jan 20 11:48:40 2017 -0800 s3: VFS: shadow_copy2: Fix length comparison to ensure we don't overstep a length. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> (cherry picked from commit 37ef8d3f65bd1215717eb51b2e1cdb84a7bed348) commit aa3365bbc1782f2c3d5d051f9182bda8dc3fd3db Author: Jeremy Allison <j...@samba.org> Date: Fri Jan 20 11:45:54 2017 -0800 s3: VFS: shadow_copy2: Ensure pathnames for parameters are correctly relative and terminated. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> (cherry picked from commit 979e39252bcc88e8aacb543b8bf322dd6f17fe7f) commit 9067d6b6593b12d10553e24aa6a5a776d654d6ee Author: Jeremy Allison <j...@samba.org> Date: Fri Jan 20 11:42:39 2017 -0800 s3: VFS: shadow_copy2: Correctly initialize timestamp and stripped variables. Allow the called functions to be fixed to not touch them on error. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> (cherry picked from commit 0a190f4dd950c947d47c42163d11ea4bd6e6e508) commit 4c81c9b766ae6f0356a8b7d06eb4acf6c308de43 Author: Jeremy Allison <j...@samba.org> Date: Tue Jan 17 11:35:52 2017 -0800 s3: smbd: Make set_conn_connectpath() call canonicalize_absolute_path(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> (cherry picked from commit d650d65488761b30fa34d42cb1ab400618a78c33) commit 7128ea6c0b83b97afe3fa1e585c87b1ad840ae02 Author: Jeremy Allison <j...@samba.org> Date: Thu Jan 26 16:08:42 2017 -0800 s3: smbtorture: Add new local test LOCAL-CANONICALIZE-PATH Tests new canonicalize_absolute_path() function. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> (cherry picked from commit a51363309a4330b65e34ae941ec99d180bdbab56) commit ed1d7cbcc75fc0fe9d7d95843c62423ff9dcd646 Author: Jeremy Allison <j...@samba.org> Date: Thu Jan 19 15:18:41 2017 -0800 s3: lib: Fix two old, old bugs in set_conn_connectpath(), now in canonicalize_absolute_path(). Canonicalizing a path of /foo/bar/../baz would return /foo/barbaz as moving forward 3 characters would delete the / character. Canonicalizing /foo/.. would end up as '\0'. Test to follow. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> (cherry picked from commit 82979afc46cc5e466bdd999a94080e7a5df95518) commit 74af6ae03169be7669c69f4456268f80f6d4c054 Author: Jeremy Allison <j...@samba.org> Date: Tue Jan 17 11:33:18 2017 -0800 s3: lib: Add canonicalize_absolute_path(). Resolves any invalid path components (.) (..) in an absolute POSIX path. We will be re-using this in several places. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> (cherry picked from commit 02599c39337c3049762a6b0bd6290577817ee5a5) commit 179e53761b4b7ec5b170ae96834131565b1954b4 Author: Jeremy Allison <j...@samba.org> Date: Wed Jan 11 16:30:38 2017 -0800 s3: smbd: Correctly canonicalize any incoming shadow copy path. Converts to: @GMT-token/path/last_component from all incoming path types. Allows shadow_copy modules to work when current directory is changed after removing last component. Ultimately when the VFS ABI is changed to add a timestamp to struct smb_filename, this is where the parsing will be done. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> (cherry picked from commit 39678ed6af708fb6f2760bfb51051add11e3c498) commit 7b190e1ae327c1e4d198841c43d849d339560950 Author: Uri Simchoni <u...@samba.org> Date: Thu Jan 19 07:46:57 2017 +0200 waf: backport finding of pkg-config Allow the builder to customize the location of pkg-config utility by setting PKGCONFIG environment variable. This is backported from upstream waf. Thanks to Zentaro Kavanagh <zent...@google.com> for pointing that out and proposing the fix. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12529 Signed-off-by: Uri Simchoni <u...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Wed Jan 25 04:23:00 CET 2017 on sn-devel-144 (cherry picked from commit 2cf141ed45b4f7b7754cb9525d987ff38495d789) commit 93c86bef54d640c3ae452ed340c20a4447972d8e Author: Garming Sam <garm...@catalyst.net.nz> Date: Wed Feb 8 15:24:14 2017 +1300 dbcheck-links: Test that dbcheck against one-way links does not error Signed-off-by: Garming Sam <garm...@catalyst.net.nz> BUG: https://bugzilla.samba.org/show_bug.cgi?id=12577 Pair-programmed-with: Bob Campbell <bobcampb...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> Autobuild-User(master): Andrew Bartlett <abart...@samba.org> Autobuild-Date(master): Mon Feb 13 07:33:08 CET 2017 on sn-devel-144 (cherry picked from commit 44ee31675afd277d429cb246525741110f8fceec) commit e91260c844556fb6fd9329221fc227f1d879e674 Author: Andrew Bartlett <abart...@samba.org> Date: Thu Feb 2 16:27:35 2017 +1300 dbcheck: Do not regard old one-way-links as errors Samba does not maintain one way links when the target is deleted or renamed so do not fail dbcheck because of such links, but allow them to be updated. This matters because administrators and make test expect that normal Samba operation do NOT cause the database to become corrupt, and any error from dbcheck tends to trigger alarms (or test failures). If an object pointed at by a one way link is renamed or deleted in normal operations (such as intersiteTopologyGenerator pointing at a demoted DC), or make test, then this could trigger. Signed-off-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Garming Sam <garm...@catalyst.net.nz> BUG: https://bugzilla.samba.org/show_bug.cgi?id=12577 (cherry picked from commit 35bfc62a31c9ad73449594ddd48f76f50e0abade) commit 1f29fb60886abbf49575cf3dc267ac819bf08d41 Author: Andrew Bartlett <abart...@samba.org> Date: Thu Jan 12 16:51:45 2017 +1300 samba_dsdb: Use and maintain compatibleFeatures and requiredFeatures in @SAMBA_DSDB This will allow us to introduce new database features that are backward compatible from the point of view of older versions of Samba, but which will be damaged by modifying the database with such a version. For example, if linked attributes are stored in sorted order in 4.7, and this change, without any values in current_supportedFeatures is itself included in 4.6, then our sortedLinks are backward compatible to that release. That is with 4.6 (including this patch) which doesn't care about ordering -- but a downgraded 4.7 database used by 4.6 will be broken when later used with 4.7. If we add a 'sortedLinks' feature flag in compatibleFeatures, we can detect that. This will allow us to determine if the database still contains unsorted links, as that information allows us to make the code handling links much more efficient. We won't add the actual flag until all the code is in place. Andrew wrote the actual code and Douglas wrote the tests, and they cross-reviewed. Signed-off-by: Andrew Bartlett <abart...@samba.org> Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Piar-programmed-with: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> selftest: check for database features flags (cherry picked from commit 8368e06ff65cc70e1cf13a0eb4349033e068fcc6) BUG 12573: Samba < 4.7 does not know about compatibleFeatures and requiredFeatures ----------------------------------------------------------------------- Summary of changes: ctdb/wscript | 7 +- python/samba/dbchecker.py | 47 +- source3/lib/util_path.c | 139 ++++ source3/lib/util_path.h | 1 + source3/modules/vfs_shadow_copy2.c | 909 +++++++++++++++------ source3/selftest/tests.py | 1 + source3/smbd/filename.c | 150 ++++ source3/smbd/service.c | 103 +-- source3/torture/torture.c | 44 + source4/dsdb/samdb/ldb_modules/samba_dsdb.c | 78 +- source4/dsdb/samdb/samdb.h | 2 + .../release-4-5-0-pre1/dangling-one-way-link.ldif | 15 + source4/selftest/tests.py | 5 + source4/setup/tests/blackbox_supported_features.sh | 86 ++ testprogs/blackbox/dbcheck-links.sh | 10 + testprogs/blackbox/renamedc.sh | 6 +- third_party/waf/wafadmin/Tools/config_c.py | 4 +- 17 files changed, 1240 insertions(+), 367 deletions(-) create mode 100644 source4/selftest/provisions/release-4-5-0-pre1/dangling-one-way-link.ldif create mode 100755 source4/setup/tests/blackbox_supported_features.sh Changeset truncated at 500 lines: diff --git a/ctdb/wscript b/ctdb/wscript index 4b58d2f..debfacc 100644 --- a/ctdb/wscript +++ b/ctdb/wscript @@ -768,8 +768,13 @@ def build(bld): 'tool' ] + if bld.env.standalone_ctdb: + testdir = 'tests' + else: + testdir = 'ctdb/tests' + for t in test_subdirs: - files = SUBDIR_MODE('tests/%s' % t, trim_path='tests') + files = SUBDIR_MODE('%s/%s' % (testdir, t), trim_path=testdir) for fmode in files: bld.INSTALL_FILES(bld.env.CTDB_TEST_DATADIR, 'tests/%s' % fmode[0], destname=fmode[0], chmod=fmode[1]) diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py index 3fcfbc0..22819de 100644 --- a/python/samba/dbchecker.py +++ b/python/samba/dbchecker.py @@ -59,6 +59,7 @@ class dbcheck(object): self.fix_all_string_dn_component_mismatch = False self.fix_all_GUID_dn_component_mismatch = False self.fix_all_SID_dn_component_mismatch = False + self.fix_all_old_dn_string_component_mismatch = False self.fix_all_metadata = False self.fix_time_metadata = False self.fix_undead_linked_attributes = False @@ -574,6 +575,23 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) "Failed to fix %s on attribute %s" % (errstr, attrname)): self.report("Fixed %s on attribute %s" % (errstr, attrname)) + def err_dn_string_component_old(self, dn, attrname, val, dsdb_dn, correct_dn): + """handle a DN string being incorrect""" + self.report("NOTE: old (due to rename or delete) DN string component for %s in object %s - %s" % (attrname, dn, val)) + dsdb_dn.dn = correct_dn + + if not self.confirm_all('Change DN to %s?' % str(dsdb_dn), + 'fix_all_old_dn_string_component_mismatch'): + self.report("Not fixing old string component") + return + m = ldb.Message() + m.dn = dn + m['old_value'] = ldb.MessageElement(val, ldb.FLAG_MOD_DELETE, attrname) + m['new_value'] = ldb.MessageElement(str(dsdb_dn), ldb.FLAG_MOD_ADD, attrname) + if self.do_modify(m, ["show_recycled:1"], + "Failed to fix old DN string on attribute %s" % (attrname)): + self.report("Fixed old DN string on attribute %s" % (attrname)) + def err_dn_component_target_mismatch(self, dn, attrname, val, dsdb_dn, correct_dn, mismatch_type): """handle a DN string being incorrect""" self.report("ERROR: incorrect DN %s component for %s in object %s - %s" % (mismatch_type, attrname, dn, val)) @@ -914,12 +932,16 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) if rmd_flags & 1: continue - # check the DN matches in string form - if str(res[0].dn) != str(dsdb_dn.dn): - error_count += 1 - self.err_dn_component_target_mismatch(obj.dn, attrname, val, dsdb_dn, - res[0].dn, "string") - continue + # assert the DN matches in string form, where a reverse + # link exists, otherwise (below) offer to fix it as a non-error. + # The string form is essentially only kept for forensics, + # as we always re-resolve by GUID in normal operations. + if reverse_link_name is not None: + if str(res[0].dn) != str(dsdb_dn.dn): + error_count += 1 + self.err_dn_component_target_mismatch(obj.dn, attrname, val, dsdb_dn, + res[0].dn, "string") + continue if res[0].dn.get_extended_component("GUID") != dsdb_dn.dn.get_extended_component("GUID"): error_count += 1 @@ -933,9 +955,18 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) res[0].dn, "SID") continue + # Now we have checked the GUID and SID, offer to fix old + # DN strings as a non-error (for forward links with no + # backlink). Samba does not maintain this string + # otherwise, so we don't increment error_count. + if reverse_link_name is None: + if str(res[0].dn) != str(dsdb_dn.dn): + self.err_dn_string_component_old(obj.dn, attrname, val, dsdb_dn, + res[0].dn) + continue - # check the reverse_link is correct if there should be one - if reverse_link_name is not None: + else: + # check the reverse_link is correct if there should be one match_count = 0 if reverse_link_name in res[0]: for v in res[0][reverse_link_name]: diff --git a/source3/lib/util_path.c b/source3/lib/util_path.c index 509ba5f..6f58a03 100644 --- a/source3/lib/util_path.c +++ b/source3/lib/util_path.c @@ -93,3 +93,142 @@ char *cache_path(const char *name) { return xx_path(name, lp_cache_directory()); } + +/** + * @brief Removes any invalid path components in an absolute POSIX path. + * + * @param ctx Talloc context to return string. + * + * @param abs_path Absolute path string to process. + * + * @retval Pointer to a talloc'ed string containing the absolute full path. + **/ + +char *canonicalize_absolute_path(TALLOC_CTX *ctx, const char *abs_path) +{ + char *destname; + char *d; + const char *s = abs_path; + bool start_of_name_component = true; + + /* Allocate for strlen + '\0' + possible leading '/' */ + destname = (char *)talloc_size(ctx, strlen(abs_path) + 2); + if (destname == NULL) { + return NULL; + } + d = destname; + + *d++ = '/'; /* Always start with root. */ + + while (*s) { + if (*s == '/') { + /* Eat multiple '/' */ + while (*s == '/') { + s++; + } + if ((d > destname + 1) && (*s != '\0')) { + *d++ = '/'; + } + start_of_name_component = true; + continue; + } + + if (start_of_name_component) { + if ((s[0] == '.') && (s[1] == '.') && + (s[2] == '/' || s[2] == '\0')) { + /* Uh oh - "/../" or "/..\0" ! */ + + /* Go past the .. leaving us on the / or '\0' */ + s += 2; + + /* If we just added a '/' - delete it */ + if ((d > destname) && (*(d-1) == '/')) { + *(d-1) = '\0'; + d--; + } + + /* + * Are we at the start ? + * Can't go back further if so. + */ + if (d <= destname) { + *d++ = '/'; /* Can't delete root */ + continue; + } + /* Go back one level... */ + /* + * Decrement d first as d points to + * the *next* char to write into. + */ + for (d--; d > destname; d--) { + if (*d == '/') { + break; + } + } + + /* + * Are we at the start ? + * Can't go back further if so. + */ + if (d <= destname) { + *d++ = '/'; /* Can't delete root */ + continue; + } + + /* + * We're still at the start of a name + * component, just the previous one. + */ + continue; + } else if ((s[0] == '.') && + ((s[1] == '\0') || s[1] == '/')) { + /* + * Component of pathname can't be "." only. + * Skip the '.' . + */ + if (s[1] == '/') { + s += 2; + } else { + s++; + } + continue; + } + } + + if (!(*s & 0x80)) { + *d++ = *s++; + } else { + size_t siz; + /* Get the size of the next MB character. */ + next_codepoint(s,&siz); + switch(siz) { + case 5: + *d++ = *s++; + /*fall through*/ + case 4: + *d++ = *s++; + /*fall through*/ + case 3: + *d++ = *s++; + /*fall through*/ + case 2: + *d++ = *s++; + /*fall through*/ + case 1: + *d++ = *s++; + break; + default: + break; + } + } + start_of_name_component = false; + } + *d = '\0'; + + /* And must not end in '/' */ + if (d > destname + 1 && (*(d-1) == '/')) { + *(d-1) = '\0'; + } + + return destname; +} diff --git a/source3/lib/util_path.h b/source3/lib/util_path.h index 118a4be..16e2792 100644 --- a/source3/lib/util_path.h +++ b/source3/lib/util_path.h @@ -27,5 +27,6 @@ char *lock_path(const char *name); char *state_path(const char *name); char *cache_path(const char *name); +char *canonicalize_absolute_path(TALLOC_CTX *ctx, const char *abs_path); #endif diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index 1f876e7..f0ec820 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -35,6 +35,7 @@ #include "system/filesys.h" #include "include/ntioctl.h" #include "util_tdb.h" +#include "lib/util_path.h" struct shadow_copy2_config { char *gmt_format; @@ -74,6 +75,11 @@ struct shadow_copy2_snaplist_info { struct shadow_copy2_private { struct shadow_copy2_config *config; struct shadow_copy2_snaplist_info *snaps; + char *shadow_cwd; /* Absolute $cwd path. */ + /* Absolute connectpath - can vary depending on $cwd. */ + char *shadow_connectpath; + /* malloc'ed realpath return. */ + char *shadow_realpath; }; static int shadow_copy2_get_shadow_copy_data( @@ -404,79 +410,254 @@ static char *shadow_copy2_snapshot_path(TALLOC_CTX *mem_ctx, return result; } +static char *make_path_absolute(TALLOC_CTX *mem_ctx, + struct shadow_copy2_private *priv, + const char *name) +{ + char *newpath = NULL; + char *abs_path = NULL; + + if (name[0] != '/') { + newpath = talloc_asprintf(mem_ctx, + "%s/%s", + priv->shadow_cwd, + name); + if (newpath == NULL) { + return NULL; + } + name = newpath; + } + abs_path = canonicalize_absolute_path(mem_ctx, name); + TALLOC_FREE(newpath); + return abs_path; +} + +/* Return a $cwd-relative path. */ +static bool make_relative_path(const char *cwd, char *abs_path) +{ + size_t cwd_len = strlen(cwd); + size_t abs_len = strlen(abs_path); + + if (abs_len < cwd_len) { + return false; + } + if (memcmp(abs_path, cwd, cwd_len) != 0) { + return false; + } + if (abs_path[cwd_len] != '/' && abs_path[cwd_len] != '\0') { + return false; + } + if (abs_path[cwd_len] == '/') { + cwd_len++; + } + memmove(abs_path, &abs_path[cwd_len], abs_len + 1 - cwd_len); + return true; +} + +static bool shadow_copy2_snapshot_to_gmt(vfs_handle_struct *handle, + const char *name, + char *gmt, size_t gmt_len); + +/* + * Check if an incoming filename is already a snapshot converted pathname. + * + * If so, it returns the pathname truncated at the snapshot point which + * will be used as the connectpath. + */ + +static int check_for_converted_path(TALLOC_CTX *mem_ctx, + struct vfs_handle_struct *handle, + struct shadow_copy2_private *priv, + char *abs_path, + bool *ppath_already_converted, + char **pconnectpath) +{ + size_t snapdirlen = 0; + char *p = strstr_m(abs_path, priv->config->snapdir); + char *q = NULL; + char *connect_path = NULL; + char snapshot[GMT_NAME_LEN+1]; + + *ppath_already_converted = false; + + if (p == NULL) { + /* Must at least contain shadow:snapdir. */ + return 0; + } + + if (priv->config->snapdir[0] == '/' && + p != abs_path) { + /* Absolute shadow:snapdir must be at the start. */ + return 0; + } + + snapdirlen = strlen(priv->config->snapdir); + if (p[snapdirlen] != '/') { + /* shadow:snapdir must end as a separate component. */ + return 0; + } + + if (p > abs_path && p[-1] != '/') { + /* shadow:snapdir must start as a separate component. */ + return 0; + } + + p += snapdirlen; + p++; /* Move past the / */ + + /* + * Need to return up to the next path + * component after the time. + * This will be used as the connectpath. + */ + q = strchr(p, '/'); + if (q == NULL) { + /* + * No next path component. + * Use entire string. + */ + connect_path = talloc_strdup(mem_ctx, + abs_path); + } else { + connect_path = talloc_strndup(mem_ctx, + abs_path, + q - abs_path); + } + if (connect_path == NULL) { + return ENOMEM; + } + + /* + * Point p at the same offset in connect_path as + * it is in abs_path. + */ + + p = &connect_path[p - abs_path]; + + /* + * Now ensure there is a time string at p. + * The SMB-format @GMT-token string is returned + * in snapshot. + */ + + if (!shadow_copy2_snapshot_to_gmt(handle, + p, + snapshot, + sizeof(snapshot))) { + TALLOC_FREE(connect_path); + return 0; + } + + if (pconnectpath != NULL) { + *pconnectpath = connect_path; + } + + *ppath_already_converted = true; + + DBG_DEBUG("path |%s| is already converted. " + "connect path = |%s|\n", + abs_path, + connect_path); + + return 0; +} + /** - * Strip a snapshot component from a filename as - * handed in via the smb layer. - * Returns the parsed timestamp and the stripped filename. + * This function does two things. + * + * 1). Checks if an incoming filename is already a + * snapshot converted pathname. + * If so, it returns the pathname truncated + * at the snapshot point which will be used + * as the connectpath, and then does an early return. + * + * 2). Checks if an incoming filename contains an + * SMB-layer @GMT- style timestamp. + * If so, it strips the timestamp, and returns + * both the timestamp and the stripped path + * (making it cwd-relative). */ -static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx, + +static bool shadow_copy2_strip_snapshot_internal(TALLOC_CTX *mem_ctx, struct vfs_handle_struct *handle, - const char *name, + const char *orig_name, time_t *ptimestamp, - char **pstripped) + char **pstripped, + char **psnappath) { struct tm tm; - time_t timestamp; + time_t timestamp = 0; const char *p; char *q; - char *stripped; + char *stripped = NULL; size_t rest_len, dst_len; struct shadow_copy2_private *priv; - const char *snapdir; - ssize_t snapdirlen; ptrdiff_t len_before_gmt; + const char *name = orig_name; + char *abs_path = NULL; + bool ret = true; + bool already_converted = false; + int err = 0; SMB_VFS_HANDLE_GET_DATA(handle, priv, struct shadow_copy2_private, return false); DEBUG(10, (__location__ ": enter path '%s'\n", name)); + abs_path = make_path_absolute(mem_ctx, priv, name); + if (abs_path == NULL) { + ret = false; + goto out; + } + name = abs_path; + + DEBUG(10, (__location__ ": abs path '%s'\n", name)); + + err = check_for_converted_path(mem_ctx, + handle, -- Samba Shared Repository