r26355: Eliminate global_loadparm in more places.
[kai/samba.git] / source4 / libcli / ldap / ldap_bind.c
index 6714d68b0ed2b3a20249231ab8c6f2c50742b3ea..bd548be38e416f182cb985abd7a8a54ac678833f 100644 (file)
@@ -8,7 +8,7 @@
     
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -17,8 +17,7 @@
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
 */
 
 #include "libcli/ldap/ldap.h"
 #include "libcli/ldap/ldap_client.h"
 #include "lib/tls/tls.h"
-#include "auth/auth.h"
+#include "auth/gensec/gensec.h"
+#include "auth/gensec/socket.h"
+#include "auth/credentials/credentials.h"
+#include "lib/stream/packet.h"
+#include "param/param.h"
 
 struct ldap_simple_creds {
        const char *dn;
@@ -40,7 +43,8 @@ NTSTATUS ldap_rebind(struct ldap_connection *conn)
 
        switch (conn->bind.type) {
        case LDAP_BIND_SASL:
-               status = ldap_bind_sasl(conn, (struct cli_credentials *)conn->bind.creds);
+               status = ldap_bind_sasl(conn, (struct cli_credentials *)conn->bind.creds,
+                                       conn->lp_ctx);
                break;
                
        case LDAP_BIND_SIMPLE:
@@ -196,7 +200,9 @@ static struct ldap_message *new_ldap_sasl_bind_msg(struct ldap_connection *conn,
 /*
   perform a sasl bind using the given credentials
 */
-NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds)
+NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, 
+                       struct cli_credentials *creds,
+                       struct loadparm_context *lp_ctx)
 {
        NTSTATUS status;
        TALLOC_CTX *tmp_ctx = NULL;
@@ -209,13 +215,13 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr
        int count, i;
 
        const char **sasl_names;
-       
+       uint32_t old_gensec_features;
        static const char *supported_sasl_mech_attrs[] = {
                "supportedSASLMechanisms", 
                NULL 
        };
 
-       status = gensec_client_start(conn, &conn->gensec, NULL);
+       status = gensec_client_start(conn, &conn->gensec, NULL, lp_ctx);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status)));
                goto failed;
@@ -223,10 +229,12 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr
 
        /* require Kerberos SIGN/SEAL only if we don't use SSL
         * Windows seem not to like double encryption */
-       if (!tls_enabled(conn->sock)) {
-               gensec_want_feature(conn->gensec, 0 | GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL);
+       old_gensec_features = cli_credentials_get_gensec_features(creds);
+       if (tls_enabled(conn->sock)) {
+               cli_credentials_set_gensec_features(creds, 0);
        }
 
+       /* this call also sets the gensec_want_features */
        status = gensec_set_credentials(conn->gensec, creds);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Failed to set GENSEC creds: %s\n", 
@@ -234,11 +242,16 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr
                goto failed;
        }
 
-       status = gensec_set_target_hostname(conn->gensec, conn->host);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(1, ("Failed to set GENSEC target hostname: %s\n", 
-                         nt_errstr(status)));
-               goto failed;
+       /* reset the original gensec_features */
+       cli_credentials_set_gensec_features(creds, old_gensec_features);
+
+       if (conn->host) {
+               status = gensec_set_target_hostname(conn->gensec, conn->host);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DEBUG(1, ("Failed to set GENSEC target hostname: %s\n", 
+                                 nt_errstr(status)));
+                       goto failed;
+               }
        }
 
        status = gensec_set_target_service(conn->gensec, "ldap");
@@ -249,7 +262,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr
        }
 
        status = ildap_search(conn, "", LDAP_SEARCH_SCOPE_BASE, "", supported_sasl_mech_attrs, 
-                             False, NULL, NULL, &sasl_mechs_msgs);
+                             false, NULL, NULL, &sasl_mechs_msgs);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: %s\n", 
                          nt_errstr(status)));
@@ -365,15 +378,23 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr
                }
        }
 
-       if (NT_STATUS_IS_OK(status) &&
-           (gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL) ||
-            gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN))) {
-               conn->enable_wrap = True;
-       }
-
        talloc_free(tmp_ctx);
 
        if (NT_STATUS_IS_OK(status)) {
+               struct socket_context *sasl_socket;
+               status = gensec_socket_init(conn->gensec, 
+                                           conn->sock,
+                                           conn->event.event_ctx, 
+                                           ldap_read_io_handler,
+                                           conn,
+                                           &sasl_socket);
+               if (!NT_STATUS_IS_OK(status)) goto failed;
+
+               talloc_steal(conn->sock, sasl_socket);
+               talloc_unlink(conn, conn->sock);
+               conn->sock = sasl_socket;
+               packet_set_socket(conn->packet, conn->sock);
+
                conn->bind.type = LDAP_BIND_SASL;
                conn->bind.creds = creds;
        }