mirror of
https://github.com/samba-team/samba.git
synced 2025-01-10 01:18:15 +03:00
s3:smbd: split out check_and_store_share_mode()
This shows that the code in open_file_ntcreate() and open_directory() is basically the same now, which simplifies things a lot. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15125 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
parent
9e619f535f
commit
26669613e2
@ -3373,6 +3373,83 @@ static void schedule_async_open(struct smb_request *req)
|
||||
}
|
||||
}
|
||||
|
||||
static NTSTATUS check_and_store_share_mode(
|
||||
struct files_struct *fsp,
|
||||
struct smb_request *req,
|
||||
struct share_mode_lock *lck,
|
||||
uint32_t create_disposition,
|
||||
uint32_t access_mask,
|
||||
uint32_t share_access,
|
||||
int oplock_request,
|
||||
const struct smb2_lease *lease,
|
||||
bool first_open_attempt)
|
||||
{
|
||||
NTSTATUS status;
|
||||
int oplock_type = NO_OPLOCK;
|
||||
uint32_t granted_lease = 0;
|
||||
const struct smb2_lease_key *lease_key = NULL;
|
||||
bool ok;
|
||||
|
||||
/* Get the types we need to examine. */
|
||||
if (!validate_oplock_types(lck)) {
|
||||
smb_panic("validate_oplock_types failed");
|
||||
}
|
||||
|
||||
if (has_delete_on_close(lck, fsp->name_hash)) {
|
||||
return NT_STATUS_DELETE_PENDING;
|
||||
}
|
||||
|
||||
status = handle_share_mode_lease(fsp,
|
||||
lck,
|
||||
create_disposition,
|
||||
access_mask,
|
||||
share_access,
|
||||
oplock_request,
|
||||
lease,
|
||||
first_open_attempt,
|
||||
&oplock_type,
|
||||
&granted_lease);
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
|
||||
schedule_defer_open(lck, fsp->file_id, req);
|
||||
return NT_STATUS_SHARING_VIOLATION;
|
||||
}
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if (oplock_type == LEASE_OPLOCK) {
|
||||
lease_key = &lease->lease_key;
|
||||
}
|
||||
|
||||
share_mode_flags_restrict(lck, access_mask, share_access, 0);
|
||||
|
||||
ok = set_share_mode(lck,
|
||||
fsp,
|
||||
get_current_uid(fsp->conn),
|
||||
req ? req->mid : 0,
|
||||
oplock_type,
|
||||
lease_key,
|
||||
share_access,
|
||||
access_mask);
|
||||
if (!ok) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (oplock_type == LEASE_OPLOCK) {
|
||||
status = grant_fsp_lease(fsp, lck, lease, granted_lease);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
del_share_mode(lck, fsp);
|
||||
return status;
|
||||
}
|
||||
|
||||
DBG_DEBUG("lease_state=%d\n", fsp->lease->lease.lease_state);
|
||||
}
|
||||
|
||||
fsp->oplock_type = oplock_type;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Work out what access_mask to use from what the client sent us.
|
||||
****************************************************************************/
|
||||
@ -3672,14 +3749,10 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
|
||||
uint32_t existing_dos_attributes = 0;
|
||||
struct share_mode_lock *lck = NULL;
|
||||
uint32_t open_access_mask = access_mask;
|
||||
const struct smb2_lease_key *lease_key = NULL;
|
||||
int oplock_type = NO_OPLOCK;
|
||||
uint32_t granted_lease = 0;
|
||||
NTSTATUS status;
|
||||
SMB_STRUCT_STAT saved_stat = smb_fname->st;
|
||||
struct timespec old_write_time;
|
||||
bool setup_poll = false;
|
||||
bool ok;
|
||||
|
||||
if (conn->printer) {
|
||||
/*
|
||||
@ -4143,77 +4216,22 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
|
||||
return NT_STATUS_SHARING_VIOLATION;
|
||||
}
|
||||
|
||||
/* Get the types we need to examine. */
|
||||
if (!validate_oplock_types(lck)) {
|
||||
smb_panic("validate_oplock_types failed");
|
||||
}
|
||||
|
||||
if (has_delete_on_close(lck, fsp->name_hash)) {
|
||||
TALLOC_FREE(lck);
|
||||
fd_close(fsp);
|
||||
return NT_STATUS_DELETE_PENDING;
|
||||
}
|
||||
|
||||
status = handle_share_mode_lease(
|
||||
status = check_and_store_share_mode(
|
||||
fsp,
|
||||
req,
|
||||
lck,
|
||||
create_disposition,
|
||||
access_mask,
|
||||
share_access,
|
||||
oplock_request,
|
||||
lease,
|
||||
first_open_attempt,
|
||||
&oplock_type,
|
||||
&granted_lease);
|
||||
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
|
||||
schedule_defer_open(lck, fsp->file_id, req);
|
||||
TALLOC_FREE(lck);
|
||||
fd_close(fsp);
|
||||
return NT_STATUS_SHARING_VIOLATION;
|
||||
}
|
||||
|
||||
first_open_attempt);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
TALLOC_FREE(lck);
|
||||
fd_close(fsp);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (oplock_type == LEASE_OPLOCK) {
|
||||
lease_key = &lease->lease_key;
|
||||
}
|
||||
|
||||
share_mode_flags_restrict(lck, access_mask, share_access, 0);
|
||||
|
||||
ok = set_share_mode(
|
||||
lck,
|
||||
fsp,
|
||||
get_current_uid(fsp->conn),
|
||||
req ? req->mid : 0,
|
||||
oplock_type,
|
||||
lease_key,
|
||||
share_access,
|
||||
access_mask);
|
||||
if (!ok) {
|
||||
TALLOC_FREE(lck);
|
||||
fd_close(fsp);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (oplock_type == LEASE_OPLOCK) {
|
||||
status = grant_fsp_lease(fsp, lck, lease, granted_lease);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
del_share_mode(lck, fsp);
|
||||
TALLOC_FREE(lck);
|
||||
fd_close(fsp);
|
||||
return status;
|
||||
}
|
||||
|
||||
DBG_DEBUG("lease_state=%d\n", fsp->lease->lease.lease_state);
|
||||
}
|
||||
|
||||
fsp->oplock_type = oplock_type;
|
||||
|
||||
if (fsp->oplock_type != NO_OPLOCK && fsp->oplock_type != LEASE_OPLOCK) {
|
||||
/*
|
||||
* Now ask for kernel oplocks
|
||||
@ -4225,7 +4243,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
|
||||
* Could not get the kernel oplock
|
||||
*/
|
||||
remove_share_oplock(lck, fsp);
|
||||
fsp->oplock_type = oplock_type = NO_OPLOCK;
|
||||
fsp->oplock_type = NO_OPLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4593,12 +4611,9 @@ static NTSTATUS open_directory(connection_struct *conn,
|
||||
struct smb_filename *smb_dname = fsp->fsp_name;
|
||||
bool dir_existed = VALID_STAT(smb_dname->st);
|
||||
struct share_mode_lock *lck = NULL;
|
||||
int oplock_type = NO_OPLOCK;
|
||||
uint32_t granted_lease = 0;
|
||||
NTSTATUS status;
|
||||
struct timespec mtimespec;
|
||||
int info = 0;
|
||||
bool ok;
|
||||
uint32_t need_fd_access;
|
||||
|
||||
if (is_ntfs_stream_smb_fname(smb_dname)) {
|
||||
@ -4869,46 +4884,22 @@ static NTSTATUS open_directory(connection_struct *conn,
|
||||
return NT_STATUS_SHARING_VIOLATION;
|
||||
}
|
||||
|
||||
if (has_delete_on_close(lck, fsp->name_hash)) {
|
||||
TALLOC_FREE(lck);
|
||||
fd_close(fsp);
|
||||
return NT_STATUS_DELETE_PENDING;
|
||||
}
|
||||
|
||||
status = handle_share_mode_lease(
|
||||
status = check_and_store_share_mode(
|
||||
fsp,
|
||||
req,
|
||||
lck,
|
||||
create_disposition,
|
||||
access_mask,
|
||||
share_access,
|
||||
NO_OPLOCK,
|
||||
NULL, /* lease */
|
||||
true, /* first_open_attempt */
|
||||
&oplock_type,
|
||||
&granted_lease);
|
||||
NULL, /* lease */
|
||||
true); /* first_open_attempt */
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
TALLOC_FREE(lck);
|
||||
fd_close(fsp);
|
||||
return status;
|
||||
}
|
||||
|
||||
share_mode_flags_restrict(lck, access_mask, share_access, 0);
|
||||
|
||||
ok = set_share_mode(
|
||||
lck,
|
||||
fsp,
|
||||
get_current_uid(conn),
|
||||
req ? req->mid : 0,
|
||||
oplock_type,
|
||||
NULL,
|
||||
share_access,
|
||||
fsp->access_mask);
|
||||
if (!ok) {
|
||||
TALLOC_FREE(lck);
|
||||
fd_close(fsp);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* For directories the delete on close bit at open time seems
|
||||
always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
|
||||
if (create_options & FILE_DELETE_ON_CLOSE) {
|
||||
|
Loading…
Reference in New Issue
Block a user