summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2017-03-27 17:04:58 -0700
committerKarolin Seeger <kseeger@samba.org>2017-03-29 10:24:14 +0200
commit8e3e969eeddc542385d0ccee793f71c12e8fd4b6 (patch)
tree271ec348caaca11c475afeabeef61f2b016e3c84
parent9a5be8b68ba38e0d98329c44d0d5c6d4579c9bf5 (diff)
downloadsamba-8e3e969eeddc542385d0ccee793f71c12e8fd4b6.tar.gz
s3: smbd: Fix "follow symlink = no" regression part 2.
Add an extra paramter to cwd_name to check_reduced_name(). If cwd_name == NULL then fname is a client given path relative to the root path of the share. If cwd_name != NULL then fname is a client given path relative to cwd_name. cwd_name is relative to the root path of the share. Not yet used, logic added in the next commit. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12721 Signed-off-by: Jeremy Allison <jra@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org> (cherry picked from commit 83e30cb48859b412b76572b6a3ba84d8fde167af)
-rw-r--r--source3/smbd/filename.c2
-rw-r--r--source3/smbd/open.c2
-rw-r--r--source3/smbd/proto.h4
-rw-r--r--source3/smbd/vfs.c10
4 files changed, 14 insertions, 4 deletions
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 046ce9c8391..9f72f99896a 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -1240,7 +1240,7 @@ NTSTATUS check_name(connection_struct *conn, const char *name)
}
if (!lp_widelinks(SNUM(conn)) || !lp_follow_symlinks(SNUM(conn))) {
- status = check_reduced_name(conn,name);
+ status = check_reduced_name(conn, NULL, name);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5,("check_name: name %s failed with %s\n",name,
nt_errstr(status)));
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 0b6648739fb..f19af87103b 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -546,7 +546,7 @@ static int non_widelink_open(struct connection_struct *conn,
}
/* Ensure the relative path is below the share. */
- status = check_reduced_name(conn, final_component);
+ status = check_reduced_name(conn, parent_dir, final_component);
if (!NT_STATUS_IS_OK(status)) {
saved_errno = map_errno_from_nt_status(status);
goto out;
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index ebccdb94d02..9103e6eb1bf 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -1197,7 +1197,9 @@ const char *vfs_readdirname(connection_struct *conn, void *p,
SMB_STRUCT_STAT *sbuf, char **talloced);
int vfs_ChDir(connection_struct *conn, const char *path);
char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn);
-NTSTATUS check_reduced_name(connection_struct *conn, const char *fname);
+NTSTATUS check_reduced_name(connection_struct *conn,
+ const char *cwd_name,
+ const char *fname);
NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
const char *fname,
struct smb_request *smbreq);
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index c358f78408f..22054674435 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -1149,9 +1149,17 @@ NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
/*******************************************************************
Reduce a file name, removing .. elements and checking that
it is below dir in the heirachy. This uses realpath.
+
+ If cwd_name == NULL then fname is a client given path relative
+ to the root path of the share.
+
+ If cwd_name != NULL then fname is a client given path relative
+ to cwd_name. cwd_name is relative to the root path of the share.
********************************************************************/
-NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
+NTSTATUS check_reduced_name(connection_struct *conn,
+ const char *cwd_name,
+ const char *fname)
{
char *resolved_name = NULL;
bool allow_symlinks = true;