Third part of fix for bug #8663 - deleting a symlink fails if the symlink target...
authorJeremy Allison <jra@samba.org>
Fri, 16 Dec 2011 23:43:21 +0000 (15:43 -0800)
committerKarolin Seeger <kseeger@samba.org>
Mon, 5 Mar 2012 19:55:25 +0000 (20:55 +0100)
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 42bcd6abe3797e0d22c8404db5edd2b96fccac47)

source3/smbd/file_access.c
source3/smbd/open.c

index 8b669fecb8c1e4c45f42e41e48c009f3ea58eea3..69f89b87428f144630f559006c9bdda011933aa6 100644 (file)
@@ -40,6 +40,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,
                                    (OWNER_SECURITY_INFORMATION |
                                     GROUP_SECURITY_INFORMATION |
@@ -115,18 +122,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;
                }
 
index 693e488a4bc5435673842a21d72746fcadde087f..ded07a13761928aba862057b72e9a986563b181b 100644 (file)
@@ -96,6 +96,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,
                        (OWNER_SECURITY_INFORMATION |
                        GROUP_SECURITY_INFORMATION |