s4:rpc_server: Allow to use RC4 for setting passwords
authorAndreas Schneider <asn@samba.org>
Fri, 15 Nov 2019 12:49:40 +0000 (13:49 +0100)
committerAndreas Schneider <asn@cryptomilk.org>
Thu, 29 Oct 2020 14:19:36 +0000 (14:19 +0000)
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
source4/rpc_server/samr/samr_password.c
source4/rpc_server/wscript_build

index 52a644176e26f79b53a2cadd7af04bef9704c5d6..83b104fbd0e212c7fde80533fa017d571f2fb89a 100644 (file)
@@ -31,6 +31,8 @@
 #include "../lib/util/util_ldb.h"
 #include "rpc_server/samr/proto.h"
 #include "auth/auth_sam.h"
+#include "lib/param/loadparm.h"
+#include "librpc/rpc/dcerpc_helper.h"
 
 #include "lib/crypto/gnutls_helpers.h"
 #include <gnutls/gnutls.h>
@@ -129,6 +131,8 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
        struct dom_sid *user_objectSid = NULL;
        gnutls_cipher_hd_t cipher_hnd = NULL;
        gnutls_datum_t lm_session_key;
+       struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
+       bool encrypted;
        int rc;
 
        if (pwbuf == NULL) {
@@ -144,6 +148,12 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
                return NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER;
        }
 
+       encrypted = dcerpc_is_transport_encrypted(session_info);
+       if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED &&
+           !encrypted) {
+               return NT_STATUS_ACCESS_DENIED;
+       }
+
        /* Connect to a SAMDB with system privileges for fetching the old pw
         * hashes. */
        sam_ctx = samdb_connect(mem_ctx,
@@ -188,11 +198,13 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
                .size = sizeof(lm_pwd->hash),
        };
 
+       GNUTLS_FIPS140_SET_LAX_MODE();
        rc = gnutls_cipher_init(&cipher_hnd,
                                GNUTLS_CIPHER_ARCFOUR_128,
                                &lm_session_key,
                                NULL);
        if (rc < 0) {
+               GNUTLS_FIPS140_SET_STRICT_MODE();
                status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
                goto failed;
        }
@@ -201,6 +213,7 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
                                   pwbuf->data,
                                   516);
        gnutls_cipher_deinit(cipher_hnd);
+       GNUTLS_FIPS140_SET_STRICT_MODE();
        if (rc < 0) {
                status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
                goto failed;
@@ -607,7 +620,17 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call,
        DATA_BLOB session_key = data_blob(NULL, 0);
        gnutls_cipher_hd_t cipher_hnd = NULL;
        gnutls_datum_t _session_key;
+       struct auth_session_info *session_info =
+               dcesrv_call_session_info(dce_call);
+       struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
        int rc;
+       bool encrypted;
+
+       encrypted = dcerpc_is_transport_encrypted(session_info);
+       if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED &&
+           !encrypted) {
+               return NT_STATUS_ACCESS_DENIED;
+       }
 
        nt_status = dcesrv_transport_session_key(dce_call, &session_key);
        if (!NT_STATUS_IS_OK(nt_status)) {
@@ -621,11 +644,17 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call,
                .size = session_key.length,
        };
 
+       /*
+        * This is safe to support as we only have a session key
+        * over a SMB connection which we force to be encrypted.
+        */
+       GNUTLS_FIPS140_SET_LAX_MODE();
        rc = gnutls_cipher_init(&cipher_hnd,
                                GNUTLS_CIPHER_ARCFOUR_128,
                                &_session_key,
                                NULL);
        if (rc < 0) {
+               GNUTLS_FIPS140_SET_STRICT_MODE();
                nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
                goto out;
        }
@@ -634,6 +663,7 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call,
                                   pwbuf->data,
                                   516);
        gnutls_cipher_deinit(cipher_hnd);
+       GNUTLS_FIPS140_SET_STRICT_MODE();
        if (rc < 0) {
                nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
                goto out;
index de55ad6239aec2145176c52db36d1e4babe0b6c2..c9c1978f22356981bc09b0c67117b3c93b1b3fe8 100644 (file)
@@ -87,7 +87,7 @@ bld.SAMBA_MODULE('dcesrv_samr',
        autoproto='samr/proto.h',
        subsystem='dcerpc_server',
        init_function='dcerpc_server_samr_init',
-       deps='samdb DCERPC_COMMON ndr-standard auth4_sam GNUTLS_HELPERS'
+       deps='samdb DCERPC_COMMON ndr-standard auth4_sam GNUTLS_HELPERS DCERPC_HELPER'
        )