fd support routines - attempt to do a dos_open.
****************************************************************************/
-NTSTATUS fd_open(struct connection_struct *conn,
- files_struct *fsp,
+NTSTATUS fd_open(files_struct *fsp,
int flags,
mode_t mode)
{
+ struct connection_struct *conn = fsp->conn;
struct smb_filename *smb_fname = fsp->fsp_name;
NTSTATUS status = NT_STATUS_OK;
int saved_errno = 0;
file was created or not.
****************************************************************************/
-static NTSTATUS fd_open_atomic(struct connection_struct *conn,
- files_struct *fsp,
- int flags,
- mode_t mode,
- bool *file_created)
+static NTSTATUS fd_open_atomic(files_struct *fsp,
+ int flags,
+ mode_t mode,
+ bool *file_created)
{
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
NTSTATUS retry_status;
/*
* We're not creating the file, just pass through.
*/
- status = fd_open(conn, fsp, flags, mode);
+ status = fd_open(fsp, flags, mode);
*file_created = false;
return status;
}
/*
* Fail if already exists, just pass through.
*/
- status = fd_open(conn, fsp, flags, mode);
+ status = fd_open(fsp, flags, mode);
/*
* Here we've opened with O_CREAT|O_EXCL. If that went
retry_status = NT_STATUS_OBJECT_NAME_COLLISION;
}
- status = fd_open(conn, fsp, curr_flags, mode);
+ status = fd_open(fsp, curr_flags, mode);
if (NT_STATUS_IS_OK(status)) {
*file_created = !file_existed;
return NT_STATUS_OK;
curr_flags = flags | O_EXCL;
}
- status = fd_open(conn, fsp, curr_flags, mode);
+ status = fd_open(fsp, curr_flags, mode);
}
*file_created = (NT_STATUS_IS_OK(status) && !file_existed);
****************************************************************************/
static NTSTATUS open_file(files_struct *fsp,
- connection_struct *conn,
struct smb_request *req,
struct smb_filename *parent_dir,
int flags,
uint32_t open_access_mask, /* what we're actually using in the open. */
bool *p_file_created)
{
+ connection_struct *conn = fsp->conn;
struct smb_filename *smb_fname = fsp->fsp_name;
NTSTATUS status = NT_STATUS_OK;
int accmode = (flags & O_ACCMODE);
* Actually do the open - if O_TRUNC is needed handle it
* below under the share mode lock.
*/
- status = fd_open_atomic(conn, fsp, local_flags & ~O_TRUNC,
- unx_mode, p_file_created);
+ status = fd_open_atomic(fsp,
+ local_flags & ~O_TRUNC,
+ unx_mode,
+ p_file_created);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
"(flags=%d)\n", smb_fname_str_dbg(smb_fname),
bool setup_poll = false;
bool ok;
+ SMB_ASSERT(fsp->dirfsp == conn->cwd_fsp);
+
if (conn->printer) {
/*
* Printers are handled completely differently.
(unsigned int)unx_mode, (unsigned int)access_mask,
(unsigned int)open_access_mask));
- fsp_open = open_file(fsp, conn, req, parent_dir_fname,
- flags|flags2, unx_mode, access_mask,
- open_access_mask, &new_file_created);
-
+ fsp_open = open_file(fsp,
+ req,
+ parent_dir_fname,
+ flags|flags2,
+ unx_mode,
+ access_mask,
+ open_access_mask,
+ &new_file_created);
if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_NETWORK_BUSY)) {
if (file_existed && S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
DEBUG(10, ("FIFO busy\n"));
}
static NTSTATUS mkdir_internal(connection_struct *conn,
+ struct files_struct **dirfsp,
struct smb_filename *smb_dname,
uint32_t file_attributes)
{
int ret;
bool ok;
+ SMB_ASSERT(*dirfsp == conn->cwd_fsp);
+
if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
DEBUG(5,("mkdir_internal: failing share access "
"%s\n", lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
}
status = check_parent_access(conn,
- conn->cwd_fsp,
- smb_dname,
- access_mask);
+ *dirfsp,
+ smb_dname,
+ access_mask);
if(!NT_STATUS_IS_OK(status)) {
DEBUG(5,("mkdir_internal: check_parent_access "
"on directory %s for path %s returned %s\n",
}
ret = SMB_VFS_MKDIRAT(conn,
- conn->cwd_fsp,
- smb_dname,
- mode);
+ *dirfsp,
+ smb_dname,
+ mode);
if (ret != 0) {
return map_nt_error_from_unix(errno);
}
static NTSTATUS open_directory(connection_struct *conn,
struct smb_request *req,
+ struct files_struct **dirfsp,
struct smb_filename *smb_dname,
uint32_t access_mask,
uint32_t share_access,
int flags;
bool ok;
+ SMB_ASSERT(*dirfsp == conn->cwd_fsp);
+
if (is_ntfs_stream_smb_fname(smb_dname)) {
DEBUG(2, ("open_directory: %s is a stream name!\n",
smb_fname_str_dbg(smb_dname)));
file_attributes);
status = smbd_calculate_access_mask(conn,
- conn->cwd_fsp,
+ *dirfsp,
smb_dname,
false,
access_mask,
return status;
}
- status = mkdir_internal(conn, smb_dname,
+ status = mkdir_internal(conn, dirfsp, smb_dname,
file_attributes);
if (!NT_STATUS_IS_OK(status)) {
status = NT_STATUS_OK;
info = FILE_WAS_OPENED;
} else {
- status = mkdir_internal(conn, smb_dname,
+ status = mkdir_internal(conn, dirfsp, smb_dname,
file_attributes);
if (NT_STATUS_IS_OK(status)) {
if (info == FILE_WAS_OPENED) {
status = smbd_check_access_rights(conn,
- conn->cwd_fsp,
+ *dirfsp,
smb_dname,
false,
access_mask);
return status;
}
+ if (*dirfsp == fsp->conn->cwd_fsp) {
+ fsp->dirfsp = fsp->conn->cwd_fsp;
+ } else {
+ fsp->dirfsp = talloc_move(fsp, dirfsp);
+ }
+
/* Don't store old timestamps for directory
handles in the internal database. We don't
update them in there if new objects
flags |= O_DIRECTORY;
#endif
- status = fd_open(conn, fsp, flags, 0);
+ status = fd_open(fsp, flags, 0);
if (!NT_STATUS_IS_OK(status)) {
DBG_INFO("Could not open fd for "
"%s (%s)\n",
static NTSTATUS create_file_unixpath(connection_struct *conn,
struct smb_request *req,
+ struct files_struct **dirfsp,
struct smb_filename *smb_fname,
uint32_t access_mask,
uint32_t share_access,
files_struct *fsp = NULL;
NTSTATUS status;
+ SMB_ASSERT(*dirfsp == conn->cwd_fsp);
+
DBG_DEBUG("create_file_unixpath: access_mask = 0x%x "
"file_attributes = 0x%x, share_access = 0x%x, "
"create_disposition = 0x%x create_options = 0x%x "
base_privflags = NTCREATEX_OPTIONS_PRIVATE_STREAM_BASEOPEN;
/* Open the base file. */
- status = create_file_unixpath(conn, NULL, smb_fname_base, 0,
+ status = create_file_unixpath(conn,
+ NULL,
+ dirfsp,
+ smb_fname_base,
+ 0,
FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE,
base_create_disposition,
- 0, 0, 0, NULL, 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ 0,
base_privflags,
- NULL, NULL,
- &base_fsp, NULL);
+ NULL,
+ NULL,
+ &base_fsp,
+ NULL);
TALLOC_FREE(smb_fname_base);
if (!NT_STATUS_IS_OK(status)) {
*/
oplock_request = 0;
- status = open_directory(
- conn, req, smb_fname, access_mask, share_access,
- create_disposition, create_options, file_attributes,
- &info, &fsp);
+ status = open_directory(conn,
+ req,
+ dirfsp,
+ smb_fname,
+ access_mask,
+ share_access,
+ create_disposition,
+ create_options,
+ file_attributes,
+ &info,
+ &fsp);
} else {
/*
goto fail;
}
+ if (*dirfsp == fsp->conn->cwd_fsp) {
+ fsp->dirfsp = fsp->conn->cwd_fsp;
+ } else {
+ fsp->dirfsp = talloc_move(fsp, dirfsp);
+ }
+
if (base_fsp) {
/*
* We're opening the stream element of a
}
oplock_request = 0;
- status = open_directory(
- conn, req, smb_fname, access_mask,
- share_access, create_disposition,
- create_options, file_attributes,
- &info, &fsp);
+ status = open_directory(conn,
+ req,
+ dirfsp,
+ smb_fname,
+ access_mask,
+ share_access,
+ create_disposition,
+ create_options,
+ file_attributes,
+ &info,
+ &fsp);
}
}
file_attributes = (FILE_FLAG_POSIX_SEMANTICS | mode_bits);
}
- status = create_file_unixpath(
- conn, req, smb_fname, access_mask, share_access,
- create_disposition, create_options, file_attributes,
- oplock_request, lease, allocation_size, private_flags,
- sd, ea_list,
- &fsp, &info);
-
+ status = create_file_unixpath(conn,
+ req,
+ _dirfsp,
+ smb_fname,
+ access_mask,
+ share_access,
+ create_disposition,
+ create_options,
+ file_attributes,
+ oplock_request,
+ lease,
+ allocation_size,
+ private_flags,
+ sd,
+ ea_list,
+ &fsp,
+ &info);
if (!NT_STATUS_IS_OK(status)) {
goto fail;
}