diff options
author | Jeremy Allison <jra@samba.org> | 2011-12-16 15:50:58 -0800 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2012-01-23 21:30:27 +0100 |
commit | f6a6b15efcd6ff3befec2fd3780d7a35178b6dc1 (patch) | |
tree | d5982e9f3163be8f21b46bcc8aa631248c10c17d | |
parent | b0099de477a8f507e17e6221db8da4ca44a37294 (diff) | |
download | samba-f6a6b15efcd6ff3befec2fd3780d7a35178b6dc1.tar.gz |
Third part of fix for bug #8663 - deleting a symlink fails if the symlink target is outside of the share.
can_access_file_acl() - we can always delete a symlink.
can_delete_file_in_directory() - We don't need to do another STAT call
here, we know smb_fname->st is in a valid state.
smbd_check_open_rights() - we can always delete a symlink.
(cherry picked from commit c6bd2aa768ebf4308c53d057bc1db7adc2b67705)
-rw-r--r-- | source3/smbd/file_access.c | 23 | ||||
-rw-r--r-- | source3/smbd/open.c | 10 |
2 files changed, 21 insertions, 12 deletions
diff --git a/source3/smbd/file_access.c b/source3/smbd/file_access.c index 74855649ea2..9f95d68cf37 100644 --- a/source3/smbd/file_access.c +++ b/source3/smbd/file_access.c @@ -44,6 +44,13 @@ bool can_access_file_acl(struct connection_struct *conn, return true; } + if (access_mask == DELETE_ACCESS && + VALID_STAT(smb_fname->st) && + S_ISLNK(smb_fname->st.st_ex_mode)) { + /* We can always delete a symlink. */ + return true; + } + status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name, (SECINFO_OWNER | SECINFO_GROUP | @@ -130,18 +137,10 @@ bool can_delete_file_in_directory(connection_struct *conn, /* sticky bit means delete only by owner of file or by root or * by owner of directory. */ if (smb_fname_parent->st.st_ex_mode & S_ISVTX) { - if(SMB_VFS_STAT(conn, smb_fname) != 0) { - if (errno == ENOENT) { - /* If the file doesn't already exist then - * yes we'll be able to delete it. */ - ret = true; - goto out; - } - DEBUG(10,("can_delete_file_in_directory: can't " - "stat file %s (%s)", - smb_fname_str_dbg(smb_fname), - strerror(errno) )); - ret = false; + if (!VALID_STAT(smb_fname->st)) { + /* If the file doesn't already exist then + * yes we'll be able to delete it. */ + ret = true; goto out; } diff --git a/source3/smbd/open.c b/source3/smbd/open.c index ab54f28c352..ce86b4caf2e 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -95,6 +95,16 @@ NTSTATUS smbd_check_open_rights(struct connection_struct *conn, return NT_STATUS_OK; } + if (access_mask == DELETE_ACCESS && + VALID_STAT(smb_fname->st) && + S_ISLNK(smb_fname->st.st_ex_mode)) { + /* We can always delete a symlink. */ + DEBUG(10,("smbd_check_open_rights: not checking ACL " + "on DELETE_ACCESS on symlink %s.\n", + smb_fname_str_dbg(smb_fname) )); + return NT_STATUS_OK; + } + status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name, (SECINFO_OWNER | SECINFO_GROUP | |