1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

smbd: Move smb_set_posix_lock to smb1_trans2.c

Signed-off-by: David Mulder <dmulder@suse.com>
Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
David Mulder 2022-03-21 11:59:15 -06:00 committed by Jeremy Allison
parent 88b07d3b7f
commit 547f5c78ad
3 changed files with 172 additions and 167 deletions

View File

@ -271,3 +271,170 @@ void send_trans2_replies(connection_struct *conn,
return;
}
/****************************************************************************
Deal with SMB_SET_POSIX_LOCK.
****************************************************************************/
static void smb_set_posix_lock_done(struct tevent_req *subreq);
NTSTATUS smb_set_posix_lock(connection_struct *conn,
struct smb_request *req,
const char *pdata,
int total_data,
files_struct *fsp)
{
struct tevent_req *subreq = NULL;
struct smbd_lock_element *lck = NULL;
uint64_t count;
uint64_t offset;
uint64_t smblctx;
bool blocking_lock = False;
enum brl_type lock_type;
NTSTATUS status = NT_STATUS_OK;
if (fsp == NULL ||
fsp->fsp_flags.is_pathref ||
fsp_get_io_fd(fsp) == -1)
{
return NT_STATUS_INVALID_HANDLE;
}
if (total_data != POSIX_LOCK_DATA_SIZE) {
return NT_STATUS_INVALID_PARAMETER;
}
switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
case POSIX_LOCK_TYPE_READ:
lock_type = READ_LOCK;
break;
case POSIX_LOCK_TYPE_WRITE:
/* Return the right POSIX-mappable error code for files opened read-only. */
if (!fsp->fsp_flags.can_write) {
return NT_STATUS_INVALID_HANDLE;
}
lock_type = WRITE_LOCK;
break;
case POSIX_LOCK_TYPE_UNLOCK:
lock_type = UNLOCK_LOCK;
break;
default:
return NT_STATUS_INVALID_PARAMETER;
}
switch (SVAL(pdata, POSIX_LOCK_FLAGS_OFFSET)) {
case POSIX_LOCK_FLAG_NOWAIT:
blocking_lock = false;
break;
case POSIX_LOCK_FLAG_WAIT:
blocking_lock = true;
break;
default:
return NT_STATUS_INVALID_PARAMETER;
}
if (!lp_blocking_locks(SNUM(conn))) {
blocking_lock = False;
}
smblctx = (uint64_t)IVAL(pdata, POSIX_LOCK_PID_OFFSET);
offset = (((uint64_t) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
((uint64_t) IVAL(pdata,POSIX_LOCK_START_OFFSET));
count = (((uint64_t) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
((uint64_t) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
DBG_DEBUG("file %s, lock_type = %u, smblctx = %"PRIu64", "
"count = %"PRIu64", offset = %"PRIu64"\n",
fsp_str_dbg(fsp),
(unsigned int)lock_type,
smblctx,
count,
offset);
if (lock_type == UNLOCK_LOCK) {
struct smbd_lock_element l = {
.req_guid = smbd_request_guid(req, 0),
.smblctx = smblctx,
.brltype = UNLOCK_LOCK,
.lock_flav = POSIX_LOCK,
.offset = offset,
.count = count,
};
status = smbd_do_unlocking(req, fsp, 1, &l);
return status;
}
lck = talloc(req, struct smbd_lock_element);
if (lck == NULL) {
return NT_STATUS_NO_MEMORY;
}
*lck = (struct smbd_lock_element) {
.req_guid = smbd_request_guid(req, 0),
.smblctx = smblctx,
.brltype = lock_type,
.lock_flav = POSIX_LOCK,
.count = count,
.offset = offset,
};
subreq = smbd_smb1_do_locks_send(
fsp,
req->sconn->ev_ctx,
&req,
fsp,
blocking_lock ? UINT32_MAX : 0,
true, /* large_offset */
1,
lck);
if (subreq == NULL) {
TALLOC_FREE(lck);
return NT_STATUS_NO_MEMORY;
}
tevent_req_set_callback(subreq, smb_set_posix_lock_done, req);
return NT_STATUS_EVENT_PENDING;
}
static void smb_set_posix_lock_done(struct tevent_req *subreq)
{
struct smb_request *req = NULL;
NTSTATUS status;
bool ok;
ok = smbd_smb1_do_locks_extract_smbreq(subreq, talloc_tos(), &req);
SMB_ASSERT(ok);
status = smbd_smb1_do_locks_recv(subreq);
TALLOC_FREE(subreq);
if (NT_STATUS_IS_OK(status)) {
char params[2] = {0};
/* Fake up max_data_bytes here - we know it fits. */
send_trans2_replies(
req->conn,
req,
NT_STATUS_OK,
params,
2,
NULL,
0,
0xffff);
} else {
reply_nterror(req, status);
ok = srv_send_smb(
req->xconn,
(char *)req->outbuf,
true,
req->seqnum+1,
IS_CONN_ENCRYPTED(req->conn),
NULL);
if (!ok) {
exit_server_cleanly("smb_set_posix_lock_done: "
"srv_send_smb failed.");
}
}
TALLOC_FREE(req);
return;
}

View File

@ -31,3 +31,8 @@ void send_trans2_replies(connection_struct *conn,
const char *pdata,
int datasize,
int max_data_bytes);
NTSTATUS smb_set_posix_lock(connection_struct *conn,
struct smb_request *req,
const char *pdata,
int total_data,
files_struct *fsp);

View File

@ -7367,173 +7367,6 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn,
}
#endif
/****************************************************************************
Deal with SMB_SET_POSIX_LOCK.
****************************************************************************/
static void smb_set_posix_lock_done(struct tevent_req *subreq);
static NTSTATUS smb_set_posix_lock(connection_struct *conn,
struct smb_request *req,
const char *pdata,
int total_data,
files_struct *fsp)
{
struct tevent_req *subreq = NULL;
struct smbd_lock_element *lck = NULL;
uint64_t count;
uint64_t offset;
uint64_t smblctx;
bool blocking_lock = False;
enum brl_type lock_type;
NTSTATUS status = NT_STATUS_OK;
if (fsp == NULL ||
fsp->fsp_flags.is_pathref ||
fsp_get_io_fd(fsp) == -1)
{
return NT_STATUS_INVALID_HANDLE;
}
if (total_data != POSIX_LOCK_DATA_SIZE) {
return NT_STATUS_INVALID_PARAMETER;
}
switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
case POSIX_LOCK_TYPE_READ:
lock_type = READ_LOCK;
break;
case POSIX_LOCK_TYPE_WRITE:
/* Return the right POSIX-mappable error code for files opened read-only. */
if (!fsp->fsp_flags.can_write) {
return NT_STATUS_INVALID_HANDLE;
}
lock_type = WRITE_LOCK;
break;
case POSIX_LOCK_TYPE_UNLOCK:
lock_type = UNLOCK_LOCK;
break;
default:
return NT_STATUS_INVALID_PARAMETER;
}
switch (SVAL(pdata, POSIX_LOCK_FLAGS_OFFSET)) {
case POSIX_LOCK_FLAG_NOWAIT:
blocking_lock = false;
break;
case POSIX_LOCK_FLAG_WAIT:
blocking_lock = true;
break;
default:
return NT_STATUS_INVALID_PARAMETER;
}
if (!lp_blocking_locks(SNUM(conn))) {
blocking_lock = False;
}
smblctx = (uint64_t)IVAL(pdata, POSIX_LOCK_PID_OFFSET);
offset = (((uint64_t) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
((uint64_t) IVAL(pdata,POSIX_LOCK_START_OFFSET));
count = (((uint64_t) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
((uint64_t) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
DBG_DEBUG("file %s, lock_type = %u, smblctx = %"PRIu64", "
"count = %"PRIu64", offset = %"PRIu64"\n",
fsp_str_dbg(fsp),
(unsigned int)lock_type,
smblctx,
count,
offset);
if (lock_type == UNLOCK_LOCK) {
struct smbd_lock_element l = {
.req_guid = smbd_request_guid(req, 0),
.smblctx = smblctx,
.brltype = UNLOCK_LOCK,
.lock_flav = POSIX_LOCK,
.offset = offset,
.count = count,
};
status = smbd_do_unlocking(req, fsp, 1, &l);
return status;
}
lck = talloc(req, struct smbd_lock_element);
if (lck == NULL) {
return NT_STATUS_NO_MEMORY;
}
*lck = (struct smbd_lock_element) {
.req_guid = smbd_request_guid(req, 0),
.smblctx = smblctx,
.brltype = lock_type,
.lock_flav = POSIX_LOCK,
.count = count,
.offset = offset,
};
subreq = smbd_smb1_do_locks_send(
fsp,
req->sconn->ev_ctx,
&req,
fsp,
blocking_lock ? UINT32_MAX : 0,
true, /* large_offset */
1,
lck);
if (subreq == NULL) {
TALLOC_FREE(lck);
return NT_STATUS_NO_MEMORY;
}
tevent_req_set_callback(subreq, smb_set_posix_lock_done, req);
return NT_STATUS_EVENT_PENDING;
}
static void smb_set_posix_lock_done(struct tevent_req *subreq)
{
struct smb_request *req = NULL;
NTSTATUS status;
bool ok;
ok = smbd_smb1_do_locks_extract_smbreq(subreq, talloc_tos(), &req);
SMB_ASSERT(ok);
status = smbd_smb1_do_locks_recv(subreq);
TALLOC_FREE(subreq);
if (NT_STATUS_IS_OK(status)) {
char params[2] = {0};
/* Fake up max_data_bytes here - we know it fits. */
send_trans2_replies(
req->conn,
req,
NT_STATUS_OK,
params,
2,
NULL,
0,
0xffff);
} else {
reply_nterror(req, status);
ok = srv_send_smb(
req->xconn,
(char *)req->outbuf,
true,
req->seqnum+1,
IS_CONN_ENCRYPTED(req->conn),
NULL);
if (!ok) {
exit_server_cleanly("smb_set_posix_lock_done: "
"srv_send_smb failed.");
}
}
TALLOC_FREE(req);
return;
}
/****************************************************************************
Deal with SMB_SET_FILE_BASIC_INFO.
****************************************************************************/