summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/globals.c4
-rw-r--r--source3/smbd/globals.h9
-rw-r--r--source3/smbd/sesssetup.c47
3 files changed, 37 insertions, 23 deletions
diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c
index 3dc057e18d..73a3a15ab8 100644
--- a/source3/smbd/globals.c
+++ b/source3/smbd/globals.c
@@ -154,10 +154,6 @@ struct db_context *session_db_ctx_ptr = NULL;
uint32_t global_client_caps = 0;
bool done_sesssetup = false;
-/****************************************************************************
- List to store partial SPNEGO auth fragments.
-****************************************************************************/
-struct pending_auth_data *pd_list = NULL;
uint16_t fnf_handle = 257;
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 2f9f7afd65..333f4f12a8 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -159,11 +159,6 @@ extern struct db_context *session_db_ctx_ptr;
extern uint32_t global_client_caps;
extern bool done_sesssetup;
-/****************************************************************************
- List to store partial SPNEGO auth fragments.
-****************************************************************************/
-struct pending_auth_data;
-extern struct pending_auth_data *pd_list;
extern uint16_t fnf_handle;
@@ -328,12 +323,16 @@ struct smbd_smb2_tcon {
int snum;
};
+struct pending_auth_data;
+
struct smbd_server_connection {
bool allow_smb2;
struct {
struct fd_event *fde;
uint64_t num_requests;
struct smb_signing_state *signing_state;
+ /* List to store partial SPNEGO auth fragments. */
+ struct pending_auth_data *pd_list;
} smb1;
struct {
struct tevent_context *event_ctx;
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index d524f21817..e82de0ae98 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -27,6 +27,15 @@
extern enum protocol_types Protocol;
+/* For split krb5 SPNEGO blobs. */
+struct pending_auth_data {
+ struct pending_auth_data *prev, *next;
+ uint16 vuid; /* Tag for this entry. */
+ uint16 smbpid; /* Alternate tag for this entry. */
+ size_t needed_len;
+ DATA_BLOB partial_data;
+};
+
/*
on a logon error possibly map the error to success if "map to guest"
is set approriately
@@ -920,12 +929,13 @@ static void reply_spnego_auth(struct smb_request *req,
Delete an entry on the list.
****************************************************************************/
-static void delete_partial_auth(struct pending_auth_data *pad)
+static void delete_partial_auth(struct smbd_server_connection *sconn,
+ struct pending_auth_data *pad)
{
if (!pad) {
return;
}
- DLIST_REMOVE(pd_list, pad);
+ DLIST_REMOVE(sconn->smb1.pd_list, pad);
data_blob_free(&pad->partial_data);
SAFE_FREE(pad);
}
@@ -934,11 +944,17 @@ static void delete_partial_auth(struct pending_auth_data *pad)
Search for a partial SPNEGO auth fragment matching an smbpid.
****************************************************************************/
-static struct pending_auth_data *get_pending_auth_data(uint16 smbpid)
+static struct pending_auth_data *get_pending_auth_data(
+ struct smbd_server_connection *sconn,
+ uint16_t smbpid)
{
struct pending_auth_data *pad;
-
- for (pad = pd_list; pad; pad = pad->next) {
+/*
+ * NOTE: using the smbpid here is completely wrong...
+ * see [MS-SMB]
+ * 3.3.5.3 Receiving an SMB_COM_SESSION_SETUP_ANDX Request
+ */
+ for (pad = sconn->smb1.pd_list; pad; pad = pad->next) {
if (pad->smbpid == smbpid) {
break;
}
@@ -952,20 +968,21 @@ static struct pending_auth_data *get_pending_auth_data(uint16 smbpid)
the blob to be more than 64k.
****************************************************************************/
-static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid,
- DATA_BLOB *pblob)
+static NTSTATUS check_spnego_blob_complete(struct smbd_server_connection *sconn,
+ uint16 smbpid, uint16 vuid,
+ DATA_BLOB *pblob)
{
struct pending_auth_data *pad = NULL;
ASN1_DATA *data;
size_t needed_len = 0;
- pad = get_pending_auth_data(smbpid);
+ pad = get_pending_auth_data(sconn, smbpid);
/* Ensure we have some data. */
if (pblob->length == 0) {
/* Caller can cope. */
DEBUG(2,("check_spnego_blob_complete: zero blob length !\n"));
- delete_partial_auth(pad);
+ delete_partial_auth(sconn, pad);
return NT_STATUS_OK;
}
@@ -986,7 +1003,7 @@ static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid,
(unsigned int)pad->partial_data.length,
(unsigned int)copy_len ));
- delete_partial_auth(pad);
+ delete_partial_auth(sconn, pad);
return NT_STATUS_INVALID_PARAMETER;
}
@@ -1022,7 +1039,7 @@ static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid,
data_blob_free(pblob);
*pblob = pad->partial_data;
ZERO_STRUCT(pad->partial_data);
- delete_partial_auth(pad);
+ delete_partial_auth(sconn, pad);
return NT_STATUS_OK;
}
@@ -1107,7 +1124,7 @@ static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid,
}
pad->smbpid = smbpid;
pad->vuid = vuid;
- DLIST_ADD(pd_list, pad);
+ DLIST_ADD(sconn->smb1.pd_list, pad);
return NT_STATUS_MORE_PROCESSING_REQUIRED;
}
@@ -1133,6 +1150,7 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
user_struct *vuser = NULL;
NTSTATUS status = NT_STATUS_OK;
uint16 smbpid = req->smbpid;
+ struct smbd_server_connection *sconn = smbd_server_conn;
DEBUG(3,("Doing spnego session setup\n"));
@@ -1198,7 +1216,8 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
if (!is_partial_auth_vuid(vuid)) {
/* No, then try and see if this is an intermediate sessionsetup
* for a large SPNEGO packet. */
- struct pending_auth_data *pad = get_pending_auth_data(smbpid);
+ struct pending_auth_data *pad;
+ pad = get_pending_auth_data(sconn, smbpid);
if (pad) {
DEBUG(10,("reply_sesssetup_and_X_spnego: found "
"pending vuid %u\n",
@@ -1230,7 +1249,7 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
* field is 4k. Bug #4400. JRA.
*/
- status = check_spnego_blob_complete(smbpid, vuid, &blob1);
+ status = check_spnego_blob_complete(sconn, smbpid, vuid, &blob1);
if (!NT_STATUS_IS_OK(status)) {
if (!NT_STATUS_EQUAL(status,
NT_STATUS_MORE_PROCESSING_REQUIRED)) {