diff options
author | Andrew Bartlett <abartlet@samba.org> | 2006-02-09 03:04:48 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:51:53 -0500 |
commit | 941c1566e514ef039220a781e12ce9385265071a (patch) | |
tree | 0fac2f8fed238b51e325eb21e97d8be8c9bdec7f | |
parent | 5cecce1761c06b0641190cf7bb8e93bff9a88cf4 (diff) | |
download | samba-941c1566e514ef039220a781e12ce9385265071a.tar.gz samba-941c1566e514ef039220a781e12ce9385265071a.tar.bz2 samba-941c1566e514ef039220a781e12ce9385265071a.zip |
r13403: Try to better handle a case where SPNEGO isn't available (allow us to
emulate the behaviour of XP standalone if required).
Andrew Bartlett
(This used to be commit 7f821097fbdbc9f35d96e05f85cf008f36c0eea3)
-rw-r--r-- | source4/smb_server/smb/negprot.c | 48 | ||||
-rw-r--r-- | source4/smb_server/smb/sesssetup.c | 7 | ||||
-rw-r--r-- | source4/smb_server/smb_server.h | 4 |
3 files changed, 34 insertions, 25 deletions
diff --git a/source4/smb_server/smb/negprot.c b/source4/smb_server/smb/negprot.c index d7646d997a..e9db4f119d 100644 --- a/source4/smb_server/smb/negprot.c +++ b/source4/smb_server/smb/negprot.c @@ -218,6 +218,22 @@ static void reply_lanman2(struct smbsrv_request *req, uint16_t choice) req_send_reply(req); } +static void reply_nt1_orig(struct smbsrv_request *req) +{ + /* Create a token value and add it to the outgoing packet. */ + if (req->smb_conn->negotiate.encrypted_passwords) { + req_grow_data(req, 8); + /* note that we do not send a challenge at all if + we are using plaintext */ + get_challenge(req->smb_conn, req->out.ptr); + req->out.ptr += 8; + SCVAL(req->out.vwv+1, VWV(16), 8); + } + req_push_str(req, NULL, lp_workgroup(), -1, STR_UNICODE|STR_TERMINATE|STR_NOALIGN); + req_push_str(req, NULL, lp_netbios_name(), -1, STR_UNICODE|STR_TERMINATE|STR_NOALIGN); + DEBUG(3,("not using SPNEGO\n")); +} + /**************************************************************************** Reply for the nt protocol. ****************************************************************************/ @@ -313,23 +329,13 @@ static void reply_nt1(struct smbsrv_request *req, uint16_t choice) SSVALS(req->out.vwv+1,VWV(15), req->smb_conn->negotiate.zone_offset/60); if (!negotiate_spnego) { - /* Create a token value and add it to the outgoing packet. */ - if (req->smb_conn->negotiate.encrypted_passwords) { - req_grow_data(req, 8); - /* note that we do not send a challenge at all if - we are using plaintext */ - get_challenge(req->smb_conn, req->out.ptr); - req->out.ptr += 8; - SCVAL(req->out.vwv+1, VWV(16), 8); - } - req_push_str(req, NULL, lp_workgroup(), -1, STR_UNICODE|STR_TERMINATE|STR_NOALIGN); - req_push_str(req, NULL, lp_netbios_name(), -1, STR_UNICODE|STR_TERMINATE|STR_NOALIGN); - DEBUG(3,("not using SPNEGO\n")); + reply_nt1_orig(req); } else { struct cli_credentials *server_credentials; struct gensec_security *gensec_security; DATA_BLOB null_data_blob = data_blob(NULL, 0); DATA_BLOB blob; + const char *oid; NTSTATUS nt_status = gensec_server_start(req->smb_conn, &gensec_security, req->smb_conn->connection->event.ctx); @@ -366,31 +372,33 @@ static void reply_nt1(struct smbsrv_request *req, uint16_t choice) gensec_set_credentials(gensec_security, server_credentials); - nt_status = gensec_start_mech_by_oid(gensec_security, GENSEC_OID_SPNEGO); + oid = GENSEC_OID_SPNEGO; + nt_status = gensec_start_mech_by_oid(gensec_security, oid); if (NT_STATUS_IS_OK(nt_status)) { /* Get and push the proposed OID list into the packets */ nt_status = gensec_update(gensec_security, req, null_data_blob, &blob); if (!NT_STATUS_IS_OK(nt_status) && !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - DEBUG(0, ("Failed to get SPNEGO to give us the first token: %s\n", nt_errstr(nt_status))); - smbsrv_terminate_connection(req->smb_conn, "Failed to start SPNEGO - no first token\n"); - return; + DEBUG(1, ("Failed to get SPNEGO to give us the first token: %s\n", nt_errstr(nt_status))); } - } else { + } + + if (!NT_STATUS_IS_OK(nt_status) && !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { DEBUG(5, ("Failed to start SPNEGO, falling back to NTLMSSP only: %s\n", nt_errstr(nt_status))); - nt_status = gensec_start_mech_by_oid(gensec_security, GENSEC_OID_NTLMSSP); + oid = GENSEC_OID_NTLMSSP; + nt_status = gensec_start_mech_by_oid(gensec_security, oid); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0, ("Failed to start SPNEGO as well as NTLMSSP fallback: %s\n", nt_errstr(nt_status))); - smbsrv_terminate_connection(req->smb_conn, "Failed to start SPNEGO and NTLMSSP"); + reply_nt1_orig(req); return; } /* NTLMSSP is a client-first exchange */ blob = data_blob(NULL, 0); } - req->smb_conn->negotiate.spnego_negotiated = True; + req->smb_conn->negotiate.oid = oid; req_grow_data(req, blob.length + 16); /* a NOT very random guid, perhaps we should get it diff --git a/source4/smb_server/smb/sesssetup.c b/source4/smb_server/smb/sesssetup.c index 225f0f7c47..a90f709a12 100644 --- a/source4/smb_server/smb/sesssetup.c +++ b/source4/smb_server/smb/sesssetup.c @@ -149,7 +149,7 @@ static NTSTATUS sesssetup_nt1(struct smbsrv_request *req, union smb_sesssetup *s req->smb_conn->negotiate.client_caps = sess->nt1.in.capabilities; } - if (req->smb_conn->negotiate.spnego_negotiated) { + if (req->smb_conn->negotiate.oid) { if (sess->nt1.in.user && *sess->nt1.in.user) { /* We can't accept a normal login, because we * don't have a challenge */ @@ -294,9 +294,10 @@ static NTSTATUS sesssetup_spnego(struct smbsrv_request *req, union smb_sesssetup gensec_want_feature(gensec_ctx, GENSEC_FEATURE_SESSION_KEY); - status = gensec_start_mech_by_oid(gensec_ctx, GENSEC_OID_SPNEGO); + status = gensec_start_mech_by_oid(gensec_ctx, req->smb_conn->negotiate.oid); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start GENSEC SPNEGO server code: %s\n", nt_errstr(status))); + DEBUG(1, ("Failed to start GENSEC %s server code: %s\n", + gensec_get_name_by_oid(req->smb_conn->negotiate.oid), nt_errstr(status))); return status; } diff --git a/source4/smb_server/smb_server.h b/source4/smb_server/smb_server.h index b72c207e3b..0c201b2b1d 100644 --- a/source4/smb_server/smb_server.h +++ b/source4/smb_server/smb_server.h @@ -251,8 +251,8 @@ struct smbsrv_connection { /* did we tell the client we support encrypted passwords? */ BOOL encrypted_passwords; - /* did we send an extended security negprot reply? */ - BOOL spnego_negotiated; + /* Did we choose SPNEGO, or perhaps raw NTLMSSP, or even no extended security at all? */ + const char *oid; /* client capabilities */ uint32_t client_caps; |