r17215: Prepare the SASL socket before actually settting it. This allows
authorAndrew Bartlett <abartlet@samba.org>
Mon, 24 Jul 2006 00:45:21 +0000 (00:45 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:10:19 +0000 (14:10 -0500)
errors to be reported corectly, rather than just dropping the socket.

Andrew Bartlett
(This used to be commit 83dd22accfd565e86d831490043d6beaa9648c96)

source4/ldap_server/ldap_bind.c

index 7fce3904505fcf01ed68d3e6a22ecd96039596bb..3afb617499d5bc17cef960337f8555f52dbad7fa 100644 (file)
@@ -90,21 +90,17 @@ static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call)
        return NT_STATUS_OK;
 }
 
+struct ldapsrv_sasl_context {
+       struct ldapsrv_connection *conn;
+       struct socket_context *sasl_socket;
+};
+
 static void ldapsrv_set_sasl(void *private) 
 {
-       struct ldapsrv_connection *conn = talloc_get_type(private, struct ldapsrv_connection);
-       struct socket_context *socket = gensec_socket_init(conn->gensec, 
-                                                          conn->connection->socket,
-                                                          conn->connection->event.ctx, 
-                                                          stream_io_handler_callback,
-                                                          conn->connection);
-       if (socket) {
-               conn->connection->socket = socket;
-               talloc_steal(conn->connection->socket, socket);
-               packet_set_socket(conn->packet, socket);
-       } else {
-               ldapsrv_terminate_connection(conn, "Failed to setup SASL wrapping on socket");
-       }
+       struct ldapsrv_sasl_context *ctx = talloc_get_type(private, struct ldapsrv_sasl_context);
+       ctx->conn->connection->socket = ctx->sasl_socket;
+       talloc_steal(ctx->conn->connection->socket, ctx->sasl_socket);
+       packet_set_socket(ctx->conn->packet, ctx->sasl_socket);
 }
 
 static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
@@ -190,32 +186,58 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
                errstr = NULL;
        } else if (NT_STATUS_IS_OK(status)) {
                struct auth_session_info *old_session_info;
+               struct ldapsrv_sasl_context *ctx;
 
                result = LDAP_SUCCESS;
                errstr = NULL;
 
-               call->send_callback = ldapsrv_set_sasl;
-               call->send_private = conn;
-               
-               old_session_info = conn->session_info;
-               conn->session_info = NULL;
-               status = gensec_session_info(conn->gensec, &conn->session_info);
-               if (!NT_STATUS_IS_OK(status)) {
+               ctx = talloc(call, struct ldapsrv_sasl_context); 
+
+               if (ctx) {
+                       ctx->conn = conn;
+                       ctx->sasl_socket = gensec_socket_init(conn->gensec, 
+                                                             conn->connection->socket,
+                                                             conn->connection->event.ctx, 
+                                                             stream_io_handler_callback,
+                                                             conn->connection);
+               }
+
+               if (!ctx || !ctx->sasl_socket) {
                        conn->session_info = old_session_info;
                        result = LDAP_OPERATIONS_ERROR;
-                       errstr = talloc_asprintf(reply, "SASL:[%s]: Failed to get session info: %s", req->creds.SASL.mechanism, nt_errstr(status));
+                       errstr = talloc_asprintf(reply, 
+                                                "SASL:[%s]: Failed to setup SASL socket (out of memory)", 
+                                                req->creds.SASL.mechanism);
                } else {
-                       talloc_free(old_session_info);
-                       talloc_steal(conn, conn->session_info);
-
-                       /* don't leak the old LDB */
-                       talloc_free(conn->ldb);
 
-                       status = ldapsrv_backend_Init(conn);            
-                       
+                       call->send_callback = ldapsrv_set_sasl;
+                       call->send_private = ctx;
+               
+                       old_session_info = conn->session_info;
+                       conn->session_info = NULL;
+                       status = gensec_session_info(conn->gensec, &conn->session_info);
                        if (!NT_STATUS_IS_OK(status)) {
+                               conn->session_info = old_session_info;
                                result = LDAP_OPERATIONS_ERROR;
-                               errstr = talloc_asprintf(reply, "SASL:[%s]: Failed to advise samdb of new credentials: %s", req->creds.SASL.mechanism, nt_errstr(status));
+                               errstr = talloc_asprintf(reply, 
+                                                        "SASL:[%s]: Failed to get session info: %s", 
+                                                        req->creds.SASL.mechanism, nt_errstr(status));
+                       } else {
+                               talloc_free(old_session_info);
+                               talloc_steal(conn, conn->session_info);
+                               
+                               /* don't leak the old LDB */
+                               talloc_free(conn->ldb);
+                               
+                               status = ldapsrv_backend_Init(conn);            
+                               
+                               if (!NT_STATUS_IS_OK(status)) {
+                                       result = LDAP_OPERATIONS_ERROR;
+                                       errstr = talloc_asprintf(reply, 
+                                                                "SASL:[%s]: Failed to advise samdb of new credentials: %s", 
+                                                                req->creds.SASL.mechanism, 
+                                                                nt_errstr(status));
+                               }
                        }
                }
        } else {