+++ /dev/null
-From b6192b3cdeaa9eb719ec5da3977af9470504d294 Mon Sep 17 00:00:00 2001
-From: Michael Adam <obnox@samba.org>
-Date: Wed, 23 Dec 2015 18:01:23 +0100
-Subject: [PATCH] s3:smbd: fix a corner case of the symlink verification
-
-Commit 7606c0db257b3f9d84da5b2bf5fbb4034cc8d77d fixes the
-path checks in check_reduced_name[_with_privilege]() to
-prevent unintended access via wide links.
-
-The fix fails to correctly treat a corner case where the share
-path is "/". This case is important for some real world
-scenarios, notably the use of the glusterfs VFS module:
-
-For the share path "/", the newly introduced checks deny all
-operations in the share.
-
-This change fixes the checks for the corner case.
-The point is that the assumptions on which the original
-checks are based are not true for the rootdir "/" case.
-This is the case where the rootdir starts _and ends_ with
-a slash. Hence a subdirectory does not continue with a
-slash after the rootdir, since the candidate path has
-been normalized.
-
-This fix just omits the string comparison and the
-next character checks in the case of rootdir "/",
-which is correct because we know that the candidate
-path is normalized and hence starts with a '/'.
-
-The patch is fairly minimal, but changes indentation,
-hence best viewed with 'git show -w'.
-
-A side effect is that the rootdir="/" case needs
-one strncmp less.
-
-BUG: https://bugzilla.samba.org/show_bug.cgi?id=11647
-
-Pair-Programmed-With: Jose A. Rivera <jarrpa@samba.org>
-
-Signed-off-by: Michael Adam <obnox@samba.org>
-Signed-off-by: Jose A. Rivera <jarrpa@samba.org>
-Reviewed-by: Jeremy Allison <jra@samba.org>
-
-Autobuild-User(master): Michael Adam <obnox@samba.org>
-Autobuild-Date(master): Thu Dec 24 00:57:31 CET 2015 on sn-devel-144
-
-(cherry picked from commit ada59ec7b3a5ed0478d11da2fe0c90991d137288)
----
- source3/smbd/vfs.c | 39 +++++++++++++++++++++++++++------------
- 1 file changed, 27 insertions(+), 12 deletions(-)
-
-diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
-index bd93b7f..2b8000d 100644
---- a/source3/smbd/vfs.c
-+++ b/source3/smbd/vfs.c
-@@ -982,7 +982,6 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
- if (!allow_widelinks || !allow_symlinks) {
- const char *conn_rootdir;
- size_t rootdir_len;
-- bool matched;
-
- conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
- if (conn_rootdir == NULL) {
-@@ -993,17 +992,33 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
- }
-
- rootdir_len = strlen(conn_rootdir);
-- matched = (strncmp(conn_rootdir, resolved_name,
-- rootdir_len) == 0);
-- if (!matched || (resolved_name[rootdir_len] != '/' &&
-- resolved_name[rootdir_len] != '\0')) {
-- DEBUG(2, ("check_reduced_name: Bad access "
-- "attempt: %s is a symlink outside the "
-- "share path\n", fname));
-- DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
-- DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
-- SAFE_FREE(resolved_name);
-- return NT_STATUS_ACCESS_DENIED;
-+
-+ /*
-+ * In the case of rootdir_len == 1, we know that
-+ * conn_rootdir is "/", and we also know that
-+ * resolved_name starts with a slash. So, in this
-+ * corner case, resolved_name is automatically a
-+ * sub-directory of the conn_rootdir. Thus we can skip
-+ * the string comparison and the next character checks
-+ * (which are even wrong in this case).
-+ */
-+ if (rootdir_len != 1) {
-+ bool matched;
-+
-+ matched = (strncmp(conn_rootdir, resolved_name,
-+ rootdir_len) == 0);
-+ if (!matched || (resolved_name[rootdir_len] != '/' &&
-+ resolved_name[rootdir_len] != '\0')) {
-+ DEBUG(2, ("check_reduced_name: Bad access "
-+ "attempt: %s is a symlink outside the "
-+ "share path\n", fname));
-+ DEBUGADD(2, ("conn_rootdir =%s\n",
-+ conn_rootdir));
-+ DEBUGADD(2, ("resolved_name=%s\n",
-+ resolved_name));
-+ SAFE_FREE(resolved_name);
-+ return NT_STATUS_ACCESS_DENIED;
-+ }
- }
-
- /* Extra checks if all symlinks are disallowed. */
---
-2.5.0
-