r24504: Try to return more useful error information on why a bind failed.
authorAndrew Bartlett <abartlet@samba.org>
Fri, 17 Aug 2007 05:28:39 +0000 (05:28 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 20:02:03 +0000 (15:02 -0500)
Note that the correct return for a failed alter_context is a fault,
not a bind_nak.

Andrew Bartlett
(This used to be commit 52cce94532edf1dd7f26e39bf3377f0077ea6792)

source4/auth/gensec/schannel.c
source4/rpc_server/dcerpc_server.c
source4/rpc_server/dcesrv_auth.c

index bc616dc64ec58019121e4fa5f0250395735dbe5d..5dc5c287eca1db092af0d958ac4339a0e45edf71 100644 (file)
@@ -102,6 +102,8 @@ static NTSTATUS schannel_update(struct gensec_security *gensec_security, TALLOC_
                status = ndr_pull_struct_blob(&in, out_mem_ctx, &bind_schannel, 
                                              (ndr_pull_flags_fn_t)ndr_pull_schannel_bind);
                if (!NT_STATUS_IS_OK(status)) {
+                       DEBUG(3, ("Could not parse incoming schannel bind: %s\n",
+                                 nt_errstr(status)));
                        return status;
                }
                
@@ -119,6 +121,9 @@ static NTSTATUS schannel_update(struct gensec_security *gensec_security, TALLOC_
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(3, ("Could not find session key for attempted schannel connection from %s: %s\n",
                                  workstation, nt_errstr(status)));
+                       if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
+                               return NT_STATUS_LOGON_FAILURE;
+                       }
                        return status;
                }
 
index f9d1606df800555ea2f93cae4cd96d2d6417428c..35b37b3af6c070372b19e513d091c0cbe34162be 100644 (file)
@@ -620,7 +620,8 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
        pkt.u.bind_ack.ctx_list[0].syntax = ndr_transfer_syntax;
        pkt.u.bind_ack.auth_info = data_blob(NULL, 0);
 
-       if (!dcesrv_auth_bind_ack(call, &pkt)) {
+       status = dcesrv_auth_bind_ack(call, &pkt);
+       if (!NT_STATUS_IS_OK(status)) {
                return dcesrv_bind_nak(call, 0);
        }
 
@@ -769,8 +770,15 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
        pkt.u.alter_resp.auth_info = data_blob(NULL, 0);
        pkt.u.alter_resp.secondary_address = "";
 
-       if (!dcesrv_auth_alter_ack(call, &pkt)) {
-               return dcesrv_bind_nak(call, 0);
+       status = dcesrv_auth_alter_ack(call, &pkt);
+       if (!NT_STATUS_IS_OK(status)) {
+               if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)
+                   || NT_STATUS_EQUAL(status, NT_STATUS_LOGON_FAILURE)
+                   || NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)
+                   || NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
+                       return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
+               }
+               return dcesrv_fault(call, 0);
        }
 
        rep = talloc(call, struct data_blob_list_item);
index 10405bb56f53bf302509a044322223346e890589..627da844aaf5912055f41f616d107edf38b874df 100644 (file)
@@ -98,13 +98,13 @@ BOOL dcesrv_auth_bind(struct dcesrv_call_state *call)
   add any auth information needed in a bind ack, and process the authentication
   information found in the bind.
 */
-BOOL dcesrv_auth_bind_ack(struct dcesrv_call_state *call, struct ncacn_packet *pkt)
+NTSTATUS dcesrv_auth_bind_ack(struct dcesrv_call_state *call, struct ncacn_packet *pkt)
 {
        struct dcesrv_connection *dce_conn = call->conn;
        NTSTATUS status;
 
        if (!call->conn->auth_state.gensec_security) {
-               return True;
+               return NT_STATUS_OK;
        }
 
        status = gensec_update(dce_conn->auth_state.gensec_security,
@@ -117,19 +117,19 @@ BOOL dcesrv_auth_bind_ack(struct dcesrv_call_state *call, struct ncacn_packet *p
                                             &dce_conn->auth_state.session_info);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(1, ("Failed to establish session_info: %s\n", nt_errstr(status)));
-                       return False;
+                       return status;
                }
 
                /* Now that we are authenticated, go back to the generic session key... */
                dce_conn->auth_state.session_key = dcesrv_generic_session_key;
-               return True;
+               return NT_STATUS_OK;
        } else if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
                dce_conn->auth_state.auth_info->auth_pad_length = 0;
                dce_conn->auth_state.auth_info->auth_reserved = 0;
-               return True;
+               return NT_STATUS_OK;
        } else {
                DEBUG(2, ("Failed to start dcesrv auth negotiate: %s\n", nt_errstr(status)));
-               return False;
+               return status;
        }
 }
 
@@ -223,7 +223,7 @@ BOOL dcesrv_auth_alter(struct dcesrv_call_state *call)
   add any auth information needed in a alter ack, and process the authentication
   information found in the alter.
 */
-BOOL dcesrv_auth_alter_ack(struct dcesrv_call_state *call, struct ncacn_packet *pkt)
+NTSTATUS dcesrv_auth_alter_ack(struct dcesrv_call_state *call, struct ncacn_packet *pkt)
 {
        struct dcesrv_connection *dce_conn = call->conn;
        NTSTATUS status;
@@ -232,11 +232,11 @@ BOOL dcesrv_auth_alter_ack(struct dcesrv_call_state *call, struct ncacn_packet *
           setup */
        if (!call->conn->auth_state.auth_info ||
            dce_conn->auth_state.auth_info->credentials.length == 0) {
-               return True;
+               return NT_STATUS_OK;
        }
 
        if (!call->conn->auth_state.gensec_security) {
-               return False;
+               return NT_STATUS_INVALID_PARAMETER;
        }
 
        status = gensec_update(dce_conn->auth_state.gensec_security,
@@ -249,20 +249,20 @@ BOOL dcesrv_auth_alter_ack(struct dcesrv_call_state *call, struct ncacn_packet *
                                             &dce_conn->auth_state.session_info);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(1, ("Failed to establish session_info: %s\n", nt_errstr(status)));
-                       return False;
+                       return status;
                }
 
                /* Now that we are authenticated, got back to the generic session key... */
                dce_conn->auth_state.session_key = dcesrv_generic_session_key;
-               return True;
+               return NT_STATUS_OK;
        } else if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
                dce_conn->auth_state.auth_info->auth_pad_length = 0;
                dce_conn->auth_state.auth_info->auth_reserved = 0;
-               return True;
+               return NT_STATUS_OK;
        }
 
        DEBUG(2, ("Failed to finish dcesrv auth alter_ack: %s\n", nt_errstr(status)));
-       return False;
+       return status;
 }
 
 /*