mirror of
https://github.com/samba-team/samba.git
synced 2025-02-24 13:57:43 +03:00
r1507: fixed the handling of SMB chaining with the new server structure. You
must think carefully about packet chaining when dealing with any authentication or SMB parsing issues. The particular problem here was that a chained tconX didn't get the req->session setup after an initial sesstion setup call, so the tconx used a bogus VUID.
This commit is contained in:
parent
f276378157
commit
6f2a335cd6
@ -82,6 +82,8 @@ static NTSTATUS sesssetup_old(struct smbsrv_request *req, union smb_sesssetup *s
|
|||||||
&sess->old.out.lanman,
|
&sess->old.out.lanman,
|
||||||
&sess->old.out.domain);
|
&sess->old.out.domain);
|
||||||
|
|
||||||
|
req->session = smbsrv_session_find(req->smb_conn, sess->old.out.vuid);
|
||||||
|
|
||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,6 +135,7 @@ static NTSTATUS sesssetup_nt1(struct smbsrv_request *req, union smb_sesssetup *s
|
|||||||
&sess->nt1.out.lanman,
|
&sess->nt1.out.lanman,
|
||||||
&sess->nt1.out.domain);
|
&sess->nt1.out.domain);
|
||||||
|
|
||||||
|
req->session = smbsrv_session_find(req->smb_conn, sess->nt1.out.vuid);
|
||||||
srv_setup_signing(req->smb_conn, &session_info->session_key, &sess->nt1.in.password2);
|
srv_setup_signing(req->smb_conn, &session_info->session_key, &sess->nt1.in.password2);
|
||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
@ -153,18 +156,25 @@ static NTSTATUS sesssetup_spnego(struct smbsrv_request *req, union smb_sesssetup
|
|||||||
NTSTATUS sesssetup_backend(struct smbsrv_request *req,
|
NTSTATUS sesssetup_backend(struct smbsrv_request *req,
|
||||||
union smb_sesssetup *sess)
|
union smb_sesssetup *sess)
|
||||||
{
|
{
|
||||||
|
NTSTATUS status = NT_STATUS_INVALID_LEVEL;
|
||||||
|
|
||||||
switch (sess->generic.level) {
|
switch (sess->generic.level) {
|
||||||
case RAW_SESSSETUP_OLD:
|
case RAW_SESSSETUP_OLD:
|
||||||
return sesssetup_old(req, sess);
|
status = sesssetup_old(req, sess);
|
||||||
|
break;
|
||||||
case RAW_SESSSETUP_NT1:
|
case RAW_SESSSETUP_NT1:
|
||||||
return sesssetup_nt1(req, sess);
|
status = sesssetup_nt1(req, sess);
|
||||||
|
break;
|
||||||
case RAW_SESSSETUP_SPNEGO:
|
case RAW_SESSSETUP_SPNEGO:
|
||||||
return sesssetup_spnego(req, sess);
|
status = sesssetup_spnego(req, sess);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NT_STATUS_IS_OK(status)) {
|
||||||
req->smb_conn->negotiate.done_sesssetup = True;
|
req->smb_conn->negotiate.done_sesssetup = True;
|
||||||
|
}
|
||||||
|
|
||||||
return NT_STATUS_INVALID_LEVEL;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -421,8 +421,8 @@ onto the message queue
|
|||||||
static void switch_message(int type, struct smbsrv_request *req)
|
static void switch_message(int type, struct smbsrv_request *req)
|
||||||
{
|
{
|
||||||
int flags;
|
int flags;
|
||||||
uint16_t session_tag;
|
|
||||||
struct smbsrv_connection *smb_conn = req->smb_conn;
|
struct smbsrv_connection *smb_conn = req->smb_conn;
|
||||||
|
uint16_t session_tag;
|
||||||
|
|
||||||
type &= 0xff;
|
type &= 0xff;
|
||||||
|
|
||||||
@ -436,22 +436,28 @@ static void switch_message(int type, struct smbsrv_request *req)
|
|||||||
|
|
||||||
flags = smb_messages[type].flags;
|
flags = smb_messages[type].flags;
|
||||||
|
|
||||||
/* In share mode security we must ignore the vuid. */
|
|
||||||
session_tag = (lp_security() == SEC_SHARE) ?
|
|
||||||
UID_FIELD_INVALID :
|
|
||||||
SVAL(req->in.hdr,HDR_UID);
|
|
||||||
|
|
||||||
req->tcon = conn_find(smb_conn, SVAL(req->in.hdr,HDR_TID));
|
req->tcon = conn_find(smb_conn, SVAL(req->in.hdr,HDR_TID));
|
||||||
|
|
||||||
/* setup the user context for this request */
|
if (req->session == NULL) {
|
||||||
|
/* setup the user context for this request if it
|
||||||
|
hasn't already been initialised (to cope with SMB
|
||||||
|
chaining) */
|
||||||
|
|
||||||
|
/* In share mode security we must ignore the vuid. */
|
||||||
|
if (lp_security() == SEC_SHARE) {
|
||||||
|
session_tag = UID_FIELD_INVALID;
|
||||||
|
} else {
|
||||||
|
session_tag = SVAL(req->in.hdr,HDR_UID);
|
||||||
|
}
|
||||||
|
|
||||||
req->session = smbsrv_session_find(req->smb_conn, session_tag);
|
req->session = smbsrv_session_find(req->smb_conn, session_tag);
|
||||||
|
|
||||||
/* Ensure this value is replaced in the incoming packet. */
|
|
||||||
SSVAL(req->in.hdr,HDR_UID,session_tag);
|
|
||||||
|
|
||||||
if (req->session) {
|
if (req->session) {
|
||||||
req->session->vuid = session_tag;
|
req->session->vuid = session_tag;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
session_tag = req->session->vuid;
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG(3,("switch message %s (task_id %d)\n",smb_fn_name(type), smb_conn->connection->service->model_ops->get_id(req)));
|
DEBUG(3,("switch message %s (task_id %d)\n",smb_fn_name(type), smb_conn->connection->service->model_ops->get_id(req)));
|
||||||
|
|
||||||
/* does this protocol need to be run as root? */
|
/* does this protocol need to be run as root? */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user