The Samba-Bugzilla – Attachment 5161 Details for
Bug 6876
Delete of an object whose parent folder does not have delete rights fails even if the delete right is set on the object
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
git-am format patch for 3.5.0.
0001-Fix-bug-6876-Delete-of-an-object-whose-parent-fol.patch (text/plain), 7.92 KB, created by
Jeremy Allison
on 2010-01-12 18:36:25 UTC
(
hide
)
Description:
git-am format patch for 3.5.0.
Filename:
MIME Type:
Creator:
Jeremy Allison
Created:
2010-01-12 18:36:25 UTC
Size:
7.92 KB
patch
obsolete
>From 2852eb30a800e8f3129f044245ca421d4476ca8c Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 12 Jan 2010 16:04:44 -0800 >Subject: [PATCH] Fix bug #6876 - Delete of an object whose parent folder does not have delete rights fails even if the delete right is set on the object. > >Final fix for the vfs_acl_xattr and vfs_acl_tdb code. >Ensure we can delete a file even if the underlying POSIX >permissions don't allow it, if the Windows permissions do. > >Jeremy. >(cherry picked from commit 47c1d9b39f292772e8d8f7a737ddff6c8bdfdeae) >--- > source3/include/smb.h | 1 + > source3/locking/locking.c | 3 + > source3/modules/vfs_acl_common.c | 127 ++++++++++++++++++++++++++++++++++++++ > source3/modules/vfs_acl_tdb.c | 3 +- > source3/modules/vfs_acl_xattr.c | 2 + > source3/smbd/close.c | 3 + > source3/smbd/posix_acls.c | 7 +- > 7 files changed, 142 insertions(+), 4 deletions(-) > >diff --git a/source3/include/smb.h b/source3/include/smb.h >index b23ea64..bc7a90d 100644 >--- a/source3/include/smb.h >+++ b/source3/include/smb.h >@@ -451,6 +451,7 @@ typedef struct files_struct { > bool aio_write_behind; > bool lockdb_clean; > bool initial_delete_on_close; /* Only set at NTCreateX if file was created. */ >+ bool delete_on_close; > bool posix_open; > struct smb_filename *fsp_name; > >diff --git a/source3/locking/locking.c b/source3/locking/locking.c >index 26018f9..095d0b1 100644 >--- a/source3/locking/locking.c >+++ b/source3/locking/locking.c >@@ -1459,6 +1459,9 @@ bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const UNIX_USE > } > > TALLOC_FREE(lck); >+ >+ fsp->delete_on_close = delete_on_close; >+ > return True; > } > >diff --git a/source3/modules/vfs_acl_common.c b/source3/modules/vfs_acl_common.c >index 1eec448..aeb9ce3 100644 >--- a/source3/modules/vfs_acl_common.c >+++ b/source3/modules/vfs_acl_common.c >@@ -760,6 +760,108 @@ static SMB_STRUCT_DIR *opendir_acl_common(vfs_handle_struct *handle, > return SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr); > } > >+static int acl_common_remove_object(vfs_handle_struct *handle, >+ const char *path, >+ bool is_directory) >+{ >+ connection_struct *conn = handle->conn; >+ struct file_id id; >+ files_struct *fsp = NULL; >+ int ret = 0; >+ char *parent_dir = NULL; >+ const char *final_component = NULL; >+ struct smb_filename local_fname; >+ int saved_errno = 0; >+ >+ if (!parent_dirname(talloc_tos(), path, >+ &parent_dir, &final_component)) { >+ saved_errno = ENOMEM; >+ goto out; >+ } >+ >+ DEBUG(10,("acl_common_remove_object: removing %s %s/%s\n", >+ is_directory ? "directory" : "file", >+ parent_dir, final_component )); >+ >+ /* cd into the parent dir to pin it. */ >+ ret = SMB_VFS_CHDIR(conn, parent_dir); >+ if (ret == -1) { >+ saved_errno = errno; >+ goto out; >+ } >+ >+ ZERO_STRUCT(local_fname); >+ local_fname.base_name = CONST_DISCARD(char *,final_component); >+ >+ /* Must use lstat here. */ >+ ret = SMB_VFS_LSTAT(conn, &local_fname); >+ if (ret == -1) { >+ saved_errno = errno; >+ goto out; >+ } >+ >+ /* Ensure we have this file open with DELETE access. */ >+ id = vfs_file_id_from_sbuf(conn, &local_fname.st); >+ for (fsp = file_find_di_first(id); fsp; file_find_di_next(fsp)) { >+ if (fsp->access_mask & DELETE_ACCESS && >+ fsp->delete_on_close) { >+ /* We did open this for delete, >+ * allow the delete as root. >+ */ >+ break; >+ } >+ } >+ >+ if (!fsp) { >+ DEBUG(10,("acl_common_remove_object: %s %s/%s " >+ "not an open file\n", >+ is_directory ? "directory" : "file", >+ parent_dir, final_component )); >+ saved_errno = EACCES; >+ goto out; >+ } >+ >+ if (is_directory) { >+ ret = SMB_VFS_NEXT_RMDIR(handle, final_component); >+ } else { >+ ret = SMB_VFS_NEXT_UNLINK(handle, &local_fname); >+ } >+ if (ret == -1) { >+ saved_errno = errno; >+ } >+ >+ out: >+ >+ TALLOC_FREE(parent_dir); >+ >+ vfs_ChDir(conn, conn->connectpath); >+ if (saved_errno) { >+ errno = saved_errno; >+ } >+ return ret; >+} >+ >+static int rmdir_acl_common(struct vfs_handle_struct *handle, >+ const char *path) >+{ >+ int ret; >+ >+ ret = SMB_VFS_NEXT_RMDIR(handle, path); >+ if (!(ret == -1 && (errno == EACCES || errno == EPERM))) { >+ DEBUG(10,("rmdir_acl_common: unlink of %s failed %s\n", >+ path, >+ strerror(errno) )); >+ return ret; >+ } >+ >+ become_root(); >+ ret = acl_common_remove_object(handle, >+ path, >+ true); >+ unbecome_root(); >+ return ret; >+} >+ > static NTSTATUS create_file_acl_common(struct vfs_handle_struct *handle, > struct smb_request *req, > uint16_t root_dir_fid, >@@ -857,3 +959,28 @@ static NTSTATUS create_file_acl_common(struct vfs_handle_struct *handle, > /* NOTREACHED */ > return status; > } >+ >+static int unlink_acl_common(struct vfs_handle_struct *handle, >+ const struct smb_filename *smb_fname) >+{ >+ int ret; >+ >+ ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname); >+ if (!(ret == -1 && (errno == EACCES || errno == EPERM))) { >+ DEBUG(10,("unlink_acl_common: unlink of %s failed %s\n", >+ smb_fname->base_name, >+ strerror(errno) )); >+ return ret; >+ } >+ /* Don't do anything fancy for streams. */ >+ if (smb_fname->stream_name) { >+ return ret; >+ } >+ >+ become_root(); >+ ret = acl_common_remove_object(handle, >+ smb_fname->base_name, >+ false); >+ unbecome_root(); >+ return ret; >+} >diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c >index a1088ab..2afe69d 100644 >--- a/source3/modules/vfs_acl_tdb.c >+++ b/source3/modules/vfs_acl_tdb.c >@@ -265,7 +265,7 @@ static int unlink_acl_tdb(vfs_handle_struct *handle, > goto out; > } > >- ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname_tmp); >+ ret = unlink_acl_common(handle, smb_fname_tmp); > > if (ret == -1) { > goto out; >@@ -413,6 +413,7 @@ static struct vfs_fn_pointers vfs_acl_tdb_fns = { > .connect_fn = connect_acl_tdb, > .opendir = opendir_acl_common, > .mkdir = mkdir_acl_common, >+ .rmdir = rmdir_acl_common, > .open = open_acl_common, > .create_file = create_file_acl_common, > .unlink = unlink_acl_tdb, >diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c >index 625ef91..18f2d42 100644 >--- a/source3/modules/vfs_acl_xattr.c >+++ b/source3/modules/vfs_acl_xattr.c >@@ -199,8 +199,10 @@ static struct vfs_fn_pointers vfs_acl_xattr_fns = { > .connect_fn = connect_acl_xattr, > .opendir = opendir_acl_common, > .mkdir = mkdir_acl_common, >+ .rmdir = rmdir_acl_common, > .open = open_acl_common, > .create_file = create_file_acl_common, >+ .unlink = unlink_acl_common, > .fget_nt_acl = fget_nt_acl_common, > .get_nt_acl = get_nt_acl_common, > .fset_nt_acl = fset_nt_acl_common, >diff --git a/source3/smbd/close.c b/source3/smbd/close.c >index 05c3c70..e81a2fd 100644 >--- a/source3/smbd/close.c >+++ b/source3/smbd/close.c >@@ -336,6 +336,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, > become_user(conn, fsp->vuid); > became_user = True; > } >+ fsp->delete_on_close = true; > set_delete_on_close_lck(lck, True, ¤t_user.ut); > if (became_user) { > unbecome_user(); >@@ -481,6 +482,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, > * the delete on close flag. JRA. > */ > >+ fsp->delete_on_close = false; > set_delete_on_close_lck(lck, False, NULL); > > done: >@@ -958,6 +960,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, > } > send_stat_cache_delete_message(fsp->fsp_name->base_name); > set_delete_on_close_lck(lck, True, ¤t_user.ut); >+ fsp->delete_on_close = true; > if (became_user) { > unbecome_user(); > } >diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c >index 8d66bf1..7342420 100644 >--- a/source3/smbd/posix_acls.c >+++ b/source3/smbd/posix_acls.c >@@ -1107,9 +1107,10 @@ uint32_t map_canon_ace_perms(int snum, > nt_mask |= ((perms & S_IWUSR) ? UNIX_ACCESS_W : 0 ); > nt_mask |= ((perms & S_IXUSR) ? UNIX_ACCESS_X : 0 ); > } >- if ((perms & S_IWUSR) && lp_dos_filemode(snum)) { >- nt_mask |= (SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER); >- } >+ } >+ >+ if ((perms & S_IWUSR) && lp_dos_filemode(snum)) { >+ nt_mask |= (SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER|DELETE_ACCESS); > } > > DEBUG(10,("map_canon_ace_perms: Mapped (UNIX) %x to (NT) %x\n", >-- >1.5.4.3 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
vl
:
review+
Actions:
View
Attachments on
bug 6876
:
5153
| 5161 |
5200
|
5299