Fix bug 6769 - symlink unlink does nothing. Jeremy.
authorJeremy Allison <jra@samba.org>
Thu, 8 Oct 2009 23:40:26 +0000 (16:40 -0700)
committerKarolin Seeger <kseeger@samba.org>
Tue, 20 Oct 2009 13:00:27 +0000 (15:00 +0200)
(cherry picked from commit 9f7d155001bc4c2808b6d17e9cb5ce87173b6061)

source3/modules/vfs_default.c
source3/smbd/posix_acls.c
source3/smbd/reply.c

index 0a66531efe15ac98aa48fd8579d6cecacd327fd2..ca401b694a1cd85adb887e580d43f3080c2837fe 100644 (file)
@@ -1130,7 +1130,11 @@ static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle,
                ret = SMB_VFS_FSTAT(fsp, &sbuf);
        }
        else {
-               ret = SMB_VFS_STAT(handle->conn, fname, &sbuf);
+               if (lp_posix_pathnames()) {
+                       ret = SMB_VFS_LSTAT(handle->conn, fname, &sbuf);
+               } else {
+                       ret = SMB_VFS_STAT(handle->conn, fname, &sbuf);
+               }
        }
 
        if (ret == -1) {
index 53bfaa16184d545989b8c9f89cc1e358aa343541..766c7b0e65164a04000c225e8239f10505b07345 100644 (file)
@@ -3341,13 +3341,19 @@ NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name,
        SMB_ACL_T posix_acl = NULL;
        SMB_ACL_T def_acl = NULL;
        struct pai_val *pal;
+       int ret;
 
        *ppdesc = NULL;
 
        DEBUG(10,("posix_get_nt_acl: called for file %s\n", name ));
 
        /* Get the stat struct for the owner info. */
-       if(SMB_VFS_STAT(conn, name, &sbuf) != 0) {
+       if (lp_posix_pathnames()) {
+               ret = SMB_VFS_LSTAT(conn, name, &sbuf);
+       } else {
+               ret = SMB_VFS_STAT(conn, name, &sbuf);
+       }
+       if(ret != 0) {
                return map_nt_error_from_unix(errno);
        }
 
@@ -3381,6 +3387,7 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid)
        int ret;
        files_struct *fsp;
        SMB_STRUCT_STAT st;
+       bool posix_paths = lp_posix_pathnames();
 
        if(!CAN_WRITE(conn)) {
                return -1;
@@ -3388,7 +3395,11 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid)
 
        /* Case (1). */
        /* try the direct way first */
-       ret = SMB_VFS_CHOWN(conn, fname, uid, gid);
+       if (posix_paths) {
+               ret = SMB_VFS_LCHOWN(conn, fname, uid, gid);
+       } else {
+               ret = SMB_VFS_CHOWN(conn, fname, uid, gid);
+       }
        if (ret == 0)
                return 0;
 
@@ -3428,7 +3439,12 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid)
                return -1;
        }
 
-       if (SMB_VFS_STAT(conn,fname,&st)) {
+       if (posix_paths) {
+               ret = SMB_VFS_LSTAT(conn,fname,&st);
+       } else {
+               ret = SMB_VFS_STAT(conn,fname,&st);
+       }
+       if (ret != 0) {
                return -1;
        }
 
@@ -3664,6 +3680,8 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
        bool set_acl_as_root = false;
        bool acl_set_support = false;
        bool ret = false;
+       bool posix_paths = lp_posix_pathnames();
+       int sret;
 
        DEBUG(10,("set_nt_acl: called for file %s\n", fsp->fsp_name ));
 
@@ -3677,8 +3695,14 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
         */
 
        if(fsp->is_directory || fsp->fh->fd == -1) {
-               if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0)
+               if (posix_paths) {
+                       sret = SMB_VFS_LSTAT(fsp->conn,fsp->fsp_name, &sbuf);
+               } else {
+                       sret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf);
+               }
+               if (sret != 0) {
                        return map_nt_error_from_unix(errno);
+               }
        } else {
                if(SMB_VFS_FSTAT(fsp, &sbuf) != 0)
                        return map_nt_error_from_unix(errno);
@@ -3722,17 +3746,24 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
                 */
 
                if(fsp->is_directory) {
-                       if(SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf) != 0) {
+                       if (posix_paths) {
+                               sret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name, &sbuf);
+                       } else {
+                               sret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf);
+                       }
+                       if (sret != 0) {
                                return map_nt_error_from_unix(errno);
                        }
                } else {
-
-                       int sret;
-
-                       if(fsp->fh->fd == -1)
-                               sret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf);
-                       else
+                       if(fsp->fh->fd == -1) {
+                               if (posix_paths) {
+                                       sret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name, &sbuf);
+                               } else {
+                                       sret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf);
+                               }
+                       } else {
                                sret = SMB_VFS_FSTAT(fsp, &sbuf);
+                       }
 
                        if(sret != 0)
                                return map_nt_error_from_unix(errno);
@@ -3811,8 +3842,6 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
                                return map_nt_error_from_unix(errno);
                        }
                } else {
-                       int sret = -1;
-
                        /*
                         * No default ACL - delete one if it exists.
                         */
@@ -3874,8 +3903,6 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
                }
 
                if (orig_mode != posix_perms) {
-                       int sret = -1;
-
                        DEBUG(3,("set_nt_acl: chmod %s. perms = 0%o.\n",
                                fsp->fsp_name, (unsigned int)posix_perms ));
 
index 285056c6d944edfa16114da69a0f4c111d4336af..acd84d689de1c13fef4897b35275ae20c8e6e868 100644 (file)
@@ -918,10 +918,19 @@ void reply_checkpath(struct smb_request *req)
                goto path_err;
        }
 
-       if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn,name,&sbuf) != 0)) {
-               DEBUG(3,("reply_checkpath: stat of %s failed (%s)\n",name,strerror(errno)));
-               status = map_nt_error_from_unix(errno);
-               goto path_err;
+       if (!VALID_STAT(sbuf)) {
+               int ret;
+
+               if (lp_posix_pathnames()) {
+                       ret = SMB_VFS_LSTAT(conn,name,&sbuf);
+               } else {
+                       ret = SMB_VFS_STAT(conn,name,&sbuf);
+               }
+               if (ret != 0) {
+                       DEBUG(3,("reply_checkpath: stat of %s failed (%s)\n",name,strerror(errno)));
+                       status = map_nt_error_from_unix(errno);
+                       goto path_err;
+               }
        }
 
        if (!S_ISDIR(sbuf.st_mode)) {
@@ -1027,11 +1036,20 @@ void reply_getatr(struct smb_request *req)
                        END_PROFILE(SMBgetatr);
                        return;
                }
-               if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn,fname,&sbuf) != 0)) {
-                       DEBUG(3,("reply_getatr: stat of %s failed (%s)\n",fname,strerror(errno)));
-                       reply_unixerror(req, ERRDOS,ERRbadfile);
-                       END_PROFILE(SMBgetatr);
-                       return;
+               if (!VALID_STAT(sbuf)) {
+                       int ret;
+
+                       if (lp_posix_pathnames()) {
+                               ret = SMB_VFS_LSTAT(conn,fname,&sbuf);
+                       } else {
+                               ret = SMB_VFS_STAT(conn,fname,&sbuf);
+                       }
+                       if (ret != 0) {
+                               DEBUG(3,("reply_getatr: stat of %s failed (%s)\n",fname,strerror(errno)));
+                               reply_unixerror(req, ERRDOS,ERRbadfile);
+                               END_PROFILE(SMBgetatr);
+                               return;
+                       }
                }
 
                mode = dos_mode(conn,fname,&sbuf);
@@ -2260,6 +2278,8 @@ static NTSTATUS do_unlink(connection_struct *conn,
        uint32 fattr;
        files_struct *fsp;
        uint32 dirtype_orig = dirtype;
+       bool posix_paths = lp_posix_pathnames();
+       int ret;
        NTSTATUS status;
 
        DEBUG(10,("do_unlink: %s, dirtype = %d\n", fname, dirtype ));
@@ -2268,7 +2288,12 @@ static NTSTATUS do_unlink(connection_struct *conn,
                return NT_STATUS_MEDIA_WRITE_PROTECTED;
        }
 
-       if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0) {
+       if (posix_paths) {
+               ret = SMB_VFS_LSTAT(conn,fname,&sbuf);
+       } else {
+               ret = SMB_VFS_STAT(conn,fname,&sbuf);
+       }
+       if (ret != 0) {
                return map_nt_error_from_unix(errno);
        }
 
@@ -2356,7 +2381,9 @@ static NTSTATUS do_unlink(connection_struct *conn,
                 FILE_SHARE_NONE,       /* share_access */
                 FILE_OPEN,             /* create_disposition*/
                 FILE_NON_DIRECTORY_FILE, /* create_options */
-                FILE_ATTRIBUTE_NORMAL, /* file_attributes */
+                                       /* file_attributes */
+                posix_paths ? FILE_FLAG_POSIX_SEMANTICS|0777 :
+                               FILE_ATTRIBUTE_NORMAL,
                 0,                     /* oplock_request */
                 0,                     /* allocation_size */
                 NULL,                  /* sd */