summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/smbd/globals.h6
-rw-r--r--source3/smbd/smb2_server.c63
-rw-r--r--source3/smbd/smb2_sesssetup.c31
3 files changed, 98 insertions, 2 deletions
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 5a7ad7d9e3..345f748802 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -201,6 +201,7 @@ extern int num_children;
struct tstream_context;
struct smbd_smb2_request;
+struct smbd_smb2_session;
DATA_BLOB negprot_spnego(void);
@@ -220,6 +221,8 @@ NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
NTSTATUS smbd_smb2_request_done(struct smbd_smb2_request *req,
DATA_BLOB body, DATA_BLOB *dyn);
+NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req);
+
NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req);
NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *req);
NTSTATUS smbd_smb2_request_process_keepalive(struct smbd_smb2_request *req);
@@ -229,6 +232,9 @@ struct smbd_smb2_request {
struct smbd_server_connection *conn;
+ /* the session the request operates on, maybe NULL */
+ struct smbd_smb2_session *session;
+
int current_idx;
struct {
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 6d8961eebb..36f4c10b17 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -288,6 +288,7 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
const uint8_t *inhdr;
int i = req->current_idx;
uint16_t opcode;
+ NTSTATUS status;
inhdr = (const uint8_t *)req->in.vector[i].iov_base;
@@ -303,35 +304,73 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_process_sesssetup(req);
case SMB2_OP_LOGOFF:
+ status = smbd_smb2_request_check_session(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
- return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_TCON:
+ status = smbd_smb2_request_check_session(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
- return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_TDIS:
+ status = smbd_smb2_request_check_session(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_CREATE:
+ status = smbd_smb2_request_check_session(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_CLOSE:
+ status = smbd_smb2_request_check_session(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_FLUSH:
+ status = smbd_smb2_request_check_session(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_READ:
+ status = smbd_smb2_request_check_session(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_WRITE:
+ status = smbd_smb2_request_check_session(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_LOCK:
+ status = smbd_smb2_request_check_session(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_IOCTL:
+ status = smbd_smb2_request_check_session(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_CANCEL:
@@ -341,18 +380,38 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_process_keepalive(req);
case SMB2_OP_FIND:
+ status = smbd_smb2_request_check_session(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_NOTIFY:
+ status = smbd_smb2_request_check_session(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_GETINFO:
+ status = smbd_smb2_request_check_session(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_SETINFO:
+ status = smbd_smb2_request_check_session(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_BREAK:
+ status = smbd_smb2_request_check_session(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
}
diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c
index 6c4da393e1..d322223ad5 100644
--- a/source3/smbd/smb2_sesssetup.c
+++ b/source3/smbd/smb2_sesssetup.c
@@ -180,6 +180,11 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req,
} else if (NT_STATUS_IS_OK(status)) {
/* TODO: setup session key for signing */
session->status = NT_STATUS_OK;
+ /*
+ * we attach the session to the request
+ * so that the response can be signed
+ */
+ req->session = session;
} else {
return status;
}
@@ -188,3 +193,29 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req,
return status;
}
+NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
+{
+ const uint8_t *inhdr;
+ int i = req->current_idx;
+ uint64_t in_session_id;
+ void *p;
+ struct smbd_smb2_session *session;
+
+ inhdr = (const uint8_t *)req->in.vector[i+0].iov_base;
+
+ in_session_id = SVAL(inhdr, SMB2_HDR_SESSION_ID);
+
+ /* lookup an existing session */
+ p = idr_find(req->conn->smb2.sessions.idtree, in_session_id);
+ if (p == NULL) {
+ return NT_STATUS_USER_SESSION_DELETED;
+ }
+ session = talloc_get_type_abort(p, struct smbd_smb2_session);
+
+ if (!NT_STATUS_IS_OK(session->status)) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ req->session = session;
+ return NT_STATUS_OK;
+}