summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2006-02-09 03:04:48 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:51:53 -0500
commit941c1566e514ef039220a781e12ce9385265071a (patch)
tree0fac2f8fed238b51e325eb21e97d8be8c9bdec7f
parent5cecce1761c06b0641190cf7bb8e93bff9a88cf4 (diff)
downloadsamba-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.c48
-rw-r--r--source4/smb_server/smb/sesssetup.c7
-rw-r--r--source4/smb_server/smb_server.h4
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;