Disable SMB2 for 3.6?
Jeremy Allison
jra at samba.org
Thu Jul 7 14:38:27 MDT 2011
On Thu, Jul 07, 2011 at 12:07:40PM -0700, Jeremy Allison wrote:
>
> Metze - do you have an opinion as to whether your patch produces
> the clearest way to get maintainable code ? I'm assuming you
> want the become_root() calls inline ?
>
> Volker - would it help if the function smbd_smb2_request_check_tcon()
> was moved out of smbd/smb2_tcon.c and into smbd/smb2_server.c
> and the same for smbd_smb2_request_check_session() (move out of
> smbd/smb2_sessetup.c into smbd/smb2_server.c) as it would make
> the validation functions locally located to the dispatch function
> that has to call them to check security ? Right now they are
> located in the files that are named after the code that processes
> the request, which makes sense from a naming point of view, but
> not from a logic point of view - these functions are validation
> code, not request processing code. If we moved them both into
> smbd/smb2_server.c to just above smbd_smb2_request_dispatch()
> they could both be make static to that file.
>
> Volker, your opinion is most valuable, as you're the one who
> found this bug - which is most definitely a show-stopper for
> release (the very definition in fact :-).
Here is the diff against master that moves the check_ functions
into smbd/smb2_server.c. Volker and Metze please comment on your
opinions on this.
Cheers,
Jeremy
-------------- next part --------------
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 51ea367..472eab1 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -267,9 +267,6 @@ NTSTATUS smbd_smb2_send_oplock_break(struct smbd_server_connection *sconn,
NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
struct tevent_req *subreq);
-NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req);
-NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req);
-
struct smb_request *smbd_smb2_fake_smb_request(struct smbd_smb2_request *req);
void remove_smb2_chained_fsp(files_struct *fsp);
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 90f4767..088fe76 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -26,6 +26,8 @@
#include "../lib/tsocket/tsocket.h"
#include "../lib/util/tevent_ntstatus.h"
#include "smbprofile.h"
+#include "../librpc/gen_ndr/krb5pac.h"
+#include "auth.h"
#define OUTVEC_ALLOC_SIZE (SMB2_HDR_BODY + 9)
@@ -1071,6 +1073,134 @@ static NTSTATUS smbd_smb2_request_process_cancel(struct smbd_smb2_request *req)
return NT_STATUS_OK;
}
+/*************************************************************
+ Ensure an incoming session_id is a valid one for us to access.
+*************************************************************/
+
+static NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
+{
+ const uint8_t *inhdr;
+ const uint8_t *outhdr;
+ int i = req->current_idx;
+ uint64_t in_session_id;
+ void *p;
+ struct smbd_smb2_session *session;
+ bool chained_fixup = false;
+
+ inhdr = (const uint8_t *)req->in.vector[i+0].iov_base;
+
+ in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
+
+ if (in_session_id == (0xFFFFFFFFFFFFFFFFLL)) {
+ if (req->async) {
+ /*
+ * async request - fill in session_id from
+ * already setup request out.vector[].iov_base.
+ */
+ outhdr = (const uint8_t *)req->out.vector[i].iov_base;
+ in_session_id = BVAL(outhdr, SMB2_HDR_SESSION_ID);
+ } else if (i > 2) {
+ /*
+ * Chained request - fill in session_id from
+ * the previous request out.vector[].iov_base.
+ */
+ outhdr = (const uint8_t *)req->out.vector[i-3].iov_base;
+ in_session_id = BVAL(outhdr, SMB2_HDR_SESSION_ID);
+ chained_fixup = true;
+ }
+ }
+
+ /* lookup an existing session */
+ p = idr_find(req->sconn->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;
+ }
+
+ set_current_user_info(session->session_info->sanitized_username,
+ session->session_info->unix_name,
+ session->session_info->info3->base.domain.string);
+
+ req->session = session;
+
+ if (chained_fixup) {
+ /* Fix up our own outhdr. */
+ outhdr = (const uint8_t *)req->out.vector[i].iov_base;
+ SBVAL(discard_const_p(uint8_t, outhdr), SMB2_HDR_SESSION_ID, in_session_id);
+ }
+ return NT_STATUS_OK;
+}
+
+/*************************************************************
+ Ensure an incoming tid is a valid one for us to access.
+ Change to the associated uid credentials and chdir to the
+ valid tid directory.
+*************************************************************/
+
+static NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req)
+{
+ const uint8_t *inhdr;
+ const uint8_t *outhdr;
+ int i = req->current_idx;
+ uint32_t in_tid;
+ void *p;
+ struct smbd_smb2_tcon *tcon;
+ bool chained_fixup = false;
+
+ inhdr = (const uint8_t *)req->in.vector[i+0].iov_base;
+
+ in_tid = IVAL(inhdr, SMB2_HDR_TID);
+
+ if (in_tid == (0xFFFFFFFF)) {
+ if (req->async) {
+ /*
+ * async request - fill in tid from
+ * already setup out.vector[].iov_base.
+ */
+ outhdr = (const uint8_t *)req->out.vector[i].iov_base;
+ in_tid = IVAL(outhdr, SMB2_HDR_TID);
+ } else if (i > 2) {
+ /*
+ * Chained request - fill in tid from
+ * the previous request out.vector[].iov_base.
+ */
+ outhdr = (const uint8_t *)req->out.vector[i-3].iov_base;
+ in_tid = IVAL(outhdr, SMB2_HDR_TID);
+ chained_fixup = true;
+ }
+ }
+
+ /* lookup an existing session */
+ p = idr_find(req->session->tcons.idtree, in_tid);
+ if (p == NULL) {
+ return NT_STATUS_NETWORK_NAME_DELETED;
+ }
+ tcon = talloc_get_type_abort(p, struct smbd_smb2_tcon);
+
+ if (!change_to_user(tcon->compat_conn,req->session->vuid)) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /* should we pass FLAG_CASELESS_PATHNAMES here? */
+ if (!set_current_service(tcon->compat_conn, 0, true)) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ req->tcon = tcon;
+
+ if (chained_fixup) {
+ /* Fix up our own outhdr. */
+ outhdr = (const uint8_t *)req->out.vector[i].iov_base;
+ SIVAL(discard_const_p(uint8_t, outhdr), SMB2_HDR_TID, in_tid);
+ }
+
+ return NT_STATUS_OK;
+}
+
NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
{
const uint8_t *inhdr;
diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c
index e09eff8..8a4704c 100644
--- a/source3/smbd/smb2_sesssetup.c
+++ b/source3/smbd/smb2_sesssetup.c
@@ -795,64 +795,6 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *smb2req,
return NT_STATUS_LOGON_FAILURE;
}
-NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
-{
- const uint8_t *inhdr;
- const uint8_t *outhdr;
- int i = req->current_idx;
- uint64_t in_session_id;
- void *p;
- struct smbd_smb2_session *session;
- bool chained_fixup = false;
-
- inhdr = (const uint8_t *)req->in.vector[i+0].iov_base;
-
- in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
-
- if (in_session_id == (0xFFFFFFFFFFFFFFFFLL)) {
- if (req->async) {
- /*
- * async request - fill in session_id from
- * already setup request out.vector[].iov_base.
- */
- outhdr = (const uint8_t *)req->out.vector[i].iov_base;
- in_session_id = BVAL(outhdr, SMB2_HDR_SESSION_ID);
- } else if (i > 2) {
- /*
- * Chained request - fill in session_id from
- * the previous request out.vector[].iov_base.
- */
- outhdr = (const uint8_t *)req->out.vector[i-3].iov_base;
- in_session_id = BVAL(outhdr, SMB2_HDR_SESSION_ID);
- chained_fixup = true;
- }
- }
-
- /* lookup an existing session */
- p = idr_find(req->sconn->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;
- }
-
- set_current_user_info(session->session_info->sanitized_username,
- session->session_info->unix_name,
- session->session_info->info3->base.domain.string);
-
- req->session = session;
-
- if (chained_fixup) {
- /* Fix up our own outhdr. */
- outhdr = (const uint8_t *)req->out.vector[i].iov_base;
- SBVAL(discard_const_p(uint8_t, outhdr), SMB2_HDR_SESSION_ID, in_session_id);
- }
- return NT_STATUS_OK;
-}
-
NTSTATUS smbd_smb2_request_process_logoff(struct smbd_smb2_request *req)
{
const uint8_t *inbody;
diff --git a/source3/smbd/smb2_tcon.c b/source3/smbd/smb2_tcon.c
index 7c2014c..946bc56 100644
--- a/source3/smbd/smb2_tcon.c
+++ b/source3/smbd/smb2_tcon.c
@@ -278,66 +278,6 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
return NT_STATUS_OK;
}
-NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req)
-{
- const uint8_t *inhdr;
- const uint8_t *outhdr;
- int i = req->current_idx;
- uint32_t in_tid;
- void *p;
- struct smbd_smb2_tcon *tcon;
- bool chained_fixup = false;
-
- inhdr = (const uint8_t *)req->in.vector[i+0].iov_base;
-
- in_tid = IVAL(inhdr, SMB2_HDR_TID);
-
- if (in_tid == (0xFFFFFFFF)) {
- if (req->async) {
- /*
- * async request - fill in tid from
- * already setup out.vector[].iov_base.
- */
- outhdr = (const uint8_t *)req->out.vector[i].iov_base;
- in_tid = IVAL(outhdr, SMB2_HDR_TID);
- } else if (i > 2) {
- /*
- * Chained request - fill in tid from
- * the previous request out.vector[].iov_base.
- */
- outhdr = (const uint8_t *)req->out.vector[i-3].iov_base;
- in_tid = IVAL(outhdr, SMB2_HDR_TID);
- chained_fixup = true;
- }
- }
-
- /* lookup an existing session */
- p = idr_find(req->session->tcons.idtree, in_tid);
- if (p == NULL) {
- return NT_STATUS_NETWORK_NAME_DELETED;
- }
- tcon = talloc_get_type_abort(p, struct smbd_smb2_tcon);
-
- if (!change_to_user(tcon->compat_conn,req->session->vuid)) {
- return NT_STATUS_ACCESS_DENIED;
- }
-
- /* should we pass FLAG_CASELESS_PATHNAMES here? */
- if (!set_current_service(tcon->compat_conn, 0, true)) {
- return NT_STATUS_ACCESS_DENIED;
- }
-
- req->tcon = tcon;
-
- if (chained_fixup) {
- /* Fix up our own outhdr. */
- outhdr = (const uint8_t *)req->out.vector[i].iov_base;
- SIVAL(discard_const_p(uint8_t, outhdr), SMB2_HDR_TID, in_tid);
- }
-
- return NT_STATUS_OK;
-}
-
NTSTATUS smbd_smb2_request_process_tdis(struct smbd_smb2_request *req)
{
const uint8_t *inbody;
More information about the samba-technical
mailing list