diff options
-rw-r--r-- | source3/include/vfs.h | 5 | ||||
-rw-r--r-- | source3/include/vfs_macros.h | 3 | ||||
-rw-r--r-- | source3/modules/vfs_default.c | 8 | ||||
-rw-r--r-- | source3/modules/vfs_full_audit.c | 18 | ||||
-rw-r--r-- | source3/smbd/vfs.c | 30 |
5 files changed, 56 insertions, 8 deletions
diff --git a/source3/include/vfs.h b/source3/include/vfs.h index 0c0e0938bd..9a736a7ca0 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 acb158e3a5..0b59f8f3ad 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 fe63d5001a..4368dcd7da 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 ebe89ec5fd..bbcb7b3364 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/smbd/vfs.c b/source3/smbd/vfs.c index bc6fd18b8e..873e65e4a4 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -956,14 +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, - strlen(conn->connectpath)) != 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 */ |