libcli:auth: Allow to connect to netlogon server offering only AES
authorAndreas Schneider <asn@samba.org>
Thu, 18 Nov 2021 12:46:26 +0000 (13:46 +0100)
committerAndreas Schneider <asn@cryptomilk.org>
Thu, 2 Dec 2021 14:49:35 +0000 (14:49 +0000)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14912

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org>
Autobuild-Date(master): Thu Dec  2 14:49:35 UTC 2021 on sn-devel-184

libcli/auth/netlogon_creds_cli.c
selftest/knownfail.d/rpcclient_schannel [deleted file]

index beab2fae53a01cd32a8f843efacc6487bf53ee9d..e92a042c01203265846a0fc6977f9db871cff1d7 100644 (file)
@@ -516,9 +516,33 @@ enum dcerpc_AuthLevel netlogon_creds_cli_auth_level(
        return context->client.auth_level;
 }
 
+static bool netlogon_creds_cli_downgraded(uint32_t negotiated_flags,
+                                         uint32_t proposed_flags,
+                                         uint32_t required_flags)
+{
+       uint32_t req_flags = required_flags;
+       uint32_t tmp_flags;
+
+       req_flags = required_flags;
+       if ((negotiated_flags & NETLOGON_NEG_SUPPORTS_AES) &&
+           (proposed_flags & NETLOGON_NEG_SUPPORTS_AES))
+       {
+               req_flags &= ~NETLOGON_NEG_ARCFOUR|NETLOGON_NEG_STRONG_KEYS;
+       }
+
+       tmp_flags = negotiated_flags;
+       tmp_flags &= req_flags;
+       if (tmp_flags != req_flags) {
+               return true;
+       }
+
+       return false;
+}
+
 struct netlogon_creds_cli_fetch_state {
        TALLOC_CTX *mem_ctx;
        struct netlogon_creds_CredentialState *creds;
+       uint32_t proposed_flags;
        uint32_t required_flags;
        NTSTATUS status;
 };
@@ -530,7 +554,7 @@ static void netlogon_creds_cli_fetch_parser(TDB_DATA key, TDB_DATA data,
                (struct netlogon_creds_cli_fetch_state *)private_data;
        enum ndr_err_code ndr_err;
        DATA_BLOB blob;
-       uint32_t tmp_flags;
+       bool downgraded;
 
        state->creds = talloc_zero(state->mem_ctx,
                                   struct netlogon_creds_CredentialState);
@@ -554,9 +578,11 @@ static void netlogon_creds_cli_fetch_parser(TDB_DATA key, TDB_DATA data,
                NDR_PRINT_DEBUG(netlogon_creds_CredentialState, state->creds);
        }
 
-       tmp_flags = state->creds->negotiate_flags;
-       tmp_flags &= state->required_flags;
-       if (tmp_flags != state->required_flags) {
+       downgraded = netlogon_creds_cli_downgraded(
+                       state->creds->negotiate_flags,
+                       state->proposed_flags,
+                       state->required_flags);
+       if (downgraded) {
                TALLOC_FREE(state->creds);
                state->status = NT_STATUS_DOWNGRADE_DETECTED;
                return;
@@ -827,6 +853,7 @@ static NTSTATUS netlogon_creds_cli_get_internal(
 {
        struct netlogon_creds_cli_fetch_state fstate = {
                .status = NT_STATUS_INTERNAL_ERROR,
+               .proposed_flags = context->client.proposed_flags,
                .required_flags = context->client.required_flags,
        };
        NTSTATUS status;
@@ -1309,7 +1336,7 @@ static void netlogon_creds_cli_auth_srvauth_done(struct tevent_req *subreq)
        enum ndr_err_code ndr_err;
        DATA_BLOB blob;
        TDB_DATA data;
-       uint32_t tmp_flags;
+       bool downgraded;
 
        if (state->try_auth3) {
                status = dcerpc_netr_ServerAuthenticate3_recv(subreq, state,
@@ -1356,9 +1383,11 @@ static void netlogon_creds_cli_auth_srvauth_done(struct tevent_req *subreq)
                return;
        }
 
-       tmp_flags = state->creds->negotiate_flags;
-       tmp_flags &= state->context->client.required_flags;
-       if (tmp_flags != state->context->client.required_flags) {
+       downgraded = netlogon_creds_cli_downgraded(
+                       state->creds->negotiate_flags,
+                       state->context->client.proposed_flags,
+                       state->context->client.required_flags);
+       if (downgraded) {
                if (NT_STATUS_IS_OK(result)) {
                        tevent_req_nterror(req, NT_STATUS_DOWNGRADE_DETECTED);
                        return;
@@ -1368,8 +1397,7 @@ static void netlogon_creds_cli_auth_srvauth_done(struct tevent_req *subreq)
        }
 
        if (NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) {
-
-               tmp_flags = state->context->client.proposed_flags;
+               uint32_t tmp_flags = state->context->client.proposed_flags;
                if ((state->current_flags == tmp_flags) &&
                    (state->creds->negotiate_flags != tmp_flags))
                {
diff --git a/selftest/knownfail.d/rpcclient_schannel b/selftest/knownfail.d/rpcclient_schannel
deleted file mode 100644 (file)
index 5498837..0000000
+++ /dev/null
@@ -1 +0,0 @@
-^samba.blackbox.rpcclient_schannel.ncacn_np.getusername.fips\(ad_member_fips:local\)