If possible (O_DIRECTORY exists) open an fd for a directory open.
authorJeremy Allison <jra@samba.org>
Tue, 8 Feb 2011 04:46:36 +0000 (20:46 -0800)
committerJeremy Allison <jra@samba.org>
Tue, 8 Feb 2011 05:34:41 +0000 (06:34 +0100)
Start of the move towards handle-based code for directory access.
Currently makes fstat/fchown code work for directories rather than
falling back to pathnames.

Jeremy.

Autobuild-User: Jeremy Allison <jra@samba.org>
Autobuild-Date: Tue Feb  8 06:34:41 CET 2011 on sn-devel-104

source3/modules/nfs4_acls.c
source3/modules/vfs_afsacl.c
source3/smbd/open.c
source3/smbd/smb2_getinfo.c
source3/smbd/smb2_setinfo.c
source3/smbd/trans2.c
source3/smbd/vfs.c

index 6e6b015f0701e8d025baf94a0121f08bb7c4ea37..952bc9c6c1beae1faafd639dffea680e3fe388a9 100644 (file)
@@ -186,7 +186,7 @@ static int smbacl4_fGetFileOwner(files_struct *fsp, SMB_STRUCT_STAT *psbuf)
 {
        memset(psbuf, 0, sizeof(SMB_STRUCT_STAT));
 
-       if (fsp->is_directory || fsp->fh->fd == -1) {
+       if (fsp->fh->fd == -1) {
                return smbacl4_GetFileOwner(fsp->conn,
                                            fsp->fsp_name->base_name, psbuf);
        }
index 8e61351a1a4b83143ee1ce9666e54b0d6cf98f78..df4a20a90bcf85654d86e34037d3edb7e6328f78 100644 (file)
@@ -682,7 +682,7 @@ static size_t afs_fto_nt_acl(struct afs_acl *afs_acl,
 {
        SMB_STRUCT_STAT sbuf;
 
-       if (fsp->is_directory || fsp->fh->fd == -1) {
+       if (fsp->fh->fd == -1) {
                /* Get the stat struct for the owner info. */
                return afs_to_nt_acl(afs_acl, fsp->conn, fsp->fsp_name,
                                     security_info, ppdesc);
index e6a70bcebc390f7a6ae5af84190df75d49c70dea..ded3d344c55e4488596c19927cb1b7389023b295 100644 (file)
@@ -2726,12 +2726,25 @@ static NTSTATUS open_directory(connection_struct *conn,
 
        mtimespec = smb_dname->st.st_ex_mtime;
 
+#ifdef O_DIRECTORY
+       status = fd_open(conn, fsp, O_RDONLY|O_DIRECTORY, 0);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(5, ("open_directory: Could not open fd for "
+                       "%s (%s)\n",
+                       smb_fname_str_dbg(smb_dname),
+                       nt_errstr(status)));
+               file_free(req, fsp);
+               return status;
+       }
+#endif
+
        lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
                                  conn->connectpath, smb_dname, &mtimespec);
 
        if (lck == NULL) {
                DEBUG(0, ("open_directory: Could not get share mode lock for "
                          "%s\n", smb_fname_str_dbg(smb_dname)));
+               fd_close(fsp);
                file_free(req, fsp);
                return NT_STATUS_SHARING_VIOLATION;
        }
@@ -2742,6 +2755,7 @@ static NTSTATUS open_directory(connection_struct *conn,
 
        if (!NT_STATUS_IS_OK(status)) {
                TALLOC_FREE(lck);
+               fd_close(fsp);
                file_free(req, fsp);
                return status;
        }
@@ -2754,6 +2768,7 @@ static NTSTATUS open_directory(connection_struct *conn,
                status = can_set_delete_on_close(fsp, 0);
                if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
                        TALLOC_FREE(lck);
+                       fd_close(fsp);
                        file_free(req, fsp);
                        return status;
                }
index 5f5cd02fe761ba03531b7130bfbc4a1247c0f427..123531c3511a070038e1df69511b51892fa89920 100644 (file)
@@ -321,7 +321,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
 
                        /* We know this name is ok, it's already passed the checks. */
 
-               } else if (fsp && (fsp->is_directory || fsp->fh->fd == -1)) {
+               } else if (fsp && fsp->fh->fd == -1) {
                        /*
                         * This is actually a QFILEINFO on a directory
                         * handle (returned from an NT SMB). NT5.0 seems
index 4b837c13b32489a932da2b0656db3d281747e4ec..9afb487dce375100ae11e3a1eaaf6ea483cf16aa 100644 (file)
@@ -218,7 +218,7 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx,
                        file_info_level = SMB2_FILE_RENAME_INFORMATION_INTERNAL;
                }
 
-               if (fsp->is_directory || fsp->fh->fd == -1) {
+               if (fsp->fh->fd == -1) {
                        /*
                         * This is actually a SETFILEINFO on a directory
                         * handle (returned from an NT SMB). NT5.0 seems
index 5865d05e44fe5d326bbbd6984d6e9def15f37f75..2ce1fd746aef747ef044506a5484ded514d0942e 100644 (file)
@@ -4827,7 +4827,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
                                uint16 num_file_acls = 0;
                                uint16 num_def_acls = 0;
 
-                               if (fsp && !fsp->is_directory && (fsp->fh->fd != -1)) {
+                               if (fsp && fsp->fh->fd != -1) {
                                        file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp);
                                } else {
                                        file_acl =
@@ -4920,7 +4920,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
                        enum brl_type lock_type;
 
                        /* We need an open file with a real fd for this. */
-                       if (!fsp || fsp->is_directory || fsp->fh->fd == -1) {
+                       if (!fsp || fsp->fh->fd == -1) {
                                return NT_STATUS_INVALID_LEVEL;
                        }
 
@@ -5073,7 +5073,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
 
                        /* We know this name is ok, it's already passed the checks. */
 
-               } else if(fsp->is_directory || fsp->fh->fd == -1) {
+               } else if(fsp->fh->fd == -1) {
                        /*
                         * This is actually a QFILEINFO on a directory
                         * handle (returned from an NT SMB). NT5.0 seems
@@ -5108,10 +5108,6 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
                        /*
                         * Original code - this is an open file.
                         */
-                       if (!check_fsp(conn, req, fsp)) {
-                               return;
-                       }
-
                        if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
                                DEBUG(3, ("fstat of fnum %d failed (%s)\n",
                                          fsp->fnum, strerror(errno)));
@@ -7885,7 +7881,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
                        return;
                }
 
-               if(fsp->is_directory || fsp->fh->fd == -1) {
+               if(fsp->fh->fd == -1) {
                        /*
                         * This is actually a SETFILEINFO on a directory
                         * handle (returned from an NT SMB). NT5.0 seems
@@ -7937,10 +7933,6 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
                        /*
                         * Original code - this is an open file.
                         */
-                       if (!check_fsp(conn, req, fsp)) {
-                               return;
-                       }
-
                        if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
                                DEBUG(3,("call_trans2setfilepathinfo: fstat "
                                         "of fnum %d failed (%s)\n", fsp->fnum,
index 9e44d02e15c42368b2177d291c246c12b80177b6..32be699ef86e83cf95671ad80faab76e02903cdd 100644 (file)
@@ -1105,7 +1105,7 @@ NTSTATUS vfs_stat_fsp(files_struct *fsp)
 {
        int ret;
 
-       if(fsp->is_directory || fsp->fh->fd == -1) {
+       if(fsp->fh->fd == -1) {
                if (fsp->posix_open) {
                        ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
                } else {
@@ -1443,7 +1443,7 @@ NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
 {
        int ret;
 
-       if (!fsp->is_directory && fsp->fh->fd != -1) {
+       if (fsp->fh->fd != -1) {
                /* Try fchown. */
                ret = SMB_VFS_FCHOWN(fsp, uid, gid);
                if (ret == 0) {