s4:rpc_server: only use context within op_bind() hooks and dcesrv_interface_bind_...
[gd/samba-autobuild/.git] / source4 / rpc_server / backupkey / dcesrv_backupkey_heimdal.c
index 8636e0fd62b950896b9814dd9bc12688be8d3137..05113a9cc74faf2f61bc042d7383816bbdb6775e 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "includes.h"
 #include "rpc_server/dcerpc_server.h"
+#include "rpc_server/common/common.h"
 #include "librpc/gen_ndr/ndr_backupkey.h"
 #include "dsdb/common/util.h"
 #include "dsdb/samdb/samdb.h"
 #include "../libcli/security/security.h"
 #include "librpc/gen_ndr/ndr_security.h"
 #include "lib/crypto/arcfour.h"
+#include "libds/common/roles.h"
 #include <gnutls/gnutls.h>
 #include <gnutls/x509.h>
 #if defined(HAVE_GCRYPT_H) && !defined(HAVE_GNUTLS3)
 #include <gcrypt.h>
 #endif
 
+#define DCESRV_INTERFACE_BACKUPKEY_BIND(call, iface) \
+       dcesrv_interface_backupkey_bind(call, iface)
+static NTSTATUS dcesrv_interface_backupkey_bind(struct dcesrv_call_state *dce_call,
+                                               const struct dcesrv_interface *iface)
+{
+       struct dcesrv_connection_context *context = dce_call->context;
+       return dcesrv_interface_bind_require_privacy(context, iface);
+}
 
 static const unsigned rsa_with_var_num[] = { 1, 2, 840, 113549, 1, 1, 1 };
 /* Equivalent to asn1_oid_id_pkcs1_rsaEncryption*/
@@ -579,6 +589,8 @@ static WERROR bkrp_client_wrap_decrypt_data(struct dcesrv_call_state *dce_call,
                                            struct bkrp_BackupKey *r,
                                            struct ldb_context *ldb_ctx)
 {
+       struct auth_session_info *session_info =
+               dcesrv_call_session_info(dce_call);
        struct bkrp_client_side_wrapped uncrypt_request;
        DATA_BLOB blob;
        enum ndr_err_code ndr_err;
@@ -593,7 +605,7 @@ static WERROR bkrp_client_wrap_decrypt_data(struct dcesrv_call_state *dce_call,
        blob.length = r->in.data_in_len;
 
        if (r->in.data_in_len < 4 || r->in.data_in == NULL) {
-               return WERR_INVALID_PARAM;
+               return WERR_INVALID_PARAMETER;
        }
 
        /*
@@ -610,7 +622,7 @@ static WERROR bkrp_client_wrap_decrypt_data(struct dcesrv_call_state *dce_call,
        ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &uncrypt_request,
                                       (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_wrapped);
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-               return WERR_INVALID_PARAM;
+               return WERR_INVALID_PARAMETER;
        }
 
        if ((uncrypt_request.version != BACKUPKEY_CLIENT_WRAP_VERSION2)
@@ -621,14 +633,14 @@ static WERROR bkrp_client_wrap_decrypt_data(struct dcesrv_call_state *dce_call,
 
        guid_string = GUID_string(mem_ctx, &uncrypt_request.guid);
        if (guid_string == NULL) {
-               return WERR_NOMEM;
+               return WERR_NOT_ENOUGH_MEMORY;
        }
 
        cert_secret_name = talloc_asprintf(mem_ctx,
                                           "BCKUPKEY_%s",
                                           guid_string);
        if (cert_secret_name == NULL) {
-               return WERR_NOMEM;
+               return WERR_NOT_ENOUGH_MEMORY;
        }
 
        status = get_lsa_secret(mem_ctx,
@@ -667,7 +679,7 @@ static WERROR bkrp_client_wrap_decrypt_data(struct dcesrv_call_state *dce_call,
                                                    uncrypt_request.encrypted_secret_len);
                if (reversed_secret.data == NULL) {
                        hx509_private_key_free(&pk);
-                       return WERR_NOMEM;
+                       return WERR_NOT_ENOUGH_MEMORY;
                }
 
                /* The secret has to be reversed ... */
@@ -714,7 +726,7 @@ static WERROR bkrp_client_wrap_decrypt_data(struct dcesrv_call_state *dce_call,
                                                           uncrypted_secretv2.payload_key,
                                                           uncrypt_request.access_check,
                                                           uncrypt_request.access_check_len,
-                                                          dce_call->conn->auth_state.session_info);
+                                                          session_info);
                        if (!W_ERROR_IS_OK(werr)) {
                                return werr;
                        }
@@ -758,7 +770,7 @@ static WERROR bkrp_client_wrap_decrypt_data(struct dcesrv_call_state *dce_call,
                                                           uncrypted_secretv3.payload_key,
                                                           uncrypt_request.access_check,
                                                           uncrypt_request.access_check_len,
-                                                          dce_call->conn->auth_state.session_info);
+                                                          session_info);
                        if (!W_ERROR_IS_OK(werr)) {
                                return werr;
                        }
@@ -821,7 +833,11 @@ static WERROR create_heimdal_rsa_key(TALLOC_CTX *ctx, hx509_context *hctx,
 
        *rsa = NULL;
 
-       gnutls_global_init();
+       ret = gnutls_global_init();
+       if (ret != GNUTLS_E_SUCCESS) {
+               DBG_ERR("TLS error: %s\n", gnutls_strerror(ret));
+               return WERR_INTERNAL_ERROR;
+       }
 #if defined(HAVE_GCRYPT_H) && !defined(HAVE_GNUTLS3)
        DEBUG(3,("Enabling QUICK mode in gcrypt\n"));
        gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0);
@@ -855,7 +871,7 @@ static WERROR create_heimdal_rsa_key(TALLOC_CTX *ctx, hx509_context *hctx,
 
        p0 = talloc_size(ctx, len);
        if (p0 == NULL) {
-               werr = WERR_NOMEM;
+               werr = WERR_NOT_ENOUGH_MEMORY;
                goto done;
        }
        p = p0;
@@ -937,7 +953,7 @@ static WERROR self_sign_cert(TALLOC_CTX *ctx, hx509_context *hctx, hx509_request
 
        uniqueid.data = talloc_memdup(ctx, guidblob->data, guidblob->length);
        if (uniqueid.data == NULL) {
-               return WERR_NOMEM;
+               return WERR_NOT_ENOUGH_MEMORY;
        }
        /* uniqueid is a bit string in which each byte represent 1 bit (1 or 0)
         * so as 1 byte is 8 bits we need to provision 8 times more space as in the
@@ -949,7 +965,7 @@ static WERROR self_sign_cert(TALLOC_CTX *ctx, hx509_context *hctx, hx509_request
                                            guidblob->length);
        if (serialnumber.data == NULL) {
                talloc_free(uniqueid.data);
-               return WERR_NOMEM;
+               return WERR_NOT_ENOUGH_MEMORY;
        }
 
        /* Native AD generates certificates with serialnumber in reversed notation */
@@ -985,10 +1001,6 @@ static WERROR self_sign_cert(TALLOC_CTX *ctx, hx509_context *hctx, hx509_request
        if (ret !=0) {
                goto fail;
        }
-       ret = hx509_ca_tbs_set_ca(*hctx, tbs, 1);
-       if (ret !=0) {
-               goto fail;
-       }
        ret = hx509_ca_tbs_set_notAfter_lifetime(*hctx, tbs, lifetime);
        if (ret !=0) {
                goto fail;
@@ -1373,7 +1385,7 @@ static WERROR generate_bkrp_server_wrap_key(TALLOC_CTX *ctx, struct ldb_context
        secret_name = talloc_asprintf(frame, "BCKUPKEY_%s", GUID_string(ctx, &guid));
        if (secret_name == NULL) {
                TALLOC_FREE(frame);
-               return WERR_NOMEM;
+               return WERR_NOT_ENOUGH_MEMORY;
        }
 
        status = set_lsa_secret(frame, ldb_ctx, secret_name, &blob_wrap_key);
@@ -1426,7 +1438,7 @@ static WERROR bkrp_do_retrieve_server_wrap_key(TALLOC_CTX *mem_ctx, struct ldb_c
 
        secret_name = talloc_asprintf(mem_ctx, "BCKUPKEY_%s", guid_string);
        if (secret_name == NULL) {
-               return WERR_NOMEM;
+               return WERR_NOT_ENOUGH_MEMORY;
        }
 
        status = get_lsa_secret(mem_ctx, ldb_ctx, secret_name, &lsa_secret);
@@ -1488,6 +1500,8 @@ static WERROR bkrp_do_retrieve_default_server_wrap_key(TALLOC_CTX *mem_ctx,
 static WERROR bkrp_server_wrap_decrypt_data(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                            struct bkrp_BackupKey *r ,struct ldb_context *ldb_ctx)
 {
+       struct auth_session_info *session_info =
+               dcesrv_call_session_info(dce_call);
        WERROR werr;
        struct bkrp_server_side_wrapped decrypt_request;
        DATA_BLOB sid_blob, encrypted_blob, symkey_blob;
@@ -1506,17 +1520,17 @@ static WERROR bkrp_server_wrap_decrypt_data(struct dcesrv_call_state *dce_call,
        blob.length = r->in.data_in_len;
 
        if (r->in.data_in_len == 0 || r->in.data_in == NULL) {
-               return WERR_INVALID_PARAM;
+               return WERR_INVALID_PARAMETER;
        }
 
        ndr_err = ndr_pull_struct_blob_all(&blob, mem_ctx, &decrypt_request,
                                           (ndr_pull_flags_fn_t)ndr_pull_bkrp_server_side_wrapped);
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-               return WERR_INVALID_PARAM;
+               return WERR_INVALID_PARAMETER;
        }
 
        if (decrypt_request.magic != BACKUPKEY_SERVER_WRAP_VERSION) {
-               return WERR_INVALID_PARAM;
+               return WERR_INVALID_PARAMETER;
        }
 
        werr = bkrp_do_retrieve_server_wrap_key(mem_ctx, ldb_ctx, &server_key,
@@ -1550,11 +1564,11 @@ static WERROR bkrp_server_wrap_decrypt_data(struct dcesrv_call_state *dce_call,
        ndr_err = ndr_pull_struct_blob_all(&encrypted_blob, mem_ctx, &rc4payload,
                                           (ndr_pull_flags_fn_t)ndr_pull_bkrp_rc4encryptedpayload);
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-               return WERR_INVALID_PARAM;
+               return WERR_INVALID_PARAMETER;
        }
 
        if (decrypt_request.payload_length != rc4payload.secret_data.length) {
-               return WERR_INVALID_PARAM;
+               return WERR_INVALID_PARAMETER;
        }
 
        dump_data_pw("r3: \n", rc4payload.r3, sizeof(rc4payload.r3));
@@ -1591,7 +1605,7 @@ static WERROR bkrp_server_wrap_decrypt_data(struct dcesrv_call_state *dce_call,
                return WERR_INVALID_ACCESS;
        }
 
-       caller_sid = &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
+       caller_sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
 
        if (!dom_sid_equal(&rc4payload.sid, caller_sid)) {
                return WERR_INVALID_ACCESS;
@@ -1614,7 +1628,7 @@ static WERROR bkrp_generic_decrypt_data(struct dcesrv_call_state *dce_call, TALL
                                        struct bkrp_BackupKey *r, struct ldb_context *ldb_ctx)
 {
        if (r->in.data_in_len < 4 || r->in.data_in == NULL) {
-               return WERR_INVALID_PARAM;
+               return WERR_INVALID_PARAMETER;
        }
 
        if (IVAL(r->in.data_in, 0) == BACKUPKEY_SERVER_WRAP_VERSION) {
@@ -1644,6 +1658,8 @@ static WERROR bkrp_generic_decrypt_data(struct dcesrv_call_state *dce_call, TALL
 static WERROR bkrp_server_wrap_encrypt_data(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                            struct bkrp_BackupKey *r ,struct ldb_context *ldb_ctx)
 {
+       struct auth_session_info *session_info =
+               dcesrv_call_session_info(dce_call);
        DATA_BLOB sid_blob, encrypted_blob, symkey_blob, server_wrapped_blob;
        WERROR werr;
        struct dom_sid *caller_sid;
@@ -1658,7 +1674,7 @@ static WERROR bkrp_server_wrap_encrypt_data(struct dcesrv_call_state *dce_call,
        struct GUID guid;
 
        if (r->in.data_in_len == 0 || r->in.data_in == NULL) {
-               return WERR_INVALID_PARAM;
+               return WERR_INVALID_PARAMETER;
        }
 
        werr = bkrp_do_retrieve_default_server_wrap_key(mem_ctx,
@@ -1690,7 +1706,7 @@ static WERROR bkrp_server_wrap_encrypt_data(struct dcesrv_call_state *dce_call,
                }
        }
 
-       caller_sid = &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
+       caller_sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
 
        dump_data_pw("server_key: \n", server_key.key, sizeof(server_key.key));
 
@@ -1786,7 +1802,7 @@ static WERROR bkrp_server_wrap_encrypt_data(struct dcesrv_call_state *dce_call,
 static WERROR dcesrv_bkrp_BackupKey(struct dcesrv_call_state *dce_call,
                                    TALLOC_CTX *mem_ctx, struct bkrp_BackupKey *r)
 {
-       WERROR error = WERR_INVALID_PARAM;
+       WERROR error = WERR_INVALID_PARAMETER;
        struct ldb_context *ldb_ctx;
        bool is_rodc;
        const char *addr = "unknown";
@@ -1806,18 +1822,15 @@ static WERROR dcesrv_bkrp_BackupKey(struct dcesrv_call_state *dce_call,
                return WERR_NOT_SUPPORTED;
        }
 
-       if (!dce_call->conn->auth_state.auth_info ||
-               dce_call->conn->auth_state.auth_info->auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
-               DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
-       }
-
-       ldb_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
-                               dce_call->conn->dce_ctx->lp_ctx,
-                               system_session(dce_call->conn->dce_ctx->lp_ctx), 0);
-
+       /*
+        * Save the current remote session details so they can used by the
+        * audit logging module. This allows the audit logging to report the
+        * remote users details, rather than the system users details.
+        */
+       ldb_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
        if (samdb_rodc(ldb_ctx, &is_rodc) != LDB_SUCCESS) {
                talloc_unlink(mem_ctx, ldb_ctx);
-               return WERR_INVALID_PARAM;
+               return WERR_INVALID_PARAMETER;
        }
 
        if (!is_rodc) {