From e68f6adca9494166bf7c24c358ea1af718970b0d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 7 Feb 2011 20:46:36 -0800 Subject: If possible (O_DIRECTORY exists) open an fd for a directory open. 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 Autobuild-Date: Tue Feb 8 06:34:41 CET 2011 on sn-devel-104 --- source3/modules/nfs4_acls.c | 2 +- source3/modules/vfs_afsacl.c | 2 +- source3/smbd/open.c | 15 +++++++++++++++ source3/smbd/smb2_getinfo.c | 2 +- source3/smbd/smb2_setinfo.c | 2 +- source3/smbd/trans2.c | 16 ++++------------ source3/smbd/vfs.c | 4 ++-- 7 files changed, 25 insertions(+), 18 deletions(-) diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c index 6e6b015f07..952bc9c6c1 100644 --- a/source3/modules/nfs4_acls.c +++ b/source3/modules/nfs4_acls.c @@ -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); } diff --git a/source3/modules/vfs_afsacl.c b/source3/modules/vfs_afsacl.c index 8e61351a1a..df4a20a90b 100644 --- a/source3/modules/vfs_afsacl.c +++ b/source3/modules/vfs_afsacl.c @@ -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); diff --git a/source3/smbd/open.c b/source3/smbd/open.c index e6a70bcebc..ded3d344c5 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -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; } diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index 5f5cd02fe7..123531c351 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -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 diff --git a/source3/smbd/smb2_setinfo.c b/source3/smbd/smb2_setinfo.c index 4b837c13b3..9afb487dce 100644 --- a/source3/smbd/smb2_setinfo.c +++ b/source3/smbd/smb2_setinfo.c @@ -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 diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 5865d05e44..2ce1fd746a 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -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, diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 9e44d02e15..32be699ef8 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -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) { -- cgit