mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
s3: No code change, just re-indent
Look at this with "git diff -b" if you don't believe me :-)
This commit is contained in:
parent
173e808ed4
commit
64c4940039
@ -1940,6 +1940,12 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
|
||||
NTSTATUS status;
|
||||
char *parent_dir;
|
||||
SMB_STRUCT_STAT saved_stat = smb_fname->st;
|
||||
struct share_mode_entry *batch_entry = NULL;
|
||||
struct share_mode_entry *exclusive_entry = NULL;
|
||||
bool got_level2_oplock = false;
|
||||
bool got_a_none_oplock = false;
|
||||
struct timespec old_write_time;
|
||||
struct file_id id;
|
||||
|
||||
if (conn->printer) {
|
||||
/*
|
||||
@ -2265,226 +2271,219 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
{
|
||||
struct share_mode_entry *batch_entry = NULL;
|
||||
struct share_mode_entry *exclusive_entry = NULL;
|
||||
bool got_level2_oplock = false;
|
||||
bool got_a_none_oplock = false;
|
||||
struct timespec old_write_time = smb_fname->st.st_ex_mtime;
|
||||
struct file_id id;
|
||||
/*
|
||||
* Deal with the race condition where two smbd's detect the
|
||||
* file doesn't exist and do the create at the same time. One
|
||||
* of them will win and set a share mode, the other (ie. this
|
||||
* one) should check if the requested share mode for this
|
||||
* create is allowed.
|
||||
*/
|
||||
old_write_time = smb_fname->st.st_ex_mtime;
|
||||
|
||||
/*
|
||||
* Now the file exists and fsp is successfully opened,
|
||||
* fsp->dev and fsp->inode are valid and should replace the
|
||||
* dev=0,inode=0 from a non existent file. Spotted by
|
||||
* Nadav Danieli <nadavd@exanet.com>. JRA.
|
||||
*/
|
||||
/*
|
||||
* Deal with the race condition where two smbd's detect the
|
||||
* file doesn't exist and do the create at the same time. One
|
||||
* of them will win and set a share mode, the other (ie. this
|
||||
* one) should check if the requested share mode for this
|
||||
* create is allowed.
|
||||
*/
|
||||
|
||||
id = fsp->file_id;
|
||||
/*
|
||||
* Now the file exists and fsp is successfully opened,
|
||||
* fsp->dev and fsp->inode are valid and should replace the
|
||||
* dev=0,inode=0 from a non existent file. Spotted by
|
||||
* Nadav Danieli <nadavd@exanet.com>. JRA.
|
||||
*/
|
||||
|
||||
lck = get_share_mode_lock(talloc_tos(), id,
|
||||
conn->connectpath,
|
||||
smb_fname, &old_write_time);
|
||||
id = fsp->file_id;
|
||||
|
||||
if (lck == NULL) {
|
||||
DEBUG(0, ("open_file_ntcreate: Could not get share "
|
||||
"mode lock for %s\n",
|
||||
smb_fname_str_dbg(smb_fname)));
|
||||
fd_close(fsp);
|
||||
return NT_STATUS_SHARING_VIOLATION;
|
||||
}
|
||||
lck = get_share_mode_lock(talloc_tos(), id,
|
||||
conn->connectpath,
|
||||
smb_fname, &old_write_time);
|
||||
|
||||
/* Get the types we need to examine. */
|
||||
find_oplock_types(fsp,
|
||||
oplock_request,
|
||||
lck,
|
||||
&batch_entry,
|
||||
&exclusive_entry,
|
||||
&got_level2_oplock,
|
||||
&got_a_none_oplock);
|
||||
if (lck == NULL) {
|
||||
DEBUG(0, ("open_file_ntcreate: Could not get share "
|
||||
"mode lock for %s\n",
|
||||
smb_fname_str_dbg(smb_fname)));
|
||||
fd_close(fsp);
|
||||
return NT_STATUS_SHARING_VIOLATION;
|
||||
}
|
||||
|
||||
/* First pass - send break only on batch oplocks. */
|
||||
/* Get the types we need to examine. */
|
||||
find_oplock_types(fsp,
|
||||
oplock_request,
|
||||
lck,
|
||||
&batch_entry,
|
||||
&exclusive_entry,
|
||||
&got_level2_oplock,
|
||||
&got_a_none_oplock);
|
||||
|
||||
/* First pass - send break only on batch oplocks. */
|
||||
if ((req != NULL) &&
|
||||
delay_for_batch_oplocks(fsp,
|
||||
req->mid,
|
||||
oplock_request,
|
||||
batch_entry)) {
|
||||
schedule_defer_open(lck, request_time, req);
|
||||
TALLOC_FREE(lck);
|
||||
fd_close(fsp);
|
||||
return NT_STATUS_SHARING_VIOLATION;
|
||||
}
|
||||
|
||||
status = open_mode_check(conn, lck, fsp->name_hash,
|
||||
access_mask, share_access,
|
||||
create_options, &file_existed);
|
||||
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
/* We might be going to allow this open. Check oplock
|
||||
* status again. */
|
||||
/* Second pass - send break for both batch or
|
||||
* exclusive oplocks. */
|
||||
if ((req != NULL) &&
|
||||
delay_for_batch_oplocks(fsp,
|
||||
req->mid,
|
||||
oplock_request,
|
||||
batch_entry)) {
|
||||
delay_for_exclusive_oplocks(
|
||||
fsp,
|
||||
req->mid,
|
||||
oplock_request,
|
||||
exclusive_entry)) {
|
||||
schedule_defer_open(lck, request_time, req);
|
||||
TALLOC_FREE(lck);
|
||||
fd_close(fsp);
|
||||
return NT_STATUS_SHARING_VIOLATION;
|
||||
}
|
||||
}
|
||||
|
||||
status = open_mode_check(conn, lck, fsp->name_hash,
|
||||
access_mask, share_access,
|
||||
create_options, &file_existed);
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) {
|
||||
/* DELETE_PENDING is not deferred for a second */
|
||||
TALLOC_FREE(lck);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
/* We might be going to allow this open. Check oplock
|
||||
* status again. */
|
||||
/* Second pass - send break for both batch or
|
||||
* exclusive oplocks. */
|
||||
if ((req != NULL) &&
|
||||
delay_for_exclusive_oplocks(
|
||||
fsp,
|
||||
req->mid,
|
||||
oplock_request,
|
||||
exclusive_entry)) {
|
||||
schedule_defer_open(lck, request_time, req);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
uint32 can_access_mask;
|
||||
bool can_access = True;
|
||||
|
||||
SMB_ASSERT(NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION));
|
||||
|
||||
/* Check if this can be done with the deny_dos and fcb
|
||||
* calls. */
|
||||
if (private_flags &
|
||||
(NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
|
||||
NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
|
||||
if (req == NULL) {
|
||||
DEBUG(0, ("DOS open without an SMB "
|
||||
"request!\n"));
|
||||
TALLOC_FREE(lck);
|
||||
fd_close(fsp);
|
||||
return NT_STATUS_SHARING_VIOLATION;
|
||||
return NT_STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
/* Use the client requested access mask here,
|
||||
* not the one we open with. */
|
||||
status = fcb_or_dos_open(req,
|
||||
conn,
|
||||
fsp,
|
||||
smb_fname,
|
||||
id,
|
||||
req->smbpid,
|
||||
req->vuid,
|
||||
access_mask,
|
||||
share_access,
|
||||
create_options);
|
||||
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
TALLOC_FREE(lck);
|
||||
if (pinfo) {
|
||||
*pinfo = FILE_WAS_OPENED;
|
||||
}
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) {
|
||||
/* DELETE_PENDING is not deferred for a second */
|
||||
TALLOC_FREE(lck);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
uint32 can_access_mask;
|
||||
bool can_access = True;
|
||||
|
||||
SMB_ASSERT(NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION));
|
||||
|
||||
/* Check if this can be done with the deny_dos and fcb
|
||||
* calls. */
|
||||
if (private_flags &
|
||||
(NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
|
||||
NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
|
||||
if (req == NULL) {
|
||||
DEBUG(0, ("DOS open without an SMB "
|
||||
"request!\n"));
|
||||
TALLOC_FREE(lck);
|
||||
return NT_STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
/* Use the client requested access mask here,
|
||||
* not the one we open with. */
|
||||
status = fcb_or_dos_open(req,
|
||||
conn,
|
||||
fsp,
|
||||
smb_fname,
|
||||
id,
|
||||
req->smbpid,
|
||||
req->vuid,
|
||||
access_mask,
|
||||
share_access,
|
||||
create_options);
|
||||
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
TALLOC_FREE(lck);
|
||||
if (pinfo) {
|
||||
*pinfo = FILE_WAS_OPENED;
|
||||
}
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This next line is a subtlety we need for
|
||||
* MS-Access. If a file open will fail due to share
|
||||
* permissions and also for security (access) reasons,
|
||||
* we need to return the access failed error, not the
|
||||
* share error. We can't open the file due to kernel
|
||||
* oplock deadlock (it's possible we failed above on
|
||||
* the open_mode_check()) so use a userspace check.
|
||||
*/
|
||||
|
||||
if (flags & O_RDWR) {
|
||||
can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
|
||||
} else if (flags & O_WRONLY) {
|
||||
can_access_mask = FILE_WRITE_DATA;
|
||||
} else {
|
||||
can_access_mask = FILE_READ_DATA;
|
||||
}
|
||||
|
||||
if (((can_access_mask & FILE_WRITE_DATA) &&
|
||||
!CAN_WRITE(conn)) ||
|
||||
!NT_STATUS_IS_OK(smbd_check_access_rights(conn,
|
||||
smb_fname,
|
||||
false,
|
||||
can_access_mask))) {
|
||||
can_access = False;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're returning a share violation, ensure we
|
||||
* cope with the braindead 1 second delay.
|
||||
*/
|
||||
|
||||
if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
|
||||
lp_defer_sharing_violations()) {
|
||||
struct timeval timeout;
|
||||
struct deferred_open_record state;
|
||||
int timeout_usecs;
|
||||
|
||||
/* this is a hack to speed up torture tests
|
||||
in 'make test' */
|
||||
timeout_usecs = lp_parm_int(SNUM(conn),
|
||||
"smbd","sharedelay",
|
||||
SHARING_VIOLATION_USEC_WAIT);
|
||||
|
||||
/* This is a relative time, added to the absolute
|
||||
request_time value to get the absolute timeout time.
|
||||
Note that if this is the second or greater time we enter
|
||||
this codepath for this particular request mid then
|
||||
request_time is left as the absolute time of the *first*
|
||||
time this request mid was processed. This is what allows
|
||||
the request to eventually time out. */
|
||||
|
||||
timeout = timeval_set(0, timeout_usecs);
|
||||
|
||||
/* Nothing actually uses state.delayed_for_oplocks
|
||||
but it's handy to differentiate in debug messages
|
||||
between a 30 second delay due to oplock break, and
|
||||
a 1 second delay for share mode conflicts. */
|
||||
|
||||
state.delayed_for_oplocks = False;
|
||||
state.async_open = false;
|
||||
state.id = id;
|
||||
|
||||
if ((req != NULL)
|
||||
&& !request_timed_out(request_time,
|
||||
timeout)) {
|
||||
defer_open(lck, request_time, timeout,
|
||||
req, &state);
|
||||
}
|
||||
}
|
||||
|
||||
TALLOC_FREE(lck);
|
||||
if (can_access) {
|
||||
/*
|
||||
* We have detected a sharing violation here
|
||||
* so return the correct error code
|
||||
*/
|
||||
status = NT_STATUS_SHARING_VIOLATION;
|
||||
} else {
|
||||
status = NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
grant_fsp_oplock_type(fsp,
|
||||
oplock_request,
|
||||
got_level2_oplock,
|
||||
got_a_none_oplock);
|
||||
|
||||
/*
|
||||
* We exit this block with the share entry *locked*.....
|
||||
* This next line is a subtlety we need for
|
||||
* MS-Access. If a file open will fail due to share
|
||||
* permissions and also for security (access) reasons,
|
||||
* we need to return the access failed error, not the
|
||||
* share error. We can't open the file due to kernel
|
||||
* oplock deadlock (it's possible we failed above on
|
||||
* the open_mode_check()) so use a userspace check.
|
||||
*/
|
||||
|
||||
if (flags & O_RDWR) {
|
||||
can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
|
||||
} else if (flags & O_WRONLY) {
|
||||
can_access_mask = FILE_WRITE_DATA;
|
||||
} else {
|
||||
can_access_mask = FILE_READ_DATA;
|
||||
}
|
||||
|
||||
if (((can_access_mask & FILE_WRITE_DATA) &&
|
||||
!CAN_WRITE(conn)) ||
|
||||
!NT_STATUS_IS_OK(smbd_check_access_rights(conn,
|
||||
smb_fname,
|
||||
false,
|
||||
can_access_mask))) {
|
||||
can_access = False;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're returning a share violation, ensure we
|
||||
* cope with the braindead 1 second delay.
|
||||
*/
|
||||
|
||||
if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
|
||||
lp_defer_sharing_violations()) {
|
||||
struct timeval timeout;
|
||||
struct deferred_open_record state;
|
||||
int timeout_usecs;
|
||||
|
||||
/* this is a hack to speed up torture tests
|
||||
in 'make test' */
|
||||
timeout_usecs = lp_parm_int(SNUM(conn),
|
||||
"smbd","sharedelay",
|
||||
SHARING_VIOLATION_USEC_WAIT);
|
||||
|
||||
/* This is a relative time, added to the absolute
|
||||
request_time value to get the absolute timeout time.
|
||||
Note that if this is the second or greater time we enter
|
||||
this codepath for this particular request mid then
|
||||
request_time is left as the absolute time of the *first*
|
||||
time this request mid was processed. This is what allows
|
||||
the request to eventually time out. */
|
||||
|
||||
timeout = timeval_set(0, timeout_usecs);
|
||||
|
||||
/* Nothing actually uses state.delayed_for_oplocks
|
||||
but it's handy to differentiate in debug messages
|
||||
between a 30 second delay due to oplock break, and
|
||||
a 1 second delay for share mode conflicts. */
|
||||
|
||||
state.delayed_for_oplocks = False;
|
||||
state.async_open = false;
|
||||
state.id = id;
|
||||
|
||||
if ((req != NULL)
|
||||
&& !request_timed_out(request_time,
|
||||
timeout)) {
|
||||
defer_open(lck, request_time, timeout,
|
||||
req, &state);
|
||||
}
|
||||
}
|
||||
|
||||
TALLOC_FREE(lck);
|
||||
if (can_access) {
|
||||
/*
|
||||
* We have detected a sharing violation here
|
||||
* so return the correct error code
|
||||
*/
|
||||
status = NT_STATUS_SHARING_VIOLATION;
|
||||
} else {
|
||||
status = NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
grant_fsp_oplock_type(fsp,
|
||||
oplock_request,
|
||||
got_level2_oplock,
|
||||
got_a_none_oplock);
|
||||
|
||||
/*
|
||||
* We have the share entry *locked*.....
|
||||
*/
|
||||
|
||||
SMB_ASSERT(lck != NULL);
|
||||
|
||||
/* Delete streams if create_disposition requires it */
|
||||
|
Loading…
Reference in New Issue
Block a user