r2307: Fix the use of 'raw' NTLMSSP to hosts that support extended security,
authorAndrew Bartlett <abartlet@samba.org>
Mon, 13 Sep 2004 04:28:10 +0000 (04:28 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:58:42 +0000 (12:58 -0500)
but do not support SPNEGO (such as XP, when not joined to a domain).

This is triggered by the presense or lack of a security blob in the
negprot reply.

Andrew Bartlett

source/libcli/auth/gensec.c
source/libcli/auth/spnego.c
source/libcli/raw/clisession.c

index a744f513dc8362a1d33c55a9d32ab9e843fa946c..b7891ee53b7d2c8b8e8f42a0e089c2d9db5c3ef6 100644 (file)
@@ -262,6 +262,17 @@ const char *gensec_get_name_by_authtype(uint8_t authtype)
 }
        
 
+const char *gensec_get_name_by_oid(const char *oid) 
+{
+       const struct gensec_security_ops *ops;
+       ops = gensec_security_by_oid(oid);
+       if (ops) {
+               return ops->name;
+       }
+       return NULL;
+}
+       
+
 /** 
  * Start a GENSEC sub-mechanism by OID, used in SPNEGO
  *
index f3ead5069dbc950843671b93f42a7031f4eb32fe..696240f8d6c1a03789103e87bb74fa3449cbb870 100644 (file)
@@ -290,7 +290,8 @@ static NTSTATUS gensec_spnego_parse_negTokenInit(struct gensec_security *gensec_
                                                  null_data_blob, 
                                                  unwrapped_out);
                }
-               if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(nt_status)) {
+               if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) 
+                   && (!NT_STATUS_IS_OK(nt_status))) {
                        DEBUG(1, ("SPNEGO(%s) NEG_TOKEN_INIT failed: %s\n", 
                                  spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status)));
                                gensec_end(&spnego_state->sub_sec_security);
@@ -412,7 +413,7 @@ static NTSTATUS gensec_spnego_server_negTokenTarg(struct gensec_security *gensec
 
 
 static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, 
-                              const DATA_BLOB in, DATA_BLOB *out) 
+                                    const DATA_BLOB in, DATA_BLOB *out) 
 {
        struct spnego_state *spnego_state = gensec_security->private_data;
        DATA_BLOB null_data_blob = data_blob(NULL, 0);
index 32be6b68ed657251c5805817927a30a684695491..dcf32c84856335d68a08910c38819ed7b07d2168 100644 (file)
@@ -379,6 +379,7 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct smbcli_session *sess
        union smb_sesssetup s2;
        DATA_BLOB session_key = data_blob(NULL, 0);
        DATA_BLOB null_data_blob = data_blob(NULL, 0);
+       const char *chosen_oid;
 
        s2.generic.level = RAW_SESSSETUP_SPNEGO;
        s2.spnego.in.bufsize = ~0;
@@ -429,21 +430,25 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct smbcli_session *sess
                goto done;
        }
 
-       status = gensec_start_mech_by_oid(session->gensec, OID_SPNEGO);
+       if (session->transport->negotiate.secblob.length) {
+               chosen_oid = OID_SPNEGO;
+       } else {
+               /* without a sec blob, means raw NTLMSSP */
+               chosen_oid = OID_NTLMSSP;
+       }
+
+       status = gensec_start_mech_by_oid(session->gensec, chosen_oid);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism: %s\n",
-                         nt_errstr(status)));
+               DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism %s: %s\n",
+                         gensec_get_name_by_oid(chosen_oid), nt_errstr(status)));
                goto done;
        }
-
+       
        status = gensec_update(session->gensec, mem_ctx,
-                              session->transport->negotiate.secblob,
-                              &s2.spnego.in.secblob);
+                                      session->transport->negotiate.secblob,
+                                      &s2.spnego.in.secblob);
 
        while(1) {
-               if (NT_STATUS_IS_OK(status) && s2.spnego.in.secblob.length == 0) {
-                       break;
-               }
                if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) {
                        break;
                }
@@ -455,6 +460,10 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct smbcli_session *sess
                        smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob);
                }
                
+               if (NT_STATUS_IS_OK(status) && s2.spnego.in.secblob.length == 0) {
+                       break;
+               }
+
                session->vuid = s2.spnego.out.vuid;
                status = smb_raw_session_setup(session, mem_ctx, &s2);
                session->vuid = UID_FIELD_INVALID;
@@ -483,7 +492,7 @@ done:
                parms->generic.out.lanman = s2.spnego.out.lanman;
                parms->generic.out.domain = s2.spnego.out.domain;
        } else {
-               DEBUG(1, ("Failed to login with SPNEGO: %s\n", nt_errstr(status)));
+               DEBUG(1, ("Failed to login with %s: %s\n", gensec_get_name_by_oid(chosen_oid), nt_errstr(status)));
                return status;
        }