summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2003-01-28 03:37:14 +0000
committerAndrew Bartlett <abartlet@samba.org>2003-01-28 03:37:14 +0000
commitdc4bb3bed82773ab0a07eb72b3d21305cccb6ecf (patch)
treeacda990f09f7037583408e4696458250eb2d0407 /source3/smbd
parent99bb7dccb29f44d7edeb0fca3f8cfc01bda03281 (diff)
downloadsamba-dc4bb3bed82773ab0a07eb72b3d21305cccb6ecf.tar.gz
samba-dc4bb3bed82773ab0a07eb72b3d21305cccb6ecf.tar.bz2
samba-dc4bb3bed82773ab0a07eb72b3d21305cccb6ecf.zip
Factor out common code in the NTLMSSP/SPNEGO code.
The idea here is to seperate, as much as possible, the SPNEGO layer from the NTLMSSP layer. This not only helps us with protocol correctness, but also should allow further mechinisms to be added with relitive ease. I indend to make the kerberos code use this shortly. I've never seen the 'zero length blob' form of the anonymous login, so I've removed that case. Andrew Bartlett (This used to be commit a8773c9f825539c5bc17e4200b16d7ebbe0b7620)
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/sesssetup.c178
1 files changed, 58 insertions, 120 deletions
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index e68695ee52..23a44d8df7 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -213,7 +213,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
send a security blob via a session setup reply
****************************************************************************/
static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf,
- DATA_BLOB blob, NTSTATUS errcode)
+ DATA_BLOB blob, NTSTATUS nt_status)
{
char *p;
@@ -222,60 +222,65 @@ static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf,
/* we set NT_STATUS_MORE_PROCESSING_REQUIRED to tell the other end
that we aren't finished yet */
- SIVAL(outbuf, smb_rcls, NT_STATUS_V(errcode));
+ nt_status = nt_status_squash(nt_status);
+ SIVAL(outbuf, smb_rcls, NT_STATUS_V(nt_status));
SSVAL(outbuf, smb_vwv0, 0xFF); /* no chaining possible */
SSVAL(outbuf, smb_vwv3, blob.length);
p = smb_buf(outbuf);
memcpy(p, blob.data, blob.length);
- p += blob.length;
- p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE);
- p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE);
- p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE);
- set_message_end(outbuf,p);
+
+ add_signature(outbuf);
return send_smb(smbd_server_fd(),outbuf);
}
/****************************************************************************
-send an NTLMSSP blob via a session setup reply, wrapped in SPNEGO
-****************************************************************************/
-static BOOL reply_spnego_ntlmssp_blob(connection_struct *conn, char *outbuf,
- DATA_BLOB *ntlmssp_blob, NTSTATUS errcode)
-{
- DATA_BLOB response;
- response = spnego_gen_auth_response(ntlmssp_blob);
- reply_sesssetup_blob(conn, outbuf, response, errcode);
- data_blob_free(&response);
- return True;
-}
-
-/****************************************************************************
- send an OK via a session setup reply, wrapped in SPNEGO.
+ send a session setup reply, wrapped in SPNEGO.
get vuid and check first.
-****************************************************************************/
-static BOOL reply_spnego_ntlmssp_ok(connection_struct *conn, char *outbuf,
- AUTH_NTLMSSP_STATE *auth_ntlmssp_state)
+ end the NTLMSSP exchange context if we are OK/complete fail
+***************************************************************************/
+static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *outbuf,
+ AUTH_NTLMSSP_STATE **auth_ntlmssp_state,
+ DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status)
{
- int sess_vuid;
- DATA_BLOB null_blob = data_blob(NULL, 0);
+ DATA_BLOB response;
+ struct auth_serversupplied_info *server_info;
+ server_info = (*auth_ntlmssp_state)->server_info;
- sess_vuid = register_vuid(auth_ntlmssp_state->server_info, auth_ntlmssp_state->ntlmssp_state->user /* check this for weird */);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ nt_status = do_map_to_guest(nt_status,
+ &server_info,
+ (*auth_ntlmssp_state)->ntlmssp_state->user,
+ (*auth_ntlmssp_state)->ntlmssp_state->domain);
+ }
- if (sess_vuid == -1) {
- return ERROR_NT(NT_STATUS_LOGON_FAILURE);
+ if (NT_STATUS_IS_OK(nt_status)) {
+ int sess_vuid;
+ sess_vuid = register_vuid(server_info, (*auth_ntlmssp_state)->ntlmssp_state->user /* check this for weird */);
+
+ if (sess_vuid == -1) {
+ nt_status = NT_STATUS_LOGON_FAILURE;
+ } else {
+
+ set_message(outbuf,4,0,True);
+ SSVAL(outbuf, smb_vwv3, 0);
+
+ if ((*auth_ntlmssp_state)->server_info->guest) {
+ SSVAL(outbuf,smb_vwv2,1);
+ }
+
+ SSVAL(outbuf,smb_uid,sess_vuid);
+ }
}
- set_message(outbuf,4,0,True);
- SSVAL(outbuf, smb_vwv3, 0);
+ response = spnego_gen_auth_response(ntlmssp_blob, nt_status);
+ reply_sesssetup_blob(conn, outbuf, response, nt_status);
+ data_blob_free(&response);
- if (auth_ntlmssp_state->server_info->guest) {
- SSVAL(outbuf,smb_vwv2,1);
+ if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ auth_ntlmssp_end(&global_ntlmssp_state);
}
- add_signature(outbuf);
-
- SSVAL(outbuf,smb_uid,sess_vuid);
- reply_spnego_ntlmssp_blob(conn, outbuf, &null_blob, NT_STATUS_OK);
return True;
}
@@ -291,7 +296,7 @@ static int reply_spnego_negotiate(connection_struct *conn,
char *OIDs[ASN1_MAX_OIDS];
DATA_BLOB secblob;
int i;
- DATA_BLOB chal, spnego_chal;
+ DATA_BLOB chal;
BOOL got_kerberos = False;
NTSTATUS nt_status;
@@ -333,41 +338,13 @@ static int reply_spnego_negotiate(connection_struct *conn,
data_blob_free(&secblob);
- if (!NT_STATUS_IS_OK(nt_status)) {
- nt_status = do_map_to_guest(nt_status,
- &global_ntlmssp_state->server_info,
- global_ntlmssp_state->ntlmssp_state->user,
- global_ntlmssp_state->ntlmssp_state->domain);
- }
-
- if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- if (!spnego_gen_challenge(&spnego_chal, &chal, NULL)) {
- DEBUG(3,("Failed to generate challenge\n"));
- data_blob_free(&chal);
- return ERROR_NT(NT_STATUS_LOGON_FAILURE);
- }
-
- /* now tell the client to send the auth packet */
- reply_sesssetup_blob(conn, outbuf, spnego_chal, nt_status);
+ reply_spnego_ntlmssp(conn, outbuf, &global_ntlmssp_state,
+ &chal, nt_status);
- data_blob_free(&chal);
- data_blob_free(&spnego_chal);
+ data_blob_free(&chal);
- /* and tell smbd that we have already replied to this packet */
- return -1;
-
- } else if (NT_STATUS_IS_OK(nt_status)) {
- reply_spnego_ntlmssp_ok(conn, outbuf,
- global_ntlmssp_state);
- auth_ntlmssp_end(&global_ntlmssp_state);
-
- /* and tell smbd that we have already replied to this packet */
- return -1;
- }
-
- auth_ntlmssp_end(&global_ntlmssp_state);
-
- return ERROR_NT(nt_status_squash(nt_status));
+ /* already replied */
+ return -1;
}
@@ -389,20 +366,14 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
}
nt_status = auth_ntlmssp_update(global_ntlmssp_state,
- auth, &auth_reply);
+ auth, &auth_reply);
data_blob_free(&auth);
- if (NT_STATUS_IS_OK(nt_status)) {
- reply_spnego_ntlmssp_ok(conn, outbuf,
- global_ntlmssp_state);
- auth_ntlmssp_end(&global_ntlmssp_state);
- data_blob_free(&auth_reply);
-
- } else { /* !NT_STATUS_IS_OK(nt_status) */
- auth_ntlmssp_end(&global_ntlmssp_state);
- return ERROR_NT(nt_status_squash(nt_status));
- }
+ reply_spnego_ntlmssp(conn, outbuf, &global_ntlmssp_state,
+ &auth_reply, nt_status);
+
+ data_blob_free(&auth_reply);
/* and tell smbd that we have already replied to this packet */
return -1;
@@ -410,41 +381,6 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
/****************************************************************************
-reply to a session setup spnego anonymous packet
-****************************************************************************/
-static int reply_spnego_anonymous(connection_struct *conn, char *inbuf, char *outbuf,
- int length, int bufsize)
-{
- int sess_vuid;
- auth_serversupplied_info *server_info = NULL;
- NTSTATUS nt_status;
-
- nt_status = check_guest_password(&server_info);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- return ERROR_NT(nt_status_squash(nt_status));
- }
-
- sess_vuid = register_vuid(server_info, lp_guestaccount());
-
- free_server_info(&server_info);
-
- if (sess_vuid == -1) {
- return ERROR_NT(NT_STATUS_LOGON_FAILURE);
- }
-
- set_message(outbuf,4,0,True);
- SSVAL(outbuf, smb_vwv3, 0);
- add_signature(outbuf);
-
- SSVAL(outbuf,smb_uid,sess_vuid);
- SSVAL(inbuf,smb_uid,sess_vuid);
-
- return chain_reply(inbuf,outbuf,length,bufsize);
-}
-
-
-/****************************************************************************
reply to a session setup command
****************************************************************************/
static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,
@@ -454,6 +390,7 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,
uint8 *p;
DATA_BLOB blob1;
int ret;
+ size_t bufrem;
DEBUG(3,("Doing spnego session setup\n"));
@@ -464,12 +401,13 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,
p = (uint8 *)smb_buf(inbuf);
if (SVAL(inbuf, smb_vwv7) == 0) {
- /* an anonymous request */
- return reply_spnego_anonymous(conn, inbuf, outbuf, length, bufsize);
+ /* an invalid request */
+ return ERROR_NT(NT_STATUS_LOGON_FAILURE);
}
+ bufrem = smb_bufrem(inbuf, p);
/* pull the spnego blob */
- blob1 = data_blob(p, SVAL(inbuf, smb_vwv7));
+ blob1 = data_blob(p, MIN(bufrem, SVAL(inbuf, smb_vwv7)));
#if 0
file_save("negotiate.dat", blob1.data, blob1.length);