[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha7-1951-g84090c9

Volker Lendecke vlendec at samba.org
Tue Jun 2 09:58:53 GMT 2009


The branch, master has been updated
       via  84090c95a5851d71bf61388281547041f9c0b277 (commit)
       via  56efcb7b723b581b9c258d137331a171512d4d09 (commit)
       via  83ffbb4ec4e0519cd4f9c5f95e11d70c18a1b25b (commit)
      from  cdb765a76caaa582b6406bd34279d04e4be9d6f2 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 84090c95a5851d71bf61388281547041f9c0b277
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Feb 2 11:52:08 2009 +0100

    Add a "connectpath" operation to the shadow_copy2 module

commit 56efcb7b723b581b9c258d137331a171512d4d09
Author: Volker Lendecke <vl at samba.org>
Date:   Thu May 28 19:20:14 2009 +0200

    Add SMB_VFS_CONNECTPATH operation
    
    This is required for the shadow_copy2 module and "wide links = no". The file
    system snapshots by nature are typically outside of share directory. So the
    REALPATH result fails the wide links = no test.

commit 83ffbb4ec4e0519cd4f9c5f95e11d70c18a1b25b
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Jan 30 15:04:44 2009 +0100

    Remove a variable used just once

-----------------------------------------------------------------------

Summary of changes:
 source3/include/vfs.h              |    5 +++
 source3/include/vfs_macros.h       |    3 ++
 source3/modules/vfs_default.c      |    8 +++++
 source3/modules/vfs_full_audit.c   |   18 ++++++++++++
 source3/modules/vfs_shadow_copy2.c |   54 ++++++++++++++++++++++++++++++++++++
 source3/smbd/vfs.c                 |   29 ++++++++++++++----
 6 files changed, 110 insertions(+), 7 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 0c0e093..9a736a7 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -221,6 +221,7 @@ typedef enum _vfs_op_type {
 	SMB_VFS_OP_FILE_ID_CREATE,
 	SMB_VFS_OP_STREAMINFO,
 	SMB_VFS_OP_GET_REAL_FILENAME,
+	SMB_VFS_OP_CONNECTPATH,
 	SMB_VFS_OP_BRL_LOCK_WINDOWS,
 	SMB_VFS_OP_BRL_UNLOCK_WINDOWS,
 	SMB_VFS_OP_BRL_CANCEL_WINDOWS,
@@ -402,6 +403,9 @@ struct vfs_ops {
 					 TALLOC_CTX *mem_ctx,
 					 char **found_name);
 
+		const char *(*connectpath)(struct vfs_handle_struct *handle,
+					   const char *filename);
+
 		NTSTATUS (*brl_lock_windows)(struct vfs_handle_struct *handle,
 					     struct byte_range_lock *br_lck,
 					     struct lock_struct *plock,
@@ -564,6 +568,7 @@ struct vfs_ops {
 		struct vfs_handle_struct *file_id_create;
 		struct vfs_handle_struct *streaminfo;
 		struct vfs_handle_struct *get_real_filename;
+		struct vfs_handle_struct *connectpath;
 		struct vfs_handle_struct *brl_lock_windows;
 		struct vfs_handle_struct *brl_unlock_windows;
 		struct vfs_handle_struct *brl_cancel_windows;
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index acb158e..0b59f8f 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -88,6 +88,7 @@
 #define SMB_VFS_FILE_ID_CREATE(conn, sbuf) ((conn)->vfs.ops.file_id_create((conn)->vfs.handles.file_id_create, (sbuf)))
 #define SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams) ((conn)->vfs.ops.streaminfo((conn)->vfs.handles.streaminfo, (fsp), (fname), (mem_ctx), (num_streams), (streams)))
 #define SMB_VFS_GET_REAL_FILENAME(conn, path, name, mem_ctx, found_name) ((conn)->vfs.ops.get_real_filename((conn)->vfs.handles.get_real_filename, (path), (name), (mem_ctx), (found_name)))
+#define SMB_VFS_CONNECTPATH(conn, fname) ((conn)->vfs.ops.connectpath((conn)->vfs.handles.connectpath, (fname)))
 #define SMB_VFS_BRL_LOCK_WINDOWS(conn, br_lck, plock, blocking_lock, blr) ((conn)->vfs.ops.brl_lock_windows((conn)->vfs.handles.brl_lock_windows, (br_lck), (plock), (blocking_lock), (blr)))
 #define SMB_VFS_BRL_UNLOCK_WINDOWS(conn, msg_ctx, br_lck, plock) ((conn)->vfs.ops.brl_unlock_windows((conn)->vfs.handles.brl_unlock_windows, (msg_ctx), (br_lck), (plock)))
 #define SMB_VFS_BRL_CANCEL_WINDOWS(conn, br_lck, plock, blr) ((conn)->vfs.ops.brl_cancel_windows((conn)->vfs.handles.brl_cancel_windows, (br_lck), (plock), (blr)))
@@ -222,6 +223,7 @@
 #define SMB_VFS_OPAQUE_FILE_ID_CREATE(conn, sbuf) ((conn)->vfs.ops_opaque.file_id_create((conn)->vfs_opaque.handles.file_id_create, (sbuf)))
 #define SMB_VFS_OPAQUE_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams) ((conn)->vfs_opaque.ops.streaminfo((conn)->vfs_opaque.handles.streaminfo, (fsp), (fname), (mem_ctx), (num_streams), (streams)))
 #define SMB_VFS_OPAQUE_GET_REAL_FILENAME(conn, path, name, mem_ctx, found_name) ((conn)->vfs_opaque.ops.get_real_filename((conn)->vfs_opaque.handles.get_real_filename, (path), (name), (mem_ctx), (found_name)))
+#define SMB_VFS_OPAQUE_CONNECTPATH(conn, fname) ((conn)->vfs_opaque.ops.connectpath((conn)->vfs_opaque.handles.connectpath, (fname)))
 #define SMB_VFS_OPAQUE_BRL_LOCK_WINDOWS(conn, br_lck, plock, blocking_lock, blr) ((conn)->vfs_opaque.ops.brl_lock_windows((conn)->vfs_opaque.handles.brl_lock_windows, (br_lck), (plock), (blocking_lock), (blr)))
 #define SMB_VFS_OPAQUE_BRL_UNLOCK_WINDOWS(conn, msg_ctx, br_lck, plock) ((conn)->vfs_opaque.ops.brl_unlock_windows((conn)->vfs_opaque.handles.brl_unlock_windows, (msg_ctx), (br_lck), (plock)))
 #define SMB_VFS_OPAQUE_BRL_CANCEL_WINDOWS(conn, br_lck, plock, blr) ((conn)->vfs_opaque.ops.brl_cancel_windows((conn)->vfs_opaque.handles.brl_cancel_windows, (br_lck), (plock), (blr)))
@@ -357,6 +359,7 @@
 #define SMB_VFS_NEXT_FILE_ID_CREATE(handle, sbuf) ((handle)->vfs_next.ops.file_id_create((handle)->vfs_next.handles.file_id_create, (sbuf)))
 #define SMB_VFS_NEXT_STREAMINFO(handle, fsp, fname, mem_ctx, num_streams, streams) ((handle)->vfs_next.ops.streaminfo((handle)->vfs_next.handles.streaminfo, (fsp), (fname), (mem_ctx), (num_streams), (streams)))
 #define SMB_VFS_NEXT_GET_REAL_FILENAME(handle, path, name, mem_ctx, found_name) ((handle)->vfs_next.ops.get_real_filename((handle)->vfs_next.handles.get_real_filename, (path), (name), (mem_ctx), (found_name)))
+#define SMB_VFS_NEXT_CONNECTPATH(conn, fname) ((conn)->vfs_next.ops.connectpath((conn)->vfs_next.handles.connectpath, (fname)))
 #define SMB_VFS_NEXT_BRL_LOCK_WINDOWS(handle, br_lck, plock, blocking_lock, blr) ((handle)->vfs_next.ops.brl_lock_windows((handle)->vfs_next.handles.brl_lock_windows, (br_lck), (plock), (blocking_lock), (blr)))
 #define SMB_VFS_NEXT_BRL_UNLOCK_WINDOWS(handle, msg_ctx, br_lck, plock) ((handle)->vfs_next.ops.brl_unlock_windows((handle)->vfs_next.handles.brl_unlock_windows, (msg_ctx), (br_lck), (plock)))
 #define SMB_VFS_NEXT_BRL_CANCEL_WINDOWS(handle, br_lck, plock, blr) ((handle)->vfs_next.ops.brl_cancel_windows((handle)->vfs_next.handles.brl_cancel_windows, (br_lck), (plock), (blr)))
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index fe63d50..4368dcd 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -1128,6 +1128,12 @@ static int vfswrap_get_real_filename(struct vfs_handle_struct *handle,
 	return -1;
 }
 
+static const char *vfswrap_connectpath(struct vfs_handle_struct *handle,
+				       const char *fname)
+{
+	return handle->conn->connectpath;
+}
+
 static NTSTATUS vfswrap_brl_lock_windows(struct vfs_handle_struct *handle,
 					 struct byte_range_lock *br_lck,
 					 struct lock_struct *plock,
@@ -1630,6 +1636,8 @@ static vfs_op_tuple vfs_default_ops[] = {
 	 SMB_VFS_LAYER_OPAQUE},
 	{SMB_VFS_OP(vfswrap_get_real_filename),	SMB_VFS_OP_GET_REAL_FILENAME,
 	 SMB_VFS_LAYER_OPAQUE},
+	{SMB_VFS_OP(vfswrap_connectpath),	SMB_VFS_OP_CONNECTPATH,
+	 SMB_VFS_LAYER_OPAQUE},
 	{SMB_VFS_OP(vfswrap_brl_lock_windows),	SMB_VFS_OP_BRL_LOCK_WINDOWS,
 	 SMB_VFS_LAYER_OPAQUE},
 	{SMB_VFS_OP(vfswrap_brl_unlock_windows),SMB_VFS_OP_BRL_UNLOCK_WINDOWS,
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index ebe89ec..bbcb7b3 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -221,6 +221,8 @@ static int smb_full_audit_get_real_filename(struct vfs_handle_struct *handle,
 					    const char *name,
 					    TALLOC_CTX *mem_ctx,
 					    char **found_name);
+static const char *smb_full_audit_connectpath(vfs_handle_struct *handle,
+					      const char *fname);
 static NTSTATUS smb_full_audit_brl_lock_windows(struct vfs_handle_struct *handle,
 					        struct byte_range_lock *br_lck,
 					        struct lock_struct *plock,
@@ -483,6 +485,8 @@ static vfs_op_tuple audit_op_tuples[] = {
 	 SMB_VFS_LAYER_LOGGER},
 	{SMB_VFS_OP(smb_full_audit_get_real_filename), SMB_VFS_OP_GET_REAL_FILENAME,
 	 SMB_VFS_LAYER_LOGGER},
+	{SMB_VFS_OP(smb_full_audit_connectpath), SMB_VFS_OP_CONNECTPATH,
+	 SMB_VFS_LAYER_LOGGER},
 	{SMB_VFS_OP(smb_full_audit_brl_lock_windows), SMB_VFS_OP_BRL_LOCK_WINDOWS,
 	 SMB_VFS_LAYER_LOGGER},
 	{SMB_VFS_OP(smb_full_audit_brl_unlock_windows), SMB_VFS_OP_BRL_UNLOCK_WINDOWS,
@@ -667,6 +671,7 @@ static struct {
 	{ SMB_VFS_OP_FILE_ID_CREATE,	"file_id_create" },
 	{ SMB_VFS_OP_STREAMINFO,	"streaminfo" },
 	{ SMB_VFS_OP_GET_REAL_FILENAME, "get_real_filename" },
+	{ SMB_VFS_OP_CONNECTPATH,	"connectpath" },
 	{ SMB_VFS_OP_BRL_LOCK_WINDOWS,  "brl_lock_windows" },
 	{ SMB_VFS_OP_BRL_UNLOCK_WINDOWS, "brl_unlock_windows" },
 	{ SMB_VFS_OP_BRL_CANCEL_WINDOWS, "brl_cancel_windows" },
@@ -1727,6 +1732,19 @@ static int smb_full_audit_get_real_filename(struct vfs_handle_struct *handle,
 	return result;
 }
 
+static const char *smb_full_audit_connectpath(vfs_handle_struct *handle,
+					      const char *fname)
+{
+	const char *result;
+
+	result = SMB_VFS_NEXT_CONNECTPATH(handle, fname);
+
+	do_log(SMB_VFS_OP_CONNECTPATH, result != NULL, handle,
+	       "%s", fname);
+
+	return result;
+}
+
 static NTSTATUS smb_full_audit_brl_lock_windows(struct vfs_handle_struct *handle,
 					        struct byte_range_lock *br_lck,
 					        struct lock_struct *plock,
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index acfac57..030d3e2 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -416,6 +416,59 @@ static char *shadow_copy2_realpath(vfs_handle_struct *handle,
         SHADOW2_NEXT(REALPATH, (handle, name, resolved_path), char *, NULL);
 }
 
+static const char *shadow_copy2_connectpath(struct vfs_handle_struct *handle,
+					    const char *fname)
+{
+	TALLOC_CTX *tmp_ctx = talloc_stackframe();
+	const char *snapdir, *baseoffset, *basedir;
+	size_t baselen;
+	char *ret;
+
+	if (!shadow_copy2_match_name(fname)) {
+		return handle->conn->connectpath;
+	}
+
+	snapdir = shadow_copy2_find_snapdir(tmp_ctx, handle);
+	if (snapdir == NULL) {
+		DEBUG(2,("no snapdir found for share at %s\n",
+			 handle->conn->connectpath));
+		TALLOC_FREE(tmp_ctx);
+		return NULL;
+	}
+
+	basedir = shadow_copy2_find_basedir(tmp_ctx, handle);
+	if (basedir == NULL) {
+		DEBUG(2,("no basedir found for share at %s\n",
+			 handle->conn->connectpath));
+		TALLOC_FREE(tmp_ctx);
+		return NULL;
+	}
+
+	baselen = strlen(basedir);
+	baseoffset = handle->conn->connectpath + baselen;
+
+	/* some sanity checks */
+	if (strncmp(basedir, handle->conn->connectpath, baselen) != 0 ||
+	    (handle->conn->connectpath[baselen] != 0
+	     && handle->conn->connectpath[baselen] != '/')) {
+		DEBUG(0,("shadow_copy2_connectpath: basedir %s is not a "
+			 "parent of %s\n", basedir,
+			 handle->conn->connectpath));
+		TALLOC_FREE(tmp_ctx);
+		return NULL;
+	}
+
+	if (*baseoffset == '/') baseoffset++;
+
+	ret = talloc_asprintf(talloc_tos(), "%s/%.*s/%s",
+			      snapdir,
+			      GMT_NAME_LEN, fname,
+			      baseoffset);
+	DEBUG(6,("shadow_copy2_connectpath: '%s' -> '%s'\n", fname, ret));
+	TALLOC_FREE(tmp_ctx);
+	return ret;
+}
+
 static NTSTATUS shadow_copy2_get_nt_acl(vfs_handle_struct *handle,
 			       const char *fname, uint32 security_info,
 			       struct security_descriptor **ppdesc)
@@ -592,6 +645,7 @@ static vfs_op_tuple shadow_copy2_ops[] = {
         {SMB_VFS_OP(shadow_copy2_link),       SMB_VFS_OP_LINK,     SMB_VFS_LAYER_TRANSPARENT},
         {SMB_VFS_OP(shadow_copy2_mknod),      SMB_VFS_OP_MKNOD,    SMB_VFS_LAYER_TRANSPARENT},
         {SMB_VFS_OP(shadow_copy2_realpath),   SMB_VFS_OP_REALPATH, SMB_VFS_LAYER_TRANSPARENT},
+        {SMB_VFS_OP(shadow_copy2_connectpath), SMB_VFS_OP_CONNECTPATH, SMB_VFS_LAYER_OPAQUE},
 
         /* NT File ACL operations */
         {SMB_VFS_OP(shadow_copy2_get_nt_acl), SMB_VFS_OP_GET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 0f70669..873e65e 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -871,7 +871,6 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
 	bool free_resolved_name = False;
 #endif
 	char *resolved_name = NULL;
-	size_t con_path_len = strlen(conn->connectpath);
 	char *p = NULL;
 
 	DEBUG(3,("reduce_name [%s] [%s]\n", fname, conn->connectpath));
@@ -957,12 +956,28 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
 	}
 
 	/* Check for widelinks allowed. */
-	if (!lp_widelinks(SNUM(conn)) && (strncmp(conn->connectpath, resolved_name, con_path_len) != 0)) {
-		DEBUG(2, ("reduce_name: Bad access attempt: %s is a symlink outside the share path", fname));
-		if (free_resolved_name) {
-			SAFE_FREE(resolved_name);
-		}
-		return NT_STATUS_ACCESS_DENIED;
+	if (!lp_widelinks(SNUM(conn))) {
+		    const char *conn_rootdir;
+
+		    conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
+		    if (conn_rootdir == NULL) {
+			    DEBUG(2, ("check_reduced_name: Could not get conn_rootdir\n"));
+			    if (free_resolved_name) {
+				    SAFE_FREE(resolved_name);
+			    }
+			    return NT_STATUS_ACCESS_DENIED;
+		    }
+
+		    if (strncmp(conn_rootdir, resolved_name,
+				strlen(conn_rootdir)) != 0) {
+			    DEBUG(2, ("reduce_name: Bad access attempt: %s is "
+				      "a symlink outside the share path",
+				      fname));
+			    if (free_resolved_name) {
+				    SAFE_FREE(resolved_name);
+			    }
+			    return NT_STATUS_ACCESS_DENIED;
+		    }
 	}
 
         /* Check if we are allowing users to follow symlinks */


-- 
Samba Shared Repository


More information about the samba-cvs mailing list