r13344: Trust SASL to have subtle distinctions between NULL and zero-length
authorAndrew Bartlett <abartlet@samba.org>
Sat, 4 Feb 2006 11:19:09 +0000 (11:19 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:51:46 +0000 (13:51 -0500)
responses...

Also trust OpenLDAP to be pedantic about it, breaking connections to AD.

In any case, we now get this 'right' (by nasty overloading hacks, but
hey), and we can now use system-supplied OpenLDAP libs and SASL/GSSAPI
to talk to Samba4.

Andrew Bartlett

source/auth/gensec/gensec_gssapi.c
source/libcli/ldap/ldap.c

index 0b48a010eb2ba5357378053b9fa35d1c4db1f898..aaa79aa407b888aeef4ec86db4d20137fab99ada 100644 (file)
@@ -394,9 +394,9 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
                                                          gensec_gssapi_state->input_chan_bindings,
                                                          &gensec_gssapi_state->client_name, 
                                                          &gss_oid_p,
-                                                 &output_token, 
-                                                 &gensec_gssapi_state->got_flags, 
-                                                 NULL, 
+                                                         &output_token, 
+                                                         &gensec_gssapi_state->got_flags, 
+                                                         NULL, 
                                                          &gensec_gssapi_state->delegated_cred_handle);
                        gensec_gssapi_state->gss_oid = gss_oid_p;
                        break;
@@ -416,8 +416,22 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
                                DEBUG(5, ("gensec_gssapi: NO credentials were delegated\n"));
                        }
 
-                       /* We may have been invoked as SASL, so there is more work to do */
+                       /* We may have been invoked as SASL, so there
+                        * is more work to do */
                        if (gensec_gssapi_state->sasl) {
+                               /* Due to a very subtle interaction
+                                * with SASL and the LDAP libs, we
+                                * must ensure the data pointer is 
+                                * != NULL, but the length is 0.  
+                                *
+                                * This ensures we send a 'zero
+                                * length' (rather than NULL) response 
+                                */
+                               
+                               if (!out->data) {
+                                       out->data = (uint8_t *)talloc_strdup(out_mem_ctx, "\0");
+                               }
+
                                gensec_gssapi_state->sasl_state = STAGE_SASL_SSF_NEG;
                                return NT_STATUS_MORE_PROCESSING_REQUIRED;
                        } else {
@@ -543,11 +557,11 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
                        gensec_gssapi_state->sasl_state = STAGE_DONE;
 
                        if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
-                               DEBUG(3, ("GSSAPI Connection to server will be cryptographicly sealed\n"));
+                               DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographicly sealed\n"));
                        } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
-                               DEBUG(3, ("GSSAPI Connection to server will be cryptographicly signed\n"));
+                               DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographicly signed\n"));
                        } else {
-                               DEBUG(3, ("GSSAPI Connection to server will have no cryptographicly protection\n"));
+                               DEBUG(3, ("SASL/GSSAPI Connection to server will have no cryptographicly protection\n"));
                        }
 
                        return NT_STATUS_OK;
@@ -661,11 +675,11 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
                /* quirk:  This changes the value that gensec_have_feature returns, to be that after SASL negotiation */
                gensec_gssapi_state->sasl_state = STAGE_DONE;
                if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
-                       DEBUG(3, ("GSSAPI Connection from client will be cryptographicly sealed\n"));
+                       DEBUG(3, ("SASL/GSSAPI Connection from client will be cryptographicly sealed\n"));
                } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
-                       DEBUG(3, ("GSSAPI Connection from client will be cryptographicly signed\n"));
+                       DEBUG(3, ("SASL/GSSAPI Connection from client will be cryptographicly signed\n"));
                } else {
-                       DEBUG(3, ("GSSAPI Connection from client will have no cryptographicly protection\n"));
+                       DEBUG(3, ("SASL/GSSAPI Connection from client will have no cryptographicly protection\n"));
                }
 
                *out = data_blob(NULL, 0);
index b281f62ed017d616bfe954191a88a310b49b7202..496fec527f76a67f034bf1b26749d3d7445dc8fb 100644 (file)
@@ -219,8 +219,15 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct
                        asn1_push_tag(&data, ASN1_CONTEXT(3));
                        asn1_write_OctetString(&data, r->creds.SASL.mechanism,
                                               strlen(r->creds.SASL.mechanism));
-                       asn1_write_OctetString(&data, r->creds.SASL.secblob.data,
-                                              r->creds.SASL.secblob.length);
+                       /* The value of data indicates if this
+                        * optional element exists at all.  In SASL
+                        * there is a difference between NULL and
+                        * zero-legnth, but our APIs don't express it
+                        * well */
+                       if (r->creds.SASL.secblob.data) {
+                               asn1_write_OctetString(&data, r->creds.SASL.secblob.data,
+                                                      r->creds.SASL.secblob.length);
+                       }
                        asn1_pop_tag(&data);
                        break;
                default:
@@ -234,7 +241,14 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct
                struct ldap_BindResponse *r = &msg->r.BindResponse;
                asn1_push_tag(&data, ASN1_APPLICATION(msg->type));
                ldap_encode_response(&data, &r->response);
-               asn1_write_ContextSimple(&data, 7, &r->SASL.secblob);
+               /* The value of data indicates if this
+                * optional element exists at all.  In SASL
+                * there is a difference between NULL and
+                * zero-legnth, but our APIs don't express it
+                * well */
+               if (r->SASL.secblob.data) {
+                       asn1_write_ContextSimple(&data, 7, &r->SASL.secblob);
+               }
                asn1_pop_tag(&data);
                break;
        }