HACK verify with Authenticate2
authorStefan Metzmacher <metze@samba.org>
Fri, 3 Jan 2014 16:52:10 +0000 (17:52 +0100)
committerStefan Metzmacher <metze@samba.org>
Wed, 11 Apr 2018 07:11:29 +0000 (09:11 +0200)
libcli/auth/netlogon_creds_cli.c

index 72f33bd601432fb11bc63d098a1d16215d3b60b9..7ed1390d28b3bf33c1909d3c76dc5193babc2063 100644 (file)
@@ -409,6 +409,7 @@ NTSTATUS netlogon_creds_cli_context_global(struct loadparm_context *lp_ctx,
 
        if (seal_secure_channel) {
                auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
+               auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
        } else {
                auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
        }
@@ -1470,6 +1471,12 @@ struct netlogon_creds_cli_check_state {
        struct netlogon_creds_CredentialState *creds;
        struct netr_Authenticator req_auth;
        struct netr_Authenticator rep_auth;
+
+       struct {
+               uint32_t negotiate_flags;
+               struct netr_Credential client_credential;
+               struct netr_Credential server_credential;
+       } verify1, verify2, verify3;
 };
 
 static void netlogon_creds_cli_check_cleanup(struct tevent_req *req,
@@ -1584,6 +1591,8 @@ static void netlogon_creds_cli_check_cleanup(struct tevent_req *req,
        TALLOC_FREE(state->creds);
 }
 
+static void netlogon_creds_cli_check_verify(struct tevent_req *req);
+
 static void netlogon_creds_cli_check_caps(struct tevent_req *subreq)
 {
        struct tevent_req *req =
@@ -1612,6 +1621,7 @@ static void netlogon_creds_cli_check_caps(struct tevent_req *subreq)
                         * already, we expect this to work!
                         */
                        status = NT_STATUS_DOWNGRADE_DETECTED;
+DEBUG(0,("%s:%s\n", __location__, __func__));
                        tevent_req_nterror(req, status);
                        netlogon_creds_cli_check_cleanup(req, status);
                        return;
@@ -1627,6 +1637,7 @@ static void netlogon_creds_cli_check_caps(struct tevent_req *subreq)
                         * allowed without "require strong key = no"
                         */
                        status = NT_STATUS_DOWNGRADE_DETECTED;
+DEBUG(0,("%s:%s\n", __location__, __func__));
                        tevent_req_nterror(req, status);
                        netlogon_creds_cli_check_cleanup(req, status);
                        return;
@@ -1646,7 +1657,8 @@ static void netlogon_creds_cli_check_caps(struct tevent_req *subreq)
                 * gets out of sync.
                 */
                netlogon_creds_cli_check_cleanup(req, status);
-               tevent_req_done(req);
+               netlogon_creds_cli_check_verify(req);
+               //tevent_req_done(req);
                return;
        }
        if (tevent_req_nterror(req, status)) {
@@ -1667,11 +1679,11 @@ static void netlogon_creds_cli_check_caps(struct tevent_req *subreq)
                         * already, we expect this to work!
                         */
                        status = NT_STATUS_DOWNGRADE_DETECTED;
+DEBUG(0,("%s:%s\n", __location__, __func__));
                        tevent_req_nterror(req, status);
                        netlogon_creds_cli_check_cleanup(req, status);
                        return;
                }
-
                /*
                 * This is ok, the server does not support
                 * NETLOGON_NEG_SUPPORTS_AES.
@@ -1681,7 +1693,8 @@ static void netlogon_creds_cli_check_caps(struct tevent_req *subreq)
                 * NETLOGON_NEG_SUPPORTS_AES was invented.
                 */
                netlogon_creds_cli_check_cleanup(req, result);
-               tevent_req_done(req);
+               netlogon_creds_cli_check_verify(req);
+               //tevent_req_done(req);
                return;
        }
 
@@ -1700,6 +1713,7 @@ static void netlogon_creds_cli_check_caps(struct tevent_req *subreq)
 
        if (state->caps.server_capabilities != state->creds->negotiate_flags) {
                status = NT_STATUS_DOWNGRADE_DETECTED;
+DEBUG(0,("%s:%s\n", __location__, __func__));
                tevent_req_nterror(req, status);
                netlogon_creds_cli_check_cleanup(req, status);
                return;
@@ -1715,6 +1729,7 @@ static void netlogon_creds_cli_check_caps(struct tevent_req *subreq)
         */
        if (!(state->caps.server_capabilities & NETLOGON_NEG_SUPPORTS_AES)) {
                status = NT_STATUS_DOWNGRADE_DETECTED;
+DEBUG(0,("%s:%s\n", __location__, __func__));
                tevent_req_nterror(req, status);
                netlogon_creds_cli_check_cleanup(req, status);
                return;
@@ -1726,6 +1741,170 @@ static void netlogon_creds_cli_check_caps(struct tevent_req *subreq)
                return;
        }
 
+       netlogon_creds_cli_check_verify(req);
+       //tevent_req_done(req);
+}
+
+static void netlogon_creds_cli_check_verify1(struct tevent_req *subreq);
+
+static void netlogon_creds_cli_check_verify(struct tevent_req *req)
+{
+       struct netlogon_creds_cli_check_state *state =
+               tevent_req_data(req,
+               struct netlogon_creds_cli_check_state);
+       struct tevent_req *subreq;
+
+       state->verify1.negotiate_flags = UINT32_MAX;
+       subreq = dcerpc_netr_ServerAuthenticate2_send(state, state->ev,
+                                               state->binding_handle,
+                                               state->srv_name_slash,
+                                               "__samba_verify1_no_account__",
+                                               SEC_CHAN_NULL,
+                                               "__samba_verify1_no_computer__",
+                                               &state->verify1.client_credential,
+                                               &state->verify1.server_credential,
+                                               &state->verify1.negotiate_flags);       
+       if (tevent_req_nomem(subreq, req)) {
+               return;
+       }
+       tevent_req_set_callback(subreq,
+                               netlogon_creds_cli_check_verify1,
+                               req);
+}
+
+static void netlogon_creds_cli_check_verify2(struct tevent_req *subreq);
+
+static void netlogon_creds_cli_check_verify1(struct tevent_req *subreq)
+{
+       struct tevent_req *req =
+               tevent_req_callback_data(subreq,
+               struct tevent_req);
+       struct netlogon_creds_cli_check_state *state =
+               tevent_req_data(req,
+               struct netlogon_creds_cli_check_state);
+       NTSTATUS status;
+       NTSTATUS result;
+
+       status = dcerpc_netr_ServerAuthenticate2_recv(subreq, state,
+                                                     &result);
+       TALLOC_FREE(subreq);
+       if (tevent_req_nterror(req, status)) {
+               return;
+       }
+       if (NT_STATUS_IS_OK(result)) {
+               result = NT_STATUS_DOWNGRADE_DETECTED;
+DEBUG(0,("%s:%s\n", __location__, __func__));
+               tevent_req_nterror(req, result);
+               return;
+       }
+       if (!NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) {
+               //tevent_req_nterror(req, result);
+               //return;
+       }
+
+       state->verify2.negotiate_flags = 0;
+       subreq = dcerpc_netr_ServerAuthenticate2_send(state, state->ev,
+                                               state->binding_handle,
+                                               state->srv_name_slash,
+                                               "__samba_verify2_no_account__",
+                                               SEC_CHAN_NULL,
+                                               "__samba_verify2_no_computer__",
+                                               &state->verify2.client_credential,
+                                               &state->verify2.server_credential,
+                                               &state->verify2.negotiate_flags);       
+       if (tevent_req_nomem(subreq, req)) {
+               status = NT_STATUS_NO_MEMORY;
+               return;
+       }
+       tevent_req_set_callback(subreq,
+                               netlogon_creds_cli_check_verify2,
+                               req);
+}
+
+static void netlogon_creds_cli_check_verify3(struct tevent_req *subreq);
+
+static void netlogon_creds_cli_check_verify2(struct tevent_req *subreq)
+{
+       struct tevent_req *req =
+               tevent_req_callback_data(subreq,
+               struct tevent_req);
+       struct netlogon_creds_cli_check_state *state =
+               tevent_req_data(req,
+               struct netlogon_creds_cli_check_state);
+       NTSTATUS status;
+       NTSTATUS result;
+
+       status = dcerpc_netr_ServerAuthenticate2_recv(subreq, state,
+                                                     &result);
+       TALLOC_FREE(subreq);
+       if (tevent_req_nterror(req, status)) {
+               return;
+       }
+       if (NT_STATUS_IS_OK(result)) {
+               result = NT_STATUS_DOWNGRADE_DETECTED;
+DEBUG(0,("%s:%s\n", __location__, __func__));
+               tevent_req_nterror(req, result);
+               return;
+       }
+       if (!NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) {
+       }
+
+       state->verify3.negotiate_flags = state->context->client.proposed_flags;
+       subreq = dcerpc_netr_ServerAuthenticate2_send(state, state->ev,
+                                               state->binding_handle,
+                                               state->srv_name_slash,
+                                               "__samba_verify3_no_account__",
+                                               SEC_CHAN_NULL,
+                                               "__samba_verify3_no_computer__",
+                                               &state->verify3.client_credential,
+                                               &state->verify3.server_credential,
+                                               &state->verify3.negotiate_flags);       
+       if (tevent_req_nomem(subreq, req)) {
+               status = NT_STATUS_NO_MEMORY;
+               return;
+       }
+       tevent_req_set_callback(subreq,
+                               netlogon_creds_cli_check_verify3,
+                               req);
+}
+
+static void netlogon_creds_cli_check_verify3(struct tevent_req *subreq)
+{
+       struct tevent_req *req =
+               tevent_req_callback_data(subreq,
+               struct tevent_req);
+       struct netlogon_creds_cli_check_state *state =
+               tevent_req_data(req,
+               struct netlogon_creds_cli_check_state);
+       NTSTATUS status;
+       NTSTATUS result;
+
+       status = dcerpc_netr_ServerAuthenticate2_recv(subreq, state,
+                                                     &result);
+       TALLOC_FREE(subreq);
+       if (tevent_req_nterror(req, status)) {
+               return;
+       }
+       if (NT_STATUS_IS_OK(result)) {
+               result = NT_STATUS_DOWNGRADE_DETECTED;
+DEBUG(0,("%s:%s\n", __location__, __func__));
+               tevent_req_nterror(req, result);
+               return;
+       }
+       if (!NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) {
+       }
+
+       DEBUG(0, ("domain[%s] flags: proposed[0x%08X] required[0x%08X] client[0x%08X] "
+                 "server[0x%08X] verify1[0x%08X] verify2[0x%08X] verify3[0x%08X]\n",
+                 state->context->server.netbios_domain,
+                 (unsigned int)state->context->client.proposed_flags,
+                 (unsigned int)state->context->client.required_flags,
+                 (unsigned int)state->tmp_creds.negotiate_flags,
+                 (unsigned int)state->caps.server_capabilities,
+                 (unsigned int)state->verify1.negotiate_flags,
+                 (unsigned int)state->verify2.negotiate_flags,
+                 (unsigned int)state->verify3.negotiate_flags));
+
        tevent_req_done(req);
 }