LCOV - code coverage report
Current view: top level - source4/rpc_server/backupkey - dcesrv_backupkey.c (source / functions) Hit Total Coverage
Test: coverage report for master 469b22b8 Lines: 582 938 62.0 %
Date: 2024-06-10 12:05:21 Functions: 19 19 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    endpoint server for the backupkey interface
       5             : 
       6             :    Copyright (C) Matthieu Patou <mat@samba.org> 2010
       7             :    Copyright (C) Andreas Schneider <asn@samba.org> 2015
       8             : 
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "includes.h"
      24             : #include "rpc_server/dcerpc_server.h"
      25             : #include "rpc_server/common/common.h"
      26             : #include "librpc/gen_ndr/ndr_backupkey.h"
      27             : #include "dsdb/common/util.h"
      28             : #include "dsdb/samdb/samdb.h"
      29             : #include "lib/ldb/include/ldb_errors.h"
      30             : #include "../lib/util/util_ldb.h"
      31             : #include "param/param.h"
      32             : #include "auth/session.h"
      33             : #include "system/network.h"
      34             : 
      35             : #include "../lib/tsocket/tsocket.h"
      36             : #include "../libcli/security/security.h"
      37             : #include "librpc/gen_ndr/ndr_security.h"
      38             : #include "libds/common/roles.h"
      39             : 
      40             : #include <gnutls/gnutls.h>
      41             : #include <gnutls/x509.h>
      42             : #include <gnutls/crypto.h>
      43             : #include <gnutls/abstract.h>
      44             : 
      45             : #include "lib/crypto/gnutls_helpers.h"
      46             : 
      47             : #undef strncasecmp
      48             : 
      49             : #define DCESRV_INTERFACE_BACKUPKEY_BIND(context, iface) \
      50             :         dcesrv_interface_backupkey_bind(context, iface)
      51           5 : static NTSTATUS dcesrv_interface_backupkey_bind(struct dcesrv_connection_context *context,
      52             :                                                 const struct dcesrv_interface *iface)
      53             : {
      54           5 :         return dcesrv_interface_bind_require_privacy(context, iface);
      55             : }
      56             : 
      57           4 : static NTSTATUS set_lsa_secret(TALLOC_CTX *mem_ctx,
      58             :                                struct ldb_context *ldb,
      59             :                                const char *name,
      60             :                                const DATA_BLOB *lsa_secret)
      61             : {
      62           4 :         TALLOC_CTX *frame = talloc_stackframe();
      63           0 :         struct ldb_message *msg;
      64           0 :         struct ldb_result *res;
      65           4 :         struct ldb_dn *system_dn = NULL;
      66           0 :         struct ldb_val val;
      67           0 :         int ret;
      68           0 :         char *name2;
      69           4 :         struct timeval now = timeval_current();
      70           4 :         NTTIME nt_now = timeval_to_nttime(&now);
      71           4 :         const char *attrs[] = {
      72             :                 NULL
      73             :         };
      74             : 
      75           4 :         msg = ldb_msg_new(frame);
      76           4 :         if (msg == NULL) {
      77           0 :                 talloc_free(frame);
      78           0 :                 return NT_STATUS_NO_MEMORY;
      79             :         }
      80             : 
      81             :         /*
      82             :          * This function is a lot like dcesrv_lsa_CreateSecret
      83             :          * in the rpc_server/lsa directory
      84             :          * The reason why we duplicate the effort here is that:
      85             :          * * we want to keep the former function static
      86             :          * * we want to avoid the burden of doing LSA calls
      87             :          *   when we can just manipulate the secrets directly
      88             :          * * taillor the function to the particular needs of backup protocol
      89             :          */
      90             : 
      91           4 :         system_dn = samdb_system_container_dn(ldb, frame);
      92           4 :         if (system_dn == NULL) {
      93           0 :                 talloc_free(frame);
      94           0 :                 return NT_STATUS_NO_MEMORY;
      95             :         }
      96             : 
      97           4 :         name2 = talloc_asprintf(msg, "%s Secret", name);
      98           4 :         if (name2 == NULL) {
      99           0 :                 talloc_free(frame);
     100           0 :                 return NT_STATUS_NO_MEMORY;
     101             :         }
     102             : 
     103           4 :         ret = ldb_search(ldb, frame, &res, system_dn, LDB_SCOPE_SUBTREE, attrs,
     104             :                            "(&(cn=%s)(objectclass=secret))",
     105             :                            ldb_binary_encode_string(frame, name2));
     106             : 
     107           4 :         if (ret != LDB_SUCCESS ||  res->count != 0 ) {
     108           0 :                 DEBUG(2, ("Secret %s already exists !\n", name2));
     109           0 :                 talloc_free(frame);
     110           0 :                 return NT_STATUS_OBJECT_NAME_COLLISION;
     111             :         }
     112             : 
     113             :         /*
     114             :          * We don't care about previous value as we are
     115             :          * here only if the key didn't exists before
     116             :          */
     117             : 
     118           4 :         msg->dn = ldb_dn_copy(frame, system_dn);
     119           4 :         if (msg->dn == NULL) {
     120           0 :                 talloc_free(frame);
     121           0 :                 return NT_STATUS_NO_MEMORY;
     122             :         }
     123           4 :         if (!ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
     124           0 :                 talloc_free(frame);
     125           0 :                 return NT_STATUS_NO_MEMORY;
     126             :         }
     127             : 
     128           4 :         ret = ldb_msg_add_string(msg, "cn", name2);
     129           4 :         if (ret != LDB_SUCCESS) {
     130           0 :                 talloc_free(frame);
     131           0 :                 return NT_STATUS_NO_MEMORY;
     132             :         }
     133           4 :         ret = ldb_msg_add_string(msg, "objectClass", "secret");
     134           4 :         if (ret != LDB_SUCCESS) {
     135           0 :                 talloc_free(frame);
     136           0 :                 return NT_STATUS_NO_MEMORY;
     137             :         }
     138           4 :         ret = samdb_msg_add_uint64(ldb, frame, msg, "priorSetTime", nt_now);
     139           4 :         if (ret != LDB_SUCCESS) {
     140           0 :                 talloc_free(frame);
     141           0 :                 return NT_STATUS_NO_MEMORY;
     142             :         }
     143           4 :         val.data = lsa_secret->data;
     144           4 :         val.length = lsa_secret->length;
     145           4 :         ret = ldb_msg_add_value(msg, "currentValue", &val, NULL);
     146           4 :         if (ret != LDB_SUCCESS) {
     147           0 :                 talloc_free(frame);
     148           0 :                 return NT_STATUS_NO_MEMORY;
     149             :         }
     150           4 :         ret = samdb_msg_add_uint64(ldb, frame, msg, "lastSetTime", nt_now);
     151           4 :         if (ret != LDB_SUCCESS) {
     152           0 :                 talloc_free(frame);
     153           0 :                 return NT_STATUS_NO_MEMORY;
     154             :         }
     155             : 
     156             :         /*
     157             :          * create the secret with DSDB_MODIFY_RELAX
     158             :          * otherwise dsdb/samdb/ldb_modules/objectclass.c forbid
     159             :          * the create of LSA secret object
     160             :          */
     161           4 :         ret = dsdb_add(ldb, msg, DSDB_MODIFY_RELAX);
     162           4 :         if (ret != LDB_SUCCESS) {
     163           0 :                 DEBUG(2,("Failed to create secret record %s: %s\n",
     164             :                         ldb_dn_get_linearized(msg->dn),
     165             :                         ldb_errstring(ldb)));
     166           0 :                 talloc_free(frame);
     167           0 :                 return NT_STATUS_ACCESS_DENIED;
     168             :         }
     169             : 
     170           4 :         talloc_free(frame);
     171           4 :         return NT_STATUS_OK;
     172             : }
     173             : 
     174             : /* This function is pretty much like dcesrv_lsa_QuerySecret */
     175          81 : static NTSTATUS get_lsa_secret(TALLOC_CTX *mem_ctx,
     176             :                                struct ldb_context *ldb,
     177             :                                const char *name,
     178             :                                DATA_BLOB *lsa_secret)
     179             : {
     180           0 :         TALLOC_CTX *tmp_mem;
     181           0 :         struct ldb_result *res;
     182          81 :         struct ldb_dn *system_dn = NULL;
     183           0 :         const struct ldb_val *val;
     184           0 :         uint8_t *data;
     185          81 :         const char *attrs[] = {
     186             :                 "currentValue",
     187             :                 NULL
     188             :         };
     189           0 :         int ret;
     190             : 
     191          81 :         lsa_secret->data = NULL;
     192          81 :         lsa_secret->length = 0;
     193             : 
     194          81 :         tmp_mem = talloc_new(mem_ctx);
     195          81 :         if (tmp_mem == NULL) {
     196           0 :                 return NT_STATUS_NO_MEMORY;
     197             :         }
     198             : 
     199          81 :         system_dn = samdb_system_container_dn(ldb, tmp_mem);
     200          81 :         if (system_dn == NULL) {
     201           0 :                 talloc_free(tmp_mem);
     202           0 :                 return NT_STATUS_NO_MEMORY;
     203             :         }
     204             : 
     205          81 :         ret = ldb_search(ldb, tmp_mem, &res, system_dn, LDB_SCOPE_SUBTREE, attrs,
     206             :                            "(&(cn=%s Secret)(objectclass=secret))",
     207             :                            ldb_binary_encode_string(tmp_mem, name));
     208             : 
     209          81 :         if (ret != LDB_SUCCESS) {
     210           0 :                 talloc_free(tmp_mem);
     211           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
     212             :         }
     213          81 :         if (res->count == 0) {
     214           5 :                 talloc_free(tmp_mem);
     215           5 :                 return NT_STATUS_RESOURCE_NAME_NOT_FOUND;
     216             :         }
     217          76 :         if (res->count > 1) {
     218           0 :                 DEBUG(2, ("Secret %s collision\n", name));
     219           0 :                 talloc_free(tmp_mem);
     220           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
     221             :         }
     222             : 
     223          76 :         val = ldb_msg_find_ldb_val(res->msgs[0], "currentValue");
     224          76 :         if (val == NULL) {
     225             :                 /*
     226             :                  * The secret object is here but we don't have the secret value
     227             :                  * The most common case is a RODC
     228             :                  */
     229           0 :                 *lsa_secret = data_blob_null;
     230           0 :                 talloc_free(tmp_mem);
     231           0 :                 return NT_STATUS_OK;
     232             :         }
     233             : 
     234          76 :         data = val->data;
     235          76 :         lsa_secret->data = talloc_move(mem_ctx, &data);
     236          76 :         lsa_secret->length = val->length;
     237             : 
     238          76 :         talloc_free(tmp_mem);
     239          76 :         return NT_STATUS_OK;
     240             : }
     241             : 
     242          64 : static int reverse_and_get_bignum(TALLOC_CTX *mem_ctx,
     243             :                                   DATA_BLOB blob,
     244             :                                   gnutls_datum_t *datum)
     245             : {
     246           0 :         uint32_t i;
     247             : 
     248          64 :         datum->data = talloc_array(mem_ctx, uint8_t, blob.length);
     249          64 :         if (datum->data == NULL) {
     250           0 :                 return -1;
     251             :         }
     252             : 
     253        9312 :         for(i = 0; i < blob.length; i++) {
     254        9248 :                 datum->data[i] = blob.data[blob.length - i - 1];
     255             :         }
     256          64 :         datum->size = blob.length;
     257             : 
     258          64 :         return 0;
     259             : }
     260             : 
     261           8 : static NTSTATUS get_pk_from_raw_keypair_params(TALLOC_CTX *ctx,
     262             :                                 struct bkrp_exported_RSA_key_pair *keypair,
     263             :                                 gnutls_privkey_t *pk)
     264             : {
     265           8 :         gnutls_x509_privkey_t x509_privkey = NULL;
     266           8 :         gnutls_privkey_t privkey = NULL;
     267           0 :         gnutls_datum_t m, e, d, p, q, u, e1, e2;
     268           0 :         int rc;
     269             : 
     270           8 :         rc = reverse_and_get_bignum(ctx, keypair->modulus, &m);
     271           8 :         if (rc != 0) {
     272           0 :                 return NT_STATUS_INVALID_PARAMETER;
     273             :         }
     274           8 :         rc = reverse_and_get_bignum(ctx, keypair->public_exponent, &e);
     275           8 :         if (rc != 0) {
     276           0 :                 return NT_STATUS_INVALID_PARAMETER;
     277             :         }
     278           8 :         rc = reverse_and_get_bignum(ctx, keypair->private_exponent, &d);
     279           8 :         if (rc != 0) {
     280           0 :                 return NT_STATUS_INVALID_PARAMETER;
     281             :         }
     282             : 
     283           8 :         rc = reverse_and_get_bignum(ctx, keypair->prime1, &p);
     284           8 :         if (rc != 0) {
     285           0 :                 return NT_STATUS_INVALID_PARAMETER;
     286             :         }
     287           8 :         rc = reverse_and_get_bignum(ctx, keypair->prime2, &q);
     288           8 :         if (rc != 0) {
     289           0 :                 return NT_STATUS_INVALID_PARAMETER;
     290             :         }
     291             : 
     292           8 :         rc = reverse_and_get_bignum(ctx, keypair->coefficient, &u);
     293           8 :         if (rc != 0) {
     294           0 :                 return NT_STATUS_INVALID_PARAMETER;
     295             :         }
     296             : 
     297           8 :         rc = reverse_and_get_bignum(ctx, keypair->exponent1, &e1);
     298           8 :         if (rc != 0) {
     299           0 :                 return NT_STATUS_INVALID_PARAMETER;
     300             :         }
     301           8 :         rc = reverse_and_get_bignum(ctx, keypair->exponent2, &e2);
     302           8 :         if (rc != 0) {
     303           0 :                 return NT_STATUS_INVALID_PARAMETER;
     304             :         }
     305             : 
     306           8 :         rc = gnutls_x509_privkey_init(&x509_privkey);
     307           8 :         if (rc != GNUTLS_E_SUCCESS) {
     308           0 :                 DBG_ERR("gnutls_x509_privkey_init failed - %s\n",
     309             :                         gnutls_strerror(rc));
     310           0 :                 return NT_STATUS_INTERNAL_ERROR;
     311             :         }
     312             : 
     313           8 :         rc = gnutls_x509_privkey_import_rsa_raw2(x509_privkey,
     314             :                                                  &m,
     315             :                                                  &e,
     316             :                                                  &d,
     317             :                                                  &p,
     318             :                                                  &q,
     319             :                                                  &u,
     320             :                                                  &e1,
     321             :                                                  &e2);
     322           8 :         if (rc != GNUTLS_E_SUCCESS) {
     323           0 :                 DBG_ERR("gnutls_x509_privkey_import_rsa_raw2 failed - %s\n",
     324             :                         gnutls_strerror(rc));
     325           0 :                 return NT_STATUS_INTERNAL_ERROR;
     326             :         }
     327             : 
     328           8 :         rc = gnutls_privkey_init(&privkey);
     329           8 :         if (rc != GNUTLS_E_SUCCESS) {
     330           0 :                 DBG_ERR("gnutls_privkey_init failed - %s\n",
     331             :                         gnutls_strerror(rc));
     332           0 :                 gnutls_x509_privkey_deinit(x509_privkey);
     333           0 :                 return NT_STATUS_INTERNAL_ERROR;
     334             :         }
     335             : 
     336           8 :         rc = gnutls_privkey_import_x509(privkey,
     337             :                                         x509_privkey,
     338             :                                         GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
     339           8 :         if (rc != GNUTLS_E_SUCCESS) {
     340           0 :                 DBG_ERR("gnutls_privkey_import_x509 failed - %s\n",
     341             :                         gnutls_strerror(rc));
     342           0 :                 gnutls_x509_privkey_deinit(x509_privkey);
     343           0 :                 return NT_STATUS_INTERNAL_ERROR;
     344             :         }
     345             : 
     346           8 :         *pk = privkey;
     347             : 
     348           8 :         return NT_STATUS_OK;
     349             : }
     350             : 
     351           6 : static WERROR get_and_verify_access_check(TALLOC_CTX *sub_ctx,
     352             :                                           uint32_t version,
     353             :                                           uint8_t *key_and_iv,
     354             :                                           uint8_t *access_check,
     355             :                                           uint32_t access_check_len,
     356             :                                           struct auth_session_info *session_info)
     357             : {
     358           0 :         struct bkrp_access_check_v2 uncrypted_accesscheckv2;
     359           0 :         struct bkrp_access_check_v3 uncrypted_accesscheckv3;
     360           6 :         gnutls_cipher_hd_t cipher_handle = { 0 };
     361           0 :         gnutls_cipher_algorithm_t cipher_algo;
     362           0 :         DATA_BLOB blob_us;
     363           0 :         enum ndr_err_code ndr_err;
     364           0 :         gnutls_datum_t key;
     365           0 :         gnutls_datum_t iv;
     366             : 
     367           6 :         struct dom_sid *access_sid = NULL;
     368           6 :         struct dom_sid *caller_sid = NULL;
     369           0 :         int rc;
     370             : 
     371           6 :         switch (version) {
     372           5 :         case 2:
     373           5 :                 cipher_algo = GNUTLS_CIPHER_3DES_CBC;
     374           5 :                 break;
     375           1 :         case 3:
     376           1 :                 cipher_algo = GNUTLS_CIPHER_AES_256_CBC;
     377           1 :                 break;
     378           0 :         default:
     379           0 :                 return WERR_INVALID_DATA;
     380             :         }
     381             : 
     382           6 :         key.data = key_and_iv;
     383           6 :         key.size = gnutls_cipher_get_key_size(cipher_algo);
     384             : 
     385           6 :         iv.data = key_and_iv + key.size;
     386           6 :         iv.size = gnutls_cipher_get_iv_size(cipher_algo);
     387             : 
     388             :         /* Allocate data structure for the plaintext */
     389           6 :         blob_us = data_blob_talloc_zero(sub_ctx, access_check_len);
     390           6 :         if (blob_us.data == NULL) {
     391           0 :                 return WERR_INVALID_DATA;
     392             :         }
     393             : 
     394           6 :         rc = gnutls_cipher_init(&cipher_handle,
     395             :                                 cipher_algo,
     396             :                                 &key,
     397             :                                 &iv);
     398           6 :         if (rc < 0) {
     399           0 :                 DBG_ERR("gnutls_cipher_init failed: %s\n",
     400             :                         gnutls_strerror(rc));
     401           0 :                 return WERR_INVALID_DATA;
     402             :         }
     403             : 
     404           6 :         rc = gnutls_cipher_decrypt2(cipher_handle,
     405             :                                     access_check,
     406             :                                     access_check_len,
     407           6 :                                     blob_us.data,
     408             :                                     blob_us.length);
     409           6 :         gnutls_cipher_deinit(cipher_handle);
     410           6 :         if (rc < 0) {
     411           0 :                 DBG_ERR("gnutls_cipher_decrypt2 failed: %s\n",
     412             :                         gnutls_strerror(rc));
     413           0 :                 return WERR_INVALID_DATA;
     414             :         }
     415             : 
     416           6 :         switch (version) {
     417           5 :         case 2:
     418           5 :         {
     419           5 :                 uint32_t hash_size = 20;
     420           5 :                 uint8_t hash[hash_size];
     421           0 :                 gnutls_hash_hd_t dig_ctx;
     422             : 
     423           5 :                 ndr_err = ndr_pull_struct_blob(&blob_us, sub_ctx, &uncrypted_accesscheckv2,
     424             :                                         (ndr_pull_flags_fn_t)ndr_pull_bkrp_access_check_v2);
     425           5 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     426             :                         /* Unable to unmarshall */
     427           0 :                         return WERR_INVALID_DATA;
     428             :                 }
     429           5 :                 if (uncrypted_accesscheckv2.magic != 0x1) {
     430             :                         /* wrong magic */
     431           1 :                         return WERR_INVALID_DATA;
     432             :                 }
     433             : 
     434           4 :                 rc = gnutls_hash_init(&dig_ctx, GNUTLS_DIG_SHA1);
     435           4 :                 if (rc != GNUTLS_E_SUCCESS) {
     436           0 :                         return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
     437             :                 }
     438           4 :                 rc = gnutls_hash(dig_ctx,
     439           4 :                                  blob_us.data,
     440           4 :                                  blob_us.length - hash_size);
     441           4 :                 gnutls_hash_deinit(dig_ctx, hash);
     442           4 :                 if (rc != GNUTLS_E_SUCCESS) {
     443           0 :                         return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
     444             :                 }
     445             : 
     446             :                 /*
     447             :                  * We free it after the sha1 calculation because blob.data
     448             :                  * points to the same area
     449             :                  */
     450             : 
     451           4 :                 if (!mem_equal_const_time(hash, uncrypted_accesscheckv2.hash, hash_size)) {
     452           1 :                         DEBUG(2, ("Wrong hash value in the access check in backup key remote protocol\n"));
     453           1 :                         return WERR_INVALID_DATA;
     454             :                 }
     455           3 :                 access_sid = &(uncrypted_accesscheckv2.sid);
     456           3 :                 break;
     457             :         }
     458           1 :         case 3:
     459           1 :         {
     460           1 :                 uint32_t hash_size = 64;
     461           1 :                 uint8_t hash[hash_size];
     462           0 :                 gnutls_hash_hd_t dig_ctx;
     463             : 
     464           1 :                 ndr_err = ndr_pull_struct_blob(&blob_us, sub_ctx, &uncrypted_accesscheckv3,
     465             :                                         (ndr_pull_flags_fn_t)ndr_pull_bkrp_access_check_v3);
     466           1 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     467             :                         /* Unable to unmarshall */
     468           0 :                         return WERR_INVALID_DATA;
     469             :                 }
     470           1 :                 if (uncrypted_accesscheckv3.magic != 0x1) {
     471             :                         /* wrong magic */
     472           0 :                         return WERR_INVALID_DATA;
     473             :                 }
     474             : 
     475           1 :                 rc = gnutls_hash_init(&dig_ctx, GNUTLS_DIG_SHA512);
     476           1 :                 if (rc != GNUTLS_E_SUCCESS) {
     477           0 :                         return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
     478             :                 }
     479           1 :                 rc = gnutls_hash(dig_ctx,
     480           1 :                                  blob_us.data,
     481           1 :                                  blob_us.length - hash_size);
     482           1 :                 gnutls_hash_deinit(dig_ctx, hash);
     483           1 :                 if (rc != GNUTLS_E_SUCCESS) {
     484           0 :                         return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
     485             :                 }
     486             : 
     487             :                 /*
     488             :                  * We free it after the sha1 calculation because blob.data
     489             :                  * points to the same area
     490             :                  */
     491             : 
     492           1 :                 if (!mem_equal_const_time(hash, uncrypted_accesscheckv3.hash, hash_size)) {
     493           0 :                         DEBUG(2, ("Wrong hash value in the access check in backup key remote protocol\n"));
     494           0 :                         return WERR_INVALID_DATA;
     495             :                 }
     496           1 :                 access_sid = &(uncrypted_accesscheckv3.sid);
     497           1 :                 break;
     498             :         }
     499           0 :         default:
     500             :                 /* Never reached normally as we filtered at the switch / case level */
     501           0 :                 return WERR_INVALID_DATA;
     502             :         }
     503             : 
     504           4 :         caller_sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
     505             : 
     506           4 :         if (!dom_sid_equal(caller_sid, access_sid)) {
     507           1 :                 return WERR_INVALID_ACCESS;
     508             :         }
     509           3 :         return WERR_OK;
     510             : }
     511             : 
     512             : /*
     513             :  * We have some data, such as saved website or IMAP passwords that the
     514             :  * client has in profile on-disk.  This needs to be decrypted.  This
     515             :  * version gives the server the data over the network (protected by
     516             :  * the X.509 certificate and public key encryption, and asks that it
     517             :  * be decrypted returned for short-term use, protected only by the
     518             :  * negotiated transport encryption.
     519             :  *
     520             :  * The data is NOT stored in the LSA, but a X.509 certificate, public
     521             :  * and private keys used to encrypt the data will be stored.  There is
     522             :  * only one active encryption key pair and certificate per domain, it
     523             :  * is pointed at with G$BCKUPKEY_PREFERRED in the LSA secrets store.
     524             :  *
     525             :  * The potentially multiple valid decrypting key pairs are in turn
     526             :  * stored in the LSA secrets store as G$BCKUPKEY_keyGuidString.
     527             :  *
     528             :  */
     529          10 : static WERROR bkrp_client_wrap_decrypt_data(struct dcesrv_call_state *dce_call,
     530             :                                             TALLOC_CTX *mem_ctx,
     531             :                                             struct bkrp_BackupKey *r,
     532             :                                             struct ldb_context *ldb_ctx)
     533             : {
     534           0 :         struct auth_session_info *session_info =
     535          10 :                 dcesrv_call_session_info(dce_call);
     536           0 :         struct bkrp_client_side_wrapped uncrypt_request;
     537           0 :         DATA_BLOB blob;
     538           0 :         enum ndr_err_code ndr_err;
     539           0 :         char *guid_string;
     540           0 :         char *cert_secret_name;
     541           0 :         DATA_BLOB lsa_secret;
     542          10 :         DATA_BLOB *uncrypted_data = NULL;
     543           0 :         NTSTATUS status;
     544           0 :         uint32_t requested_version;
     545             : 
     546          10 :         blob.data = r->in.data_in;
     547          10 :         blob.length = r->in.data_in_len;
     548             : 
     549          10 :         if (r->in.data_in_len < 4 || r->in.data_in == NULL) {
     550           0 :                 return WERR_INVALID_PARAMETER;
     551             :         }
     552             : 
     553             :         /*
     554             :          * We check for the version here, so we can actually print the
     555             :          * message as we are unlikely to parse it with NDR.
     556             :          */
     557          10 :         requested_version = IVAL(r->in.data_in, 0);
     558          10 :         if ((requested_version != BACKUPKEY_CLIENT_WRAP_VERSION2)
     559           4 :             && (requested_version != BACKUPKEY_CLIENT_WRAP_VERSION3)) {
     560           1 :                 DEBUG(1, ("Request for unknown BackupKey sub-protocol %d\n", requested_version));
     561           1 :                 return WERR_INVALID_PARAMETER;
     562             :         }
     563             : 
     564           9 :         ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &uncrypt_request,
     565             :                                        (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_wrapped);
     566           9 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     567           0 :                 return WERR_INVALID_PARAMETER;
     568             :         }
     569             : 
     570           9 :         if ((uncrypt_request.version != BACKUPKEY_CLIENT_WRAP_VERSION2)
     571           3 :             && (uncrypt_request.version != BACKUPKEY_CLIENT_WRAP_VERSION3)) {
     572           0 :                 DEBUG(1, ("Request for unknown BackupKey sub-protocol %d\n", uncrypt_request.version));
     573           0 :                 return WERR_INVALID_PARAMETER;
     574             :         }
     575             : 
     576           9 :         guid_string = GUID_string(mem_ctx, &uncrypt_request.guid);
     577           9 :         if (guid_string == NULL) {
     578           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     579             :         }
     580             : 
     581           9 :         cert_secret_name = talloc_asprintf(mem_ctx,
     582             :                                            "BCKUPKEY_%s",
     583             :                                            guid_string);
     584           9 :         if (cert_secret_name == NULL) {
     585           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     586             :         }
     587             : 
     588           9 :         status = get_lsa_secret(mem_ctx,
     589             :                                 ldb_ctx,
     590             :                                 cert_secret_name,
     591             :                                 &lsa_secret);
     592           9 :         if (!NT_STATUS_IS_OK(status)) {
     593           1 :                 DEBUG(10, ("Error while fetching secret %s\n", cert_secret_name));
     594           1 :                 return WERR_INVALID_DATA;
     595           8 :         } else if (lsa_secret.length == 0) {
     596             :                 /* we do not have the real secret attribute, like if we are an RODC */
     597           0 :                 return WERR_INVALID_PARAMETER;
     598             :         } else {
     599           0 :                 struct bkrp_exported_RSA_key_pair keypair;
     600           8 :                 gnutls_privkey_t privkey = NULL;
     601           0 :                 gnutls_datum_t reversed_secret;
     602           0 :                 gnutls_datum_t uncrypted_secret;
     603           0 :                 uint32_t i;
     604           0 :                 DATA_BLOB blob_us;
     605           0 :                 WERROR werr;
     606           0 :                 int rc;
     607             : 
     608           8 :                 ndr_err = ndr_pull_struct_blob(&lsa_secret, mem_ctx, &keypair, (ndr_pull_flags_fn_t)ndr_pull_bkrp_exported_RSA_key_pair);
     609           8 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     610           0 :                         DEBUG(2, ("Unable to parse the ndr encoded cert in key %s\n", cert_secret_name));
     611           0 :                         return WERR_FILE_NOT_FOUND;
     612             :                 }
     613             : 
     614           8 :                 status = get_pk_from_raw_keypair_params(mem_ctx,
     615             :                                                         &keypair,
     616             :                                                         &privkey);
     617           8 :                 if (!NT_STATUS_IS_OK(status)) {
     618           0 :                         return WERR_INTERNAL_ERROR;
     619             :                 }
     620             : 
     621           8 :                 reversed_secret.data = talloc_array(mem_ctx, uint8_t,
     622             :                                                     uncrypt_request.encrypted_secret_len);
     623           8 :                 if (reversed_secret.data == NULL) {
     624           0 :                         gnutls_privkey_deinit(privkey);
     625           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     626             :                 }
     627             : 
     628             :                 /* The secret has to be reversed ... */
     629        2056 :                 for(i=0; i< uncrypt_request.encrypted_secret_len; i++) {
     630        2048 :                         uint8_t *reversed = (uint8_t *)reversed_secret.data;
     631        2048 :                         uint8_t *uncrypt = uncrypt_request.encrypted_secret;
     632        2048 :                         reversed[i] = uncrypt[uncrypt_request.encrypted_secret_len - 1 - i];
     633             :                 }
     634           8 :                 reversed_secret.size = uncrypt_request.encrypted_secret_len;
     635             : 
     636             :                 /*
     637             :                  * Let's try to decrypt the secret now that
     638             :                  * we have the private key ...
     639             :                  */
     640           8 :                 rc = gnutls_privkey_decrypt_data(privkey,
     641             :                                                  0,
     642             :                                                  &reversed_secret,
     643             :                                                  &uncrypted_secret);
     644           8 :                 gnutls_privkey_deinit(privkey);
     645           8 :                 if (rc != GNUTLS_E_SUCCESS) {
     646             :                         /* We are not able to decrypt the secret, looks like something is wrong */
     647           1 :                         return WERR_INVALID_PARAMETER;
     648             :                 }
     649           7 :                 blob_us.data = uncrypted_secret.data;
     650           7 :                 blob_us.length = uncrypted_secret.size;
     651             : 
     652           7 :                 if (uncrypt_request.version == 2) {
     653           0 :                         struct bkrp_encrypted_secret_v2 uncrypted_secretv2;
     654             : 
     655           5 :                         ndr_err = ndr_pull_struct_blob(&blob_us, mem_ctx, &uncrypted_secretv2,
     656             :                                         (ndr_pull_flags_fn_t)ndr_pull_bkrp_encrypted_secret_v2);
     657           5 :                         gnutls_free(uncrypted_secret.data);
     658           5 :                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     659             :                                 /* Unable to unmarshall */
     660           0 :                                 return WERR_INVALID_DATA;
     661             :                         }
     662           5 :                         if (uncrypted_secretv2.magic != 0x20) {
     663             :                                 /* wrong magic */
     664           0 :                                 return WERR_INVALID_DATA;
     665             :                         }
     666             : 
     667           5 :                         werr = get_and_verify_access_check(mem_ctx, 2,
     668             :                                                            uncrypted_secretv2.payload_key,
     669             :                                                            uncrypt_request.access_check,
     670             :                                                            uncrypt_request.access_check_len,
     671             :                                                            session_info);
     672           5 :                         if (!W_ERROR_IS_OK(werr)) {
     673           3 :                                 return werr;
     674             :                         }
     675           2 :                         uncrypted_data = talloc(mem_ctx, DATA_BLOB);
     676           2 :                         if (uncrypted_data == NULL) {
     677           0 :                                 return WERR_INVALID_DATA;
     678             :                         }
     679             : 
     680           2 :                         uncrypted_data->data = uncrypted_secretv2.secret;
     681           2 :                         uncrypted_data->length = uncrypted_secretv2.secret_len;
     682             :                 }
     683           4 :                 if (uncrypt_request.version == 3) {
     684           0 :                         struct bkrp_encrypted_secret_v3 uncrypted_secretv3;
     685             : 
     686           2 :                         ndr_err = ndr_pull_struct_blob(&blob_us, mem_ctx, &uncrypted_secretv3,
     687             :                                         (ndr_pull_flags_fn_t)ndr_pull_bkrp_encrypted_secret_v3);
     688           2 :                         gnutls_free(uncrypted_secret.data);
     689           2 :                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     690             :                                 /* Unable to unmarshall */
     691           0 :                                 return WERR_INVALID_DATA;
     692             :                         }
     693             : 
     694           2 :                         if (uncrypted_secretv3.magic1 != 0x30  ||
     695           1 :                             uncrypted_secretv3.magic2 != 0x6610 ||
     696           1 :                             uncrypted_secretv3.magic3 != 0x800e) {
     697             :                                 /* wrong magic */
     698           1 :                                 return WERR_INVALID_DATA;
     699             :                         }
     700             : 
     701             :                         /*
     702             :                          * Confirm that the caller is permitted to
     703             :                          * read this particular data.  Because one key
     704             :                          * pair is used per domain, the caller could
     705             :                          * have stolen the profile data on-disk and
     706             :                          * would otherwise be able to read the
     707             :                          * passwords.
     708             :                          */
     709             : 
     710           1 :                         werr = get_and_verify_access_check(mem_ctx, 3,
     711             :                                                            uncrypted_secretv3.payload_key,
     712             :                                                            uncrypt_request.access_check,
     713             :                                                            uncrypt_request.access_check_len,
     714             :                                                            session_info);
     715           1 :                         if (!W_ERROR_IS_OK(werr)) {
     716           0 :                                 return werr;
     717             :                         }
     718             : 
     719           1 :                         uncrypted_data = talloc(mem_ctx, DATA_BLOB);
     720           1 :                         if (uncrypted_data == NULL) {
     721           0 :                                 return WERR_INVALID_DATA;
     722             :                         }
     723             : 
     724           1 :                         uncrypted_data->data = uncrypted_secretv3.secret;
     725           1 :                         uncrypted_data->length = uncrypted_secretv3.secret_len;
     726             :                 }
     727             : 
     728             :                 /*
     729             :                  * Yeah if we are here all looks pretty good:
     730             :                  * - hash is ok
     731             :                  * - user sid is the same as the one in access check
     732             :                  * - we were able to decrypt the whole stuff
     733             :                  */
     734             :         }
     735             : 
     736           3 :         if (uncrypted_data->data == NULL) {
     737           0 :                 return WERR_INVALID_DATA;
     738             :         }
     739             : 
     740             :         /* There is a magic value at the beginning of the data
     741             :          * we can use an ad hoc structure but as the
     742             :          * parent structure is just an array of bytes it is a lot of
     743             :          * work just prepending 4 bytes
     744             :          */
     745           3 :         *(r->out.data_out) = talloc_zero_array(mem_ctx, uint8_t, uncrypted_data->length + 4);
     746           3 :         W_ERROR_HAVE_NO_MEMORY(*(r->out.data_out));
     747           3 :         memcpy(4+*(r->out.data_out), uncrypted_data->data, uncrypted_data->length);
     748           3 :         *(r->out.data_out_len) = uncrypted_data->length + 4;
     749             : 
     750           3 :         return WERR_OK;
     751             : }
     752             : 
     753           8 : static DATA_BLOB *reverse_and_get_blob(TALLOC_CTX *mem_ctx,
     754             :                                        gnutls_datum_t *datum)
     755             : {
     756           0 :         DATA_BLOB *blob;
     757           0 :         size_t i;
     758             : 
     759           8 :         blob = talloc(mem_ctx, DATA_BLOB);
     760           8 :         if (blob == NULL) {
     761           0 :                 return NULL;
     762             :         }
     763             : 
     764           8 :         blob->length = datum->size;
     765           8 :         if (datum->data[0] == '\0') {
     766             :                 /* The datum has a leading byte zero, skip it */
     767           5 :                 blob->length = datum->size - 1;
     768             :         }
     769           8 :         blob->data = talloc_zero_array(mem_ctx, uint8_t, blob->length);
     770           8 :         if (blob->data == NULL) {
     771           0 :                 talloc_free(blob);
     772           0 :                 return NULL;
     773             :         }
     774             : 
     775        1163 :         for (i = 0; i < blob->length; i++) {
     776        1155 :                 blob->data[i] = datum->data[datum->size - i - 1];
     777             :         }
     778             : 
     779           8 :         return blob;
     780             : }
     781             : 
     782           1 : static WERROR create_privkey_rsa(gnutls_privkey_t *pk)
     783             : {
     784           1 :         int bits = 2048;
     785           1 :         gnutls_x509_privkey_t x509_privkey = NULL;
     786           1 :         gnutls_privkey_t privkey = NULL;
     787           0 :         int rc;
     788             : 
     789           1 :         rc = gnutls_x509_privkey_init(&x509_privkey);
     790           1 :         if (rc != GNUTLS_E_SUCCESS) {
     791           0 :                 DBG_ERR("gnutls_x509_privkey_init failed - %s\n",
     792             :                         gnutls_strerror(rc));
     793           0 :                 return WERR_INTERNAL_ERROR;
     794             :         }
     795             : 
     796           1 :         rc = gnutls_x509_privkey_generate(x509_privkey,
     797             :                                           GNUTLS_PK_RSA,
     798             :                                           bits,
     799             :                                           0);
     800           1 :         if (rc != GNUTLS_E_SUCCESS) {
     801           0 :                 DBG_ERR("gnutls_x509_privkey_generate failed - %s\n",
     802             :                         gnutls_strerror(rc));
     803           0 :                 gnutls_x509_privkey_deinit(x509_privkey);
     804           0 :                 return WERR_INTERNAL_ERROR;
     805             :         }
     806             : 
     807           1 :         rc = gnutls_privkey_init(&privkey);
     808           1 :         if (rc != GNUTLS_E_SUCCESS) {
     809           0 :                 DBG_ERR("gnutls_privkey_init failed - %s\n",
     810             :                         gnutls_strerror(rc));
     811           0 :                 gnutls_x509_privkey_deinit(x509_privkey);
     812           0 :                 return WERR_INTERNAL_ERROR;
     813             :         }
     814             : 
     815           1 :         rc = gnutls_privkey_import_x509(privkey,
     816             :                                         x509_privkey,
     817             :                                         GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
     818           1 :         if (rc != GNUTLS_E_SUCCESS) {
     819           0 :                 DBG_ERR("gnutls_privkey_import_x509 failed - %s\n",
     820             :                         gnutls_strerror(rc));
     821           0 :                 gnutls_x509_privkey_deinit(x509_privkey);
     822           0 :                 return WERR_INTERNAL_ERROR;
     823             :         }
     824             : 
     825           1 :         *pk = privkey;
     826             : 
     827           1 :         return WERR_OK;
     828             : }
     829             : 
     830           1 : static WERROR self_sign_cert(TALLOC_CTX *mem_ctx,
     831             :                              time_t lifetime,
     832             :                              const char *dn,
     833             :                              gnutls_privkey_t issuer_privkey,
     834             :                              gnutls_x509_crt_t *certificate,
     835             :                              DATA_BLOB *guidblob)
     836             : {
     837           0 :         gnutls_datum_t unique_id;
     838           0 :         gnutls_datum_t serial_number;
     839           0 :         gnutls_x509_crt_t issuer_cert;
     840           0 :         gnutls_x509_privkey_t x509_issuer_privkey;
     841           1 :         time_t activation = time(NULL);
     842           1 :         time_t expiry = activation + lifetime;
     843           0 :         const char *error_string;
     844           0 :         uint8_t *reversed;
     845           0 :         size_t i;
     846           0 :         int rc;
     847             : 
     848           1 :         unique_id.size = guidblob->length;
     849           1 :         unique_id.data = talloc_memdup(mem_ctx,
     850             :                                        guidblob->data,
     851             :                                        guidblob->length);
     852           1 :         if (unique_id.data == NULL) {
     853           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     854             :         }
     855             : 
     856           1 :         reversed = talloc_array(mem_ctx, uint8_t, guidblob->length);
     857           1 :         if (reversed == NULL) {
     858           0 :                 talloc_free(unique_id.data);
     859           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     860             :         }
     861             : 
     862             :         /* Native AD generates certificates with serialnumber in reversed notation */
     863          17 :         for (i = 0; i < guidblob->length; i++) {
     864          16 :                 uint8_t *uncrypt = guidblob->data;
     865          16 :                 reversed[i] = uncrypt[guidblob->length - i - 1];
     866             :         }
     867           1 :         serial_number.size = guidblob->length;
     868           1 :         serial_number.data = reversed;
     869             : 
     870             :         /* Create certificate to sign */
     871           1 :         rc = gnutls_x509_crt_init(&issuer_cert);
     872           1 :         if (rc != GNUTLS_E_SUCCESS) {
     873           0 :                 DBG_ERR("gnutls_x509_crt_init failed - %s\n",
     874             :                         gnutls_strerror(rc));
     875           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     876             :         }
     877             : 
     878           1 :         rc = gnutls_x509_crt_set_dn(issuer_cert, dn, &error_string);
     879           1 :         if (rc != GNUTLS_E_SUCCESS) {
     880           0 :                 DBG_ERR("gnutls_x509_crt_set_dn failed - %s (%s)\n",
     881             :                         gnutls_strerror(rc),
     882             :                         error_string);
     883           0 :                 gnutls_x509_crt_deinit(issuer_cert);
     884           0 :                 return WERR_INVALID_PARAMETER;
     885             :         }
     886             : 
     887           1 :         rc = gnutls_x509_crt_set_issuer_dn(issuer_cert, dn, &error_string);
     888           1 :         if (rc != GNUTLS_E_SUCCESS) {
     889           0 :                 DBG_ERR("gnutls_x509_crt_set_issuer_dn failed - %s (%s)\n",
     890             :                         gnutls_strerror(rc),
     891             :                         error_string);
     892           0 :                 gnutls_x509_crt_deinit(issuer_cert);
     893           0 :                 return WERR_INVALID_PARAMETER;
     894             :         }
     895             : 
     896             :         /* Get x509 privkey for subjectPublicKeyInfo */
     897           1 :         rc = gnutls_x509_privkey_init(&x509_issuer_privkey);
     898           1 :         if (rc != GNUTLS_E_SUCCESS) {
     899           0 :                 DBG_ERR("gnutls_x509_privkey_init failed - %s\n",
     900             :                         gnutls_strerror(rc));
     901           0 :                 gnutls_x509_crt_deinit(issuer_cert);
     902           0 :                 return WERR_INVALID_PARAMETER;
     903             :         }
     904             : 
     905           1 :         rc = gnutls_privkey_export_x509(issuer_privkey,
     906             :                                         &x509_issuer_privkey);
     907           1 :         if (rc != GNUTLS_E_SUCCESS) {
     908           0 :                 DBG_ERR("gnutls_x509_privkey_init failed - %s\n",
     909             :                         gnutls_strerror(rc));
     910           0 :                 gnutls_x509_privkey_deinit(x509_issuer_privkey);
     911           0 :                 gnutls_x509_crt_deinit(issuer_cert);
     912           0 :                 return WERR_INVALID_PARAMETER;
     913             :         }
     914             : 
     915             :         /* Set subjectPublicKeyInfo */
     916           1 :         rc = gnutls_x509_crt_set_key(issuer_cert, x509_issuer_privkey);
     917           1 :         gnutls_x509_privkey_deinit(x509_issuer_privkey);
     918           1 :         if (rc != GNUTLS_E_SUCCESS) {
     919           0 :                 DBG_ERR("gnutls_x509_crt_set_pubkey failed - %s\n",
     920             :                         gnutls_strerror(rc));
     921           0 :                 gnutls_x509_crt_deinit(issuer_cert);
     922           0 :                 return WERR_INVALID_PARAMETER;
     923             :         }
     924             : 
     925           1 :         rc = gnutls_x509_crt_set_activation_time(issuer_cert, activation);
     926           1 :         if (rc != GNUTLS_E_SUCCESS) {
     927           0 :                 DBG_ERR("gnutls_x509_crt_set_activation_time failed - %s\n",
     928             :                         gnutls_strerror(rc));
     929           0 :                 gnutls_x509_crt_deinit(issuer_cert);
     930           0 :                 return WERR_INVALID_PARAMETER;
     931             :         }
     932             : 
     933           1 :         rc = gnutls_x509_crt_set_expiration_time(issuer_cert, expiry);
     934           1 :         if (rc != GNUTLS_E_SUCCESS) {
     935           0 :                 DBG_ERR("gnutls_x509_crt_set_expiration_time failed - %s\n",
     936             :                         gnutls_strerror(rc));
     937           0 :                 gnutls_x509_crt_deinit(issuer_cert);
     938           0 :                 return WERR_INVALID_PARAMETER;
     939             :         }
     940             : 
     941           1 :         rc = gnutls_x509_crt_set_version(issuer_cert, 3);
     942           1 :         if (rc != GNUTLS_E_SUCCESS) {
     943           0 :                 DBG_ERR("gnutls_x509_crt_set_version failed - %s\n",
     944             :                         gnutls_strerror(rc));
     945           0 :                 gnutls_x509_crt_deinit(issuer_cert);
     946           0 :                 return WERR_INVALID_PARAMETER;
     947             :         }
     948             : 
     949           1 :         rc = gnutls_x509_crt_set_subject_unique_id(issuer_cert,
     950           1 :                                                    unique_id.data,
     951           1 :                                                    unique_id.size);
     952           1 :         if (rc != GNUTLS_E_SUCCESS) {
     953           0 :                 DBG_ERR("gnutls_x509_crt_set_subject_key_id failed - %s\n",
     954             :                         gnutls_strerror(rc));
     955           0 :                 gnutls_x509_crt_deinit(issuer_cert);
     956           0 :                 return WERR_INVALID_PARAMETER;
     957             :         }
     958             : 
     959           1 :         rc = gnutls_x509_crt_set_issuer_unique_id(issuer_cert,
     960           1 :                                                   unique_id.data,
     961           1 :                                                   unique_id.size);
     962           1 :         if (rc != GNUTLS_E_SUCCESS) {
     963           0 :                 DBG_ERR("gnutls_x509_crt_set_issuer_unique_id failed - %s\n",
     964             :                         gnutls_strerror(rc));
     965           0 :                 gnutls_x509_crt_deinit(issuer_cert);
     966           0 :                 return WERR_INVALID_PARAMETER;
     967             :         }
     968             : 
     969           1 :         rc = gnutls_x509_crt_set_serial(issuer_cert,
     970           1 :                                         serial_number.data,
     971           1 :                                         serial_number.size);
     972           1 :         if (rc != GNUTLS_E_SUCCESS) {
     973           0 :                 DBG_ERR("gnutls_x509_crt_set_serial failed - %s\n",
     974             :                         gnutls_strerror(rc));
     975           0 :                 gnutls_x509_crt_deinit(issuer_cert);
     976           0 :                 return WERR_INVALID_PARAMETER;
     977             :         }
     978             : 
     979           1 :         rc = gnutls_x509_crt_privkey_sign(issuer_cert,
     980             :                                           issuer_cert,
     981             :                                           issuer_privkey,
     982             :                                           GNUTLS_DIG_SHA1,
     983             :                                           0);
     984           1 :         if (rc != GNUTLS_E_SUCCESS) {
     985           0 :                 DBG_ERR("gnutls_x509_crt_privkey_sign failed - %s\n",
     986             :                         gnutls_strerror(rc));
     987           0 :                 return WERR_INVALID_PARAMETER;
     988             :         }
     989             : 
     990           1 :         *certificate = issuer_cert;
     991             : 
     992           1 :         return WERR_OK;
     993             : }
     994             : 
     995             : /* Return an error when we fail to generate a certificate */
     996           1 : static WERROR generate_bkrp_cert(TALLOC_CTX *mem_ctx,
     997             :                                  struct dcesrv_call_state *dce_call,
     998             :                                  struct ldb_context *ldb_ctx,
     999             :                                  const char *dn)
    1000             : {
    1001           0 :         WERROR werr;
    1002           1 :         gnutls_privkey_t issuer_privkey = NULL;
    1003           1 :         gnutls_x509_crt_t cert = NULL;
    1004           0 :         gnutls_datum_t cert_blob;
    1005           0 :         gnutls_datum_t m, e, d, p, q, u, e1, e2;
    1006           0 :         DATA_BLOB blob;
    1007           0 :         DATA_BLOB blobkeypair;
    1008           0 :         DATA_BLOB *tmp;
    1009           1 :         bool ok = true;
    1010           1 :         struct GUID guid = GUID_random();
    1011           0 :         NTSTATUS status;
    1012           0 :         char *secret_name;
    1013           0 :         struct bkrp_exported_RSA_key_pair keypair;
    1014           0 :         enum ndr_err_code ndr_err;
    1015           1 :         time_t nb_seconds_validity = 3600 * 24 * 365;
    1016           0 :         int rc;
    1017             : 
    1018           1 :         DEBUG(6, ("Trying to generate a certificate\n"));
    1019           1 :         werr = create_privkey_rsa(&issuer_privkey);
    1020           1 :         if (!W_ERROR_IS_OK(werr)) {
    1021           0 :                 return werr;
    1022             :         }
    1023             : 
    1024           1 :         status = GUID_to_ndr_blob(&guid, mem_ctx, &blob);
    1025           1 :         if (!NT_STATUS_IS_OK(status)) {
    1026           0 :                 gnutls_privkey_deinit(issuer_privkey);
    1027           0 :                 return WERR_INVALID_DATA;
    1028             :         }
    1029             : 
    1030           1 :         werr = self_sign_cert(mem_ctx,
    1031             :                               nb_seconds_validity,
    1032             :                               dn,
    1033             :                               issuer_privkey,
    1034             :                               &cert,
    1035             :                               &blob);
    1036           1 :         if (!W_ERROR_IS_OK(werr)) {
    1037           0 :                 gnutls_privkey_deinit(issuer_privkey);
    1038           0 :                 return WERR_INVALID_DATA;
    1039             :         }
    1040             : 
    1041           1 :         rc = gnutls_x509_crt_export2(cert, GNUTLS_X509_FMT_DER, &cert_blob);
    1042           1 :         if (rc != GNUTLS_E_SUCCESS) {
    1043           0 :                 DBG_ERR("gnutls_x509_crt_export2 failed - %s\n",
    1044             :                         gnutls_strerror(rc));
    1045           0 :                 gnutls_privkey_deinit(issuer_privkey);
    1046           0 :                 gnutls_x509_crt_deinit(cert);
    1047           0 :                 return WERR_INVALID_DATA;
    1048             :         }
    1049             : 
    1050           1 :         keypair.cert.length = cert_blob.size;
    1051           1 :         keypair.cert.data = talloc_memdup(mem_ctx, cert_blob.data, cert_blob.size);
    1052           1 :         gnutls_x509_crt_deinit(cert);
    1053           1 :         gnutls_free(cert_blob.data);
    1054           1 :         if (keypair.cert.data == NULL) {
    1055           0 :                 gnutls_privkey_deinit(issuer_privkey);
    1056           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    1057             :         }
    1058             : 
    1059           1 :         rc = gnutls_privkey_export_rsa_raw(issuer_privkey,
    1060             :                                            &m,
    1061             :                                            &e,
    1062             :                                            &d,
    1063             :                                            &p,
    1064             :                                            &q,
    1065             :                                            &u,
    1066             :                                            &e1,
    1067             :                                            &e2);
    1068           1 :         if (rc != GNUTLS_E_SUCCESS) {
    1069           0 :                 gnutls_privkey_deinit(issuer_privkey);
    1070           0 :                 return WERR_INVALID_DATA;
    1071             :         }
    1072             : 
    1073             :         /*
    1074             :          * Heimdal's bignum are big endian and the
    1075             :          * structure expect it to be in little endian
    1076             :          * so we reverse the buffer to make it work
    1077             :          */
    1078           1 :         tmp = reverse_and_get_blob(mem_ctx, &e);
    1079           1 :         if (tmp == NULL) {
    1080           0 :                 ok = false;
    1081             :         } else {
    1082           1 :                 SMB_ASSERT(tmp->length <= 4);
    1083           1 :                 keypair.public_exponent = *tmp;
    1084             :         }
    1085             : 
    1086           1 :         tmp = reverse_and_get_blob(mem_ctx, &d);
    1087           1 :         if (tmp == NULL) {
    1088           0 :                 ok = false;
    1089             :         } else {
    1090           1 :                 keypair.private_exponent = *tmp;
    1091             :         }
    1092             : 
    1093           1 :         tmp = reverse_and_get_blob(mem_ctx, &m);
    1094           1 :         if (tmp == NULL) {
    1095           0 :                 ok = false;
    1096             :         } else {
    1097           1 :                 keypair.modulus = *tmp;
    1098             :         }
    1099             : 
    1100           1 :         tmp = reverse_and_get_blob(mem_ctx, &p);
    1101           1 :         if (tmp == NULL) {
    1102           0 :                 ok = false;
    1103             :         } else {
    1104           1 :                 keypair.prime1 = *tmp;
    1105             :         }
    1106             : 
    1107           1 :         tmp = reverse_and_get_blob(mem_ctx, &q);
    1108           1 :         if (tmp == NULL) {
    1109           0 :                 ok = false;
    1110             :         } else {
    1111           1 :                 keypair.prime2 = *tmp;
    1112             :         }
    1113             : 
    1114           1 :         tmp = reverse_and_get_blob(mem_ctx, &e1);
    1115           1 :         if (tmp == NULL) {
    1116           0 :                 ok = false;
    1117             :         } else {
    1118           1 :                 keypair.exponent1 = *tmp;
    1119             :         }
    1120             : 
    1121           1 :         tmp = reverse_and_get_blob(mem_ctx, &e2);
    1122           1 :         if (tmp == NULL) {
    1123           0 :                 ok = false;
    1124             :         } else {
    1125           1 :                 keypair.exponent2 = *tmp;
    1126             :         }
    1127             : 
    1128           1 :         tmp = reverse_and_get_blob(mem_ctx, &u);
    1129           1 :         if (tmp == NULL) {
    1130           0 :                 ok = false;
    1131             :         } else {
    1132           1 :                 keypair.coefficient = *tmp;
    1133             :         }
    1134             : 
    1135             :         /* One of the keypair allocation was wrong */
    1136           1 :         if (ok == false) {
    1137           0 :                 gnutls_privkey_deinit(issuer_privkey);
    1138           0 :                 return WERR_INVALID_DATA;
    1139             :         }
    1140             : 
    1141           1 :         keypair.certificate_len = keypair.cert.length;
    1142           1 :         ndr_err = ndr_push_struct_blob(&blobkeypair,
    1143             :                                        mem_ctx,
    1144             :                                        &keypair,
    1145             :                                        (ndr_push_flags_fn_t)ndr_push_bkrp_exported_RSA_key_pair);
    1146           1 :         gnutls_privkey_deinit(issuer_privkey);
    1147           1 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1148           0 :                 return WERR_INVALID_DATA;
    1149             :         }
    1150             : 
    1151           1 :         secret_name = talloc_asprintf(mem_ctx, "BCKUPKEY_%s", GUID_string(mem_ctx, &guid));
    1152           1 :         if (secret_name == NULL) {
    1153           0 :                 return WERR_OUTOFMEMORY;
    1154             :         }
    1155             : 
    1156           1 :         status = set_lsa_secret(mem_ctx, ldb_ctx, secret_name, &blobkeypair);
    1157           1 :         if (!NT_STATUS_IS_OK(status)) {
    1158           0 :                 DEBUG(2, ("Failed to save the secret %s\n", secret_name));
    1159             :         }
    1160           1 :         talloc_free(secret_name);
    1161             : 
    1162           1 :         GUID_to_ndr_blob(&guid, mem_ctx, &blob);
    1163           1 :         status = set_lsa_secret(mem_ctx, ldb_ctx, "BCKUPKEY_PREFERRED", &blob);
    1164           1 :         if (!NT_STATUS_IS_OK(status)) {
    1165           0 :                 DEBUG(2, ("Failed to save the secret BCKUPKEY_PREFERRED\n"));
    1166             :         }
    1167             : 
    1168           1 :         return WERR_OK;
    1169             : }
    1170             : 
    1171          13 : static WERROR bkrp_retrieve_client_wrap_key(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    1172             :                                             struct bkrp_BackupKey *r, struct ldb_context *ldb_ctx)
    1173             : {
    1174           0 :         struct GUID guid;
    1175           0 :         char *guid_string;
    1176           0 :         DATA_BLOB lsa_secret;
    1177           0 :         enum ndr_err_code ndr_err;
    1178           0 :         NTSTATUS status;
    1179             : 
    1180             :         /*
    1181             :          * here we basically need to return our certificate
    1182             :          * search for lsa secret BCKUPKEY_PREFERRED first
    1183             :          */
    1184             : 
    1185          13 :         status = get_lsa_secret(mem_ctx,
    1186             :                                 ldb_ctx,
    1187             :                                 "BCKUPKEY_PREFERRED",
    1188             :                                 &lsa_secret);
    1189          13 :         if (NT_STATUS_EQUAL(status, NT_STATUS_RESOURCE_NAME_NOT_FOUND)) {
    1190             :                 /* Ok we can be in this case if there was no certs */
    1191           1 :                 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
    1192           1 :                 char *dn = talloc_asprintf(mem_ctx, "CN=%s",
    1193             :                                            lpcfg_realm(lp_ctx));
    1194             : 
    1195           1 :                 WERROR werr =  generate_bkrp_cert(mem_ctx, dce_call, ldb_ctx, dn);
    1196           1 :                 if (!W_ERROR_IS_OK(werr)) {
    1197           0 :                         return WERR_INVALID_PARAMETER;
    1198             :                 }
    1199           1 :                 status = get_lsa_secret(mem_ctx,
    1200             :                                         ldb_ctx,
    1201             :                                         "BCKUPKEY_PREFERRED",
    1202             :                                         &lsa_secret);
    1203             : 
    1204           1 :                 if (!NT_STATUS_IS_OK(status)) {
    1205             :                         /* Ok we really don't manage to get this certs ...*/
    1206           0 :                         DEBUG(2, ("Unable to locate BCKUPKEY_PREFERRED after cert generation\n"));
    1207           0 :                         return WERR_FILE_NOT_FOUND;
    1208             :                 }
    1209          12 :         } else if (!NT_STATUS_IS_OK(status)) {
    1210           0 :                 return WERR_INTERNAL_ERROR;
    1211             :         }
    1212             : 
    1213          13 :         if (lsa_secret.length == 0) {
    1214           0 :                 DEBUG(1, ("No secret in BCKUPKEY_PREFERRED, are we an undetected RODC?\n"));
    1215           0 :                 return WERR_INTERNAL_ERROR;
    1216             :         } else {
    1217           0 :                 char *cert_secret_name;
    1218             : 
    1219          13 :                 status = GUID_from_ndr_blob(&lsa_secret, &guid);
    1220          13 :                 if (!NT_STATUS_IS_OK(status)) {
    1221           0 :                         return WERR_FILE_NOT_FOUND;
    1222             :                 }
    1223             : 
    1224          13 :                 guid_string = GUID_string(mem_ctx, &guid);
    1225          13 :                 if (guid_string == NULL) {
    1226             :                         /* We return file not found because the client
    1227             :                          * expect this error
    1228             :                          */
    1229           0 :                         return WERR_FILE_NOT_FOUND;
    1230             :                 }
    1231             : 
    1232          13 :                 cert_secret_name = talloc_asprintf(mem_ctx,
    1233             :                                                         "BCKUPKEY_%s",
    1234             :                                                         guid_string);
    1235          13 :                 status = get_lsa_secret(mem_ctx,
    1236             :                                         ldb_ctx,
    1237             :                                         cert_secret_name,
    1238             :                                         &lsa_secret);
    1239          13 :                 if (!NT_STATUS_IS_OK(status)) {
    1240           0 :                         return WERR_FILE_NOT_FOUND;
    1241             :                 }
    1242             : 
    1243          13 :                 if (lsa_secret.length != 0) {
    1244           0 :                         struct bkrp_exported_RSA_key_pair keypair;
    1245          13 :                         ndr_err = ndr_pull_struct_blob(&lsa_secret, mem_ctx, &keypair,
    1246             :                                         (ndr_pull_flags_fn_t)ndr_pull_bkrp_exported_RSA_key_pair);
    1247          13 :                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1248           0 :                                 return WERR_FILE_NOT_FOUND;
    1249             :                         }
    1250          13 :                         *(r->out.data_out_len) = keypair.cert.length;
    1251          13 :                         *(r->out.data_out) = talloc_memdup(mem_ctx, keypair.cert.data, keypair.cert.length);
    1252          13 :                         W_ERROR_HAVE_NO_MEMORY(*(r->out.data_out));
    1253          13 :                         return WERR_OK;
    1254             :                 } else {
    1255           0 :                         DEBUG(1, ("No or broken secret called %s\n", cert_secret_name));
    1256           0 :                         return WERR_INTERNAL_ERROR;
    1257             :                 }
    1258             :         }
    1259             : 
    1260             :         return WERR_NOT_SUPPORTED;
    1261             : }
    1262             : 
    1263           1 : static WERROR generate_bkrp_server_wrap_key(TALLOC_CTX *ctx, struct ldb_context *ldb_ctx)
    1264             : {
    1265           1 :         struct GUID guid = GUID_random();
    1266           0 :         enum ndr_err_code ndr_err;
    1267           0 :         DATA_BLOB blob_wrap_key, guid_blob;
    1268           0 :         struct bkrp_dc_serverwrap_key wrap_key;
    1269           0 :         NTSTATUS status;
    1270           0 :         char *secret_name;
    1271           1 :         TALLOC_CTX *frame = talloc_stackframe();
    1272             : 
    1273           1 :         generate_random_buffer(wrap_key.key, sizeof(wrap_key.key));
    1274             : 
    1275           1 :         ndr_err = ndr_push_struct_blob(&blob_wrap_key, ctx, &wrap_key, (ndr_push_flags_fn_t)ndr_push_bkrp_dc_serverwrap_key);
    1276           1 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1277           0 :                 TALLOC_FREE(frame);
    1278           0 :                 return WERR_INVALID_DATA;
    1279             :         }
    1280             : 
    1281           1 :         secret_name = talloc_asprintf(frame, "BCKUPKEY_%s", GUID_string(ctx, &guid));
    1282           1 :         if (secret_name == NULL) {
    1283           0 :                 TALLOC_FREE(frame);
    1284           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    1285             :         }
    1286             : 
    1287           1 :         status = set_lsa_secret(frame, ldb_ctx, secret_name, &blob_wrap_key);
    1288           1 :         if (!NT_STATUS_IS_OK(status)) {
    1289           0 :                 DEBUG(2, ("Failed to save the secret %s\n", secret_name));
    1290           0 :                 TALLOC_FREE(frame);
    1291           0 :                 return WERR_INTERNAL_ERROR;
    1292             :         }
    1293             : 
    1294           1 :         status = GUID_to_ndr_blob(&guid, frame, &guid_blob);
    1295           1 :         if (!NT_STATUS_IS_OK(status)) {
    1296           0 :                 DEBUG(2, ("Failed to save the secret %s\n", secret_name));
    1297           0 :                 TALLOC_FREE(frame);
    1298             :         }
    1299             : 
    1300           1 :         status = set_lsa_secret(frame, ldb_ctx, "BCKUPKEY_P", &guid_blob);
    1301           1 :         if (!NT_STATUS_IS_OK(status)) {
    1302           0 :                 DEBUG(2, ("Failed to save the secret %s\n", secret_name));
    1303           0 :                 TALLOC_FREE(frame);
    1304           0 :                 return WERR_INTERNAL_ERROR;
    1305             :         }
    1306             : 
    1307           1 :         TALLOC_FREE(frame);
    1308             : 
    1309           1 :         return WERR_OK;
    1310             : }
    1311             : 
    1312             : /*
    1313             :  * Find the specified decryption keys from the LSA secrets store as
    1314             :  * G$BCKUPKEY_keyGuidString.
    1315             :  */
    1316             : 
    1317          31 : static WERROR bkrp_do_retrieve_server_wrap_key(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx,
    1318             :                                                struct bkrp_dc_serverwrap_key *server_key,
    1319             :                                                struct GUID *guid)
    1320             : {
    1321           0 :         NTSTATUS status;
    1322           0 :         DATA_BLOB lsa_secret;
    1323           0 :         char *secret_name;
    1324           0 :         char *guid_string;
    1325           0 :         enum ndr_err_code ndr_err;
    1326             : 
    1327          31 :         guid_string = GUID_string(mem_ctx, guid);
    1328          31 :         if (guid_string == NULL) {
    1329             :                 /* We return file not found because the client
    1330             :                  * expect this error
    1331             :                  */
    1332           0 :                 return WERR_FILE_NOT_FOUND;
    1333             :         }
    1334             : 
    1335          31 :         secret_name = talloc_asprintf(mem_ctx, "BCKUPKEY_%s", guid_string);
    1336          31 :         if (secret_name == NULL) {
    1337           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    1338             :         }
    1339             : 
    1340          31 :         status = get_lsa_secret(mem_ctx, ldb_ctx, secret_name, &lsa_secret);
    1341          31 :         if (!NT_STATUS_IS_OK(status)) {
    1342           2 :                 DEBUG(10, ("Error while fetching secret %s\n", secret_name));
    1343           2 :                 return WERR_INVALID_DATA;
    1344             :         }
    1345          29 :         if (lsa_secret.length == 0) {
    1346             :                 /* RODC case, we do not have secrets locally */
    1347           0 :                 DEBUG(1, ("Unable to fetch value for secret %s, are we an undetected RODC?\n",
    1348             :                           secret_name));
    1349           0 :                 return WERR_INTERNAL_ERROR;
    1350             :         }
    1351          29 :         ndr_err = ndr_pull_struct_blob(&lsa_secret, mem_ctx, server_key,
    1352             :                                        (ndr_pull_flags_fn_t)ndr_pull_bkrp_dc_serverwrap_key);
    1353          29 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1354           0 :                 DEBUG(2, ("Unable to parse the ndr encoded server wrap key %s\n", secret_name));
    1355           0 :                 return WERR_INVALID_DATA;
    1356             :         }
    1357             : 
    1358          29 :         return WERR_OK;
    1359             : }
    1360             : 
    1361             : /*
    1362             :  * Find the current, preferred ServerWrap Key by looking at
    1363             :  * G$BCKUPKEY_P in the LSA secrets store.
    1364             :  *
    1365             :  * Then find the current decryption keys from the LSA secrets store as
    1366             :  * G$BCKUPKEY_keyGuidString.
    1367             :  */
    1368             : 
    1369          14 : static WERROR bkrp_do_retrieve_default_server_wrap_key(TALLOC_CTX *mem_ctx,
    1370             :                                                        struct ldb_context *ldb_ctx,
    1371             :                                                        struct bkrp_dc_serverwrap_key *server_key,
    1372             :                                                        struct GUID *returned_guid)
    1373             : {
    1374           0 :         NTSTATUS status;
    1375           0 :         DATA_BLOB guid_binary;
    1376             : 
    1377          14 :         status = get_lsa_secret(mem_ctx, ldb_ctx, "BCKUPKEY_P", &guid_binary);
    1378          14 :         if (!NT_STATUS_IS_OK(status)) {
    1379           1 :                 DEBUG(10, ("Error while fetching secret BCKUPKEY_P to find current GUID\n"));
    1380           1 :                 return WERR_FILE_NOT_FOUND;
    1381          13 :         } else if (guid_binary.length == 0) {
    1382             :                 /* RODC case, we do not have secrets locally */
    1383           0 :                 DEBUG(1, ("Unable to fetch value for secret BCKUPKEY_P, are we an undetected RODC?\n"));
    1384           0 :                 return WERR_INTERNAL_ERROR;
    1385             :         }
    1386             : 
    1387          13 :         status = GUID_from_ndr_blob(&guid_binary, returned_guid);
    1388          13 :         if (!NT_STATUS_IS_OK(status)) {
    1389           0 :                 return WERR_FILE_NOT_FOUND;
    1390             :         }
    1391             : 
    1392          13 :         return bkrp_do_retrieve_server_wrap_key(mem_ctx, ldb_ctx,
    1393             :                                                 server_key, returned_guid);
    1394             : }
    1395             : 
    1396          30 : static WERROR bkrp_server_wrap_decrypt_data(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    1397             :                                             struct bkrp_BackupKey *r ,struct ldb_context *ldb_ctx)
    1398             : {
    1399           0 :         struct auth_session_info *session_info =
    1400          30 :                 dcesrv_call_session_info(dce_call);
    1401           0 :         WERROR werr;
    1402           0 :         struct bkrp_server_side_wrapped decrypt_request;
    1403           0 :         DATA_BLOB sid_blob, encrypted_blob;
    1404           0 :         DATA_BLOB blob;
    1405           0 :         enum ndr_err_code ndr_err;
    1406           0 :         struct bkrp_dc_serverwrap_key server_key;
    1407           0 :         struct bkrp_rc4encryptedpayload rc4payload;
    1408           0 :         struct dom_sid *caller_sid;
    1409           0 :         uint8_t symkey[20]; /* SHA-1 hash len */
    1410           0 :         uint8_t mackey[20]; /* SHA-1 hash len */
    1411           0 :         uint8_t mac[20]; /* SHA-1 hash len */
    1412           0 :         gnutls_hmac_hd_t hmac_hnd;
    1413           0 :         gnutls_cipher_hd_t cipher_hnd;
    1414           0 :         gnutls_datum_t cipher_key;
    1415           0 :         int rc;
    1416             : 
    1417          30 :         blob.data = r->in.data_in;
    1418          30 :         blob.length = r->in.data_in_len;
    1419             : 
    1420          30 :         if (r->in.data_in_len == 0 || r->in.data_in == NULL) {
    1421           1 :                 return WERR_INVALID_PARAMETER;
    1422             :         }
    1423             : 
    1424          29 :         ndr_err = ndr_pull_struct_blob_all(&blob, mem_ctx, &decrypt_request,
    1425             :                                            (ndr_pull_flags_fn_t)ndr_pull_bkrp_server_side_wrapped);
    1426          29 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1427          10 :                 return WERR_INVALID_PARAMETER;
    1428             :         }
    1429             : 
    1430          19 :         if (decrypt_request.magic != BACKUPKEY_SERVER_WRAP_VERSION) {
    1431           1 :                 return WERR_INVALID_PARAMETER;
    1432             :         }
    1433             : 
    1434          18 :         werr = bkrp_do_retrieve_server_wrap_key(mem_ctx, ldb_ctx, &server_key,
    1435             :                                                 &decrypt_request.guid);
    1436          18 :         if (!W_ERROR_IS_OK(werr)) {
    1437           2 :                 return werr;
    1438             :         }
    1439             : 
    1440          16 :         dump_data_pw("server_key: \n", server_key.key, sizeof(server_key.key));
    1441             : 
    1442          16 :         dump_data_pw("r2: \n", decrypt_request.r2, sizeof(decrypt_request.r2));
    1443             : 
    1444             :         /*
    1445             :          * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
    1446             :          * BACKUPKEY_BACKUP_GUID, it really is the whole key
    1447             :          */
    1448             : 
    1449          16 :         rc = gnutls_hmac_init(&hmac_hnd,
    1450             :                               GNUTLS_MAC_SHA1,
    1451             :                               server_key.key,
    1452             :                               sizeof(server_key.key));
    1453          16 :         if (rc != GNUTLS_E_SUCCESS) {
    1454           0 :                 return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
    1455             :         }
    1456             : 
    1457          16 :         rc = gnutls_hmac(hmac_hnd,
    1458             :                     decrypt_request.r2,
    1459             :                     sizeof(decrypt_request.r2));
    1460             : 
    1461          16 :         if (rc != GNUTLS_E_SUCCESS) {
    1462           0 :                 return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
    1463             :         }
    1464             : 
    1465          16 :         gnutls_hmac_output(hmac_hnd, symkey);
    1466          16 :         dump_data_pw("symkey: \n", symkey, sizeof(symkey));
    1467             : 
    1468             :         /* rc4 decrypt sid and secret using sym key */
    1469          16 :         cipher_key.data = symkey;
    1470          16 :         cipher_key.size = sizeof(symkey);
    1471             : 
    1472          16 :         encrypted_blob = data_blob_const(decrypt_request.rc4encryptedpayload,
    1473          16 :                                          decrypt_request.ciphertext_length);
    1474             : 
    1475          16 :         rc = gnutls_cipher_init(&cipher_hnd,
    1476             :                                 GNUTLS_CIPHER_ARCFOUR_128,
    1477             :                                 &cipher_key,
    1478             :                                 NULL);
    1479          16 :         if (rc != GNUTLS_E_SUCCESS) {
    1480           0 :                 return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
    1481             :         }
    1482          16 :         rc = gnutls_cipher_encrypt2(cipher_hnd,
    1483          16 :                                     encrypted_blob.data,
    1484             :                                     encrypted_blob.length,
    1485          16 :                                     encrypted_blob.data,
    1486             :                                     encrypted_blob.length);
    1487          16 :         gnutls_cipher_deinit(cipher_hnd);
    1488          16 :         if (rc != GNUTLS_E_SUCCESS) {
    1489           0 :                 return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
    1490             :         }
    1491             : 
    1492          16 :         ndr_err = ndr_pull_struct_blob_all(&encrypted_blob, mem_ctx, &rc4payload,
    1493             :                                            (ndr_pull_flags_fn_t)ndr_pull_bkrp_rc4encryptedpayload);
    1494          16 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1495           2 :                 return WERR_INVALID_PARAMETER;
    1496             :         }
    1497             : 
    1498          14 :         if (decrypt_request.payload_length != rc4payload.secret_data.length) {
    1499           8 :                 return WERR_INVALID_PARAMETER;
    1500             :         }
    1501             : 
    1502           6 :         dump_data_pw("r3: \n", rc4payload.r3, sizeof(rc4payload.r3));
    1503             : 
    1504             :         /*
    1505             :          * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
    1506             :          * BACKUPKEY_BACKUP_GUID, it really is the whole key
    1507             :          */
    1508           6 :         rc = gnutls_hmac(hmac_hnd,
    1509             :                          rc4payload.r3,
    1510             :                          sizeof(rc4payload.r3));
    1511           6 :         if (rc != GNUTLS_E_SUCCESS) {
    1512           0 :                 return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
    1513             :         }
    1514             : 
    1515           6 :         gnutls_hmac_deinit(hmac_hnd, mackey);
    1516             : 
    1517           6 :         dump_data_pw("mackey: \n", mackey, sizeof(mackey));
    1518             : 
    1519           6 :         ndr_err = ndr_push_struct_blob(&sid_blob, mem_ctx, &rc4payload.sid,
    1520             :                                        (ndr_push_flags_fn_t)ndr_push_dom_sid);
    1521           6 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1522           0 :                 return WERR_INTERNAL_ERROR;
    1523             :         }
    1524             : 
    1525           6 :         rc = gnutls_hmac_init(&hmac_hnd,
    1526             :                               GNUTLS_MAC_SHA1,
    1527             :                               mackey,
    1528             :                               sizeof(mackey));
    1529           6 :         if (rc != GNUTLS_E_SUCCESS) {
    1530           0 :                 return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
    1531             :         }
    1532             : 
    1533             :         /* SID field */
    1534           6 :         rc = gnutls_hmac(hmac_hnd,
    1535           6 :                          sid_blob.data,
    1536             :                          sid_blob.length);
    1537           6 :         if (rc != GNUTLS_E_SUCCESS) {
    1538           0 :                 return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
    1539             :         }
    1540             : 
    1541             :         /* Secret field */
    1542           6 :         rc = gnutls_hmac(hmac_hnd,
    1543           6 :                          rc4payload.secret_data.data,
    1544             :                          rc4payload.secret_data.length);
    1545           6 :         if (rc != GNUTLS_E_SUCCESS) {
    1546           0 :                 return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
    1547             :         }
    1548             : 
    1549           6 :         gnutls_hmac_deinit(hmac_hnd, mac);
    1550           6 :         dump_data_pw("mac: \n", mac, sizeof(mac));
    1551           6 :         dump_data_pw("rc4payload.mac: \n", rc4payload.mac, sizeof(rc4payload.mac));
    1552             : 
    1553           6 :         if (!mem_equal_const_time(mac, rc4payload.mac, sizeof(mac))) {
    1554           0 :                 return WERR_INVALID_ACCESS;
    1555             :         }
    1556             : 
    1557           6 :         caller_sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
    1558             : 
    1559           6 :         if (!dom_sid_equal(&rc4payload.sid, caller_sid)) {
    1560           2 :                 return WERR_INVALID_ACCESS;
    1561             :         }
    1562             : 
    1563           4 :         *(r->out.data_out) = rc4payload.secret_data.data;
    1564           4 :         *(r->out.data_out_len) = rc4payload.secret_data.length;
    1565             : 
    1566           4 :         return WERR_OK;
    1567             : }
    1568             : 
    1569             : /*
    1570             :  * For BACKUPKEY_RESTORE_GUID we need to check the first 4 bytes to
    1571             :  * determine what type of restore is wanted.
    1572             :  *
    1573             :  * See MS-BKRP 3.1.4.1.4 BACKUPKEY_RESTORE_GUID point 1.
    1574             :  */
    1575             : 
    1576          27 : static WERROR bkrp_generic_decrypt_data(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    1577             :                                         struct bkrp_BackupKey *r, struct ldb_context *ldb_ctx)
    1578             : {
    1579          27 :         if (r->in.data_in_len < 4 || r->in.data_in == NULL) {
    1580           3 :                 return WERR_INVALID_PARAMETER;
    1581             :         }
    1582             : 
    1583          24 :         if (IVAL(r->in.data_in, 0) == BACKUPKEY_SERVER_WRAP_VERSION) {
    1584          14 :                 return bkrp_server_wrap_decrypt_data(dce_call, mem_ctx, r, ldb_ctx);
    1585             :         }
    1586             : 
    1587          10 :         return bkrp_client_wrap_decrypt_data(dce_call, mem_ctx, r, ldb_ctx);
    1588             : }
    1589             : 
    1590             : /*
    1591             :  * We have some data, such as saved website or IMAP passwords that the
    1592             :  * client would like to put into the profile on-disk.  This needs to
    1593             :  * be encrypted.  This version gives the server the data over the
    1594             :  * network (protected only by the negotiated transport encryption),
    1595             :  * and asks that it be encrypted and returned for long-term storage.
    1596             :  *
    1597             :  * The data is NOT stored in the LSA, but a key to encrypt the data
    1598             :  * will be stored.  There is only one active encryption key per domain,
    1599             :  * it is pointed at with G$BCKUPKEY_P in the LSA secrets store.
    1600             :  *
    1601             :  * The potentially multiple valid decryption keys (and the encryption
    1602             :  * key) are in turn stored in the LSA secrets store as
    1603             :  * G$BCKUPKEY_keyGuidString.
    1604             :  *
    1605             :  */
    1606             : 
    1607          13 : static WERROR bkrp_server_wrap_encrypt_data(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    1608             :                                             struct bkrp_BackupKey *r ,struct ldb_context *ldb_ctx)
    1609             : {
    1610           0 :         struct auth_session_info *session_info =
    1611          13 :                 dcesrv_call_session_info(dce_call);
    1612           0 :         DATA_BLOB sid_blob, encrypted_blob, server_wrapped_blob;
    1613           0 :         WERROR werr;
    1614           0 :         struct dom_sid *caller_sid;
    1615           0 :         uint8_t symkey[20]; /* SHA-1 hash len */
    1616           0 :         uint8_t mackey[20]; /* SHA-1 hash len */
    1617           0 :         struct bkrp_rc4encryptedpayload rc4payload;
    1618           0 :         gnutls_hmac_hd_t hmac_hnd;
    1619           0 :         struct bkrp_dc_serverwrap_key server_key;
    1620           0 :         enum ndr_err_code ndr_err;
    1621           0 :         struct bkrp_server_side_wrapped server_side_wrapped;
    1622           0 :         struct GUID guid;
    1623           0 :         gnutls_cipher_hd_t cipher_hnd;
    1624           0 :         gnutls_datum_t cipher_key;
    1625           0 :         int rc;
    1626             : 
    1627          13 :         if (r->in.data_in_len == 0 || r->in.data_in == NULL) {
    1628           0 :                 return WERR_INVALID_PARAMETER;
    1629             :         }
    1630             : 
    1631          13 :         werr = bkrp_do_retrieve_default_server_wrap_key(mem_ctx,
    1632             :                                                         ldb_ctx, &server_key,
    1633             :                                                         &guid);
    1634             : 
    1635          13 :         if (!W_ERROR_IS_OK(werr)) {
    1636           1 :                 if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
    1637             :                         /* Generate the server wrap key since one wasn't found */
    1638           1 :                         werr =  generate_bkrp_server_wrap_key(mem_ctx,
    1639             :                                                               ldb_ctx);
    1640           1 :                         if (!W_ERROR_IS_OK(werr)) {
    1641           0 :                                 return WERR_INVALID_PARAMETER;
    1642             :                         }
    1643           1 :                         werr = bkrp_do_retrieve_default_server_wrap_key(mem_ctx,
    1644             :                                                                         ldb_ctx,
    1645             :                                                                         &server_key,
    1646             :                                                                         &guid);
    1647             : 
    1648           1 :                         if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
    1649             :                                 /* Ok we really don't manage to get this secret ...*/
    1650           0 :                                 return WERR_FILE_NOT_FOUND;
    1651             :                         }
    1652             :                 } else {
    1653             :                         /* In theory we should NEVER reach this point as it
    1654             :                            should only appear in a rodc server */
    1655             :                         /* we do not have the real secret attribute */
    1656           0 :                         return WERR_INVALID_PARAMETER;
    1657             :                 }
    1658             :         }
    1659             : 
    1660          13 :         caller_sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
    1661             : 
    1662          13 :         dump_data_pw("server_key: \n", server_key.key, sizeof(server_key.key));
    1663             : 
    1664             :         /*
    1665             :          * This is the key derivation step, so that the HMAC and RC4
    1666             :          * operations over the user-supplied data are not able to
    1667             :          * disclose the master key.  By using random data, the symkey
    1668             :          * and mackey values are unique for this operation, and
    1669             :          * discovering these (by reversing the RC4 over the
    1670             :          * attacker-controlled data) does not return something able to
    1671             :          * be used to decrypt the encrypted data of other users
    1672             :          */
    1673          13 :         generate_random_buffer(server_side_wrapped.r2, sizeof(server_side_wrapped.r2));
    1674             : 
    1675          13 :         dump_data_pw("r2: \n", server_side_wrapped.r2, sizeof(server_side_wrapped.r2));
    1676             : 
    1677          13 :         generate_random_buffer(rc4payload.r3, sizeof(rc4payload.r3));
    1678             : 
    1679          13 :         dump_data_pw("r3: \n", rc4payload.r3, sizeof(rc4payload.r3));
    1680             : 
    1681             : 
    1682             :         /*
    1683             :          * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
    1684             :          * BACKUPKEY_BACKUP_GUID, it really is the whole key
    1685             :          */
    1686          13 :         rc = gnutls_hmac_init(&hmac_hnd,
    1687             :                               GNUTLS_MAC_SHA1,
    1688             :                               server_key.key,
    1689             :                               sizeof(server_key.key));
    1690          13 :         if (rc != GNUTLS_E_SUCCESS) {
    1691           0 :                 return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
    1692             :         }
    1693             : 
    1694          13 :         rc = gnutls_hmac(hmac_hnd,
    1695             :                          server_side_wrapped.r2,
    1696             :                          sizeof(server_side_wrapped.r2));
    1697          13 :         if (rc != GNUTLS_E_SUCCESS) {
    1698           0 :                 return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
    1699             :         }
    1700          13 :         gnutls_hmac_output(hmac_hnd, symkey);
    1701          13 :         dump_data_pw("symkey: \n", symkey, sizeof(symkey));
    1702             : 
    1703             :         /*
    1704             :          * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
    1705             :          * BACKUPKEY_BACKUP_GUID, it really is the whole key
    1706             :          */
    1707          13 :         rc = gnutls_hmac(hmac_hnd,
    1708             :                          rc4payload.r3,
    1709             :                          sizeof(rc4payload.r3));
    1710          13 :         if (rc != GNUTLS_E_SUCCESS) {
    1711           0 :                 return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
    1712             :         }
    1713          13 :         gnutls_hmac_deinit(hmac_hnd, mackey);
    1714          13 :         dump_data_pw("mackey: \n", mackey, sizeof(mackey));
    1715             : 
    1716          13 :         ndr_err = ndr_push_struct_blob(&sid_blob, mem_ctx, caller_sid,
    1717             :                                        (ndr_push_flags_fn_t)ndr_push_dom_sid);
    1718          13 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1719           0 :                 return WERR_INTERNAL_ERROR;
    1720             :         }
    1721             : 
    1722          13 :         rc4payload.secret_data.data = r->in.data_in;
    1723          13 :         rc4payload.secret_data.length = r->in.data_in_len;
    1724             : 
    1725          13 :         rc = gnutls_hmac_init(&hmac_hnd,
    1726             :                               GNUTLS_MAC_SHA1,
    1727             :                               mackey,
    1728             :                               sizeof(mackey));
    1729          13 :         if (rc != GNUTLS_E_SUCCESS) {
    1730           0 :                 return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
    1731             :         }
    1732             : 
    1733             :         /* SID field */
    1734          13 :         rc = gnutls_hmac(hmac_hnd,
    1735          13 :                          sid_blob.data,
    1736             :                          sid_blob.length);
    1737          13 :         if (rc != GNUTLS_E_SUCCESS) {
    1738           0 :                 return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
    1739             :         }
    1740             : 
    1741             :         /* Secret field */
    1742          13 :         rc = gnutls_hmac(hmac_hnd,
    1743          13 :                          rc4payload.secret_data.data,
    1744             :                          rc4payload.secret_data.length);
    1745          13 :         if (rc != GNUTLS_E_SUCCESS) {
    1746           0 :                 return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
    1747             :         }
    1748             : 
    1749          13 :         gnutls_hmac_deinit(hmac_hnd, rc4payload.mac);
    1750          13 :         dump_data_pw("rc4payload.mac: \n", rc4payload.mac, sizeof(rc4payload.mac));
    1751             : 
    1752          13 :         rc4payload.sid = *caller_sid;
    1753             : 
    1754          13 :         ndr_err = ndr_push_struct_blob(&encrypted_blob, mem_ctx, &rc4payload,
    1755             :                                        (ndr_push_flags_fn_t)ndr_push_bkrp_rc4encryptedpayload);
    1756          13 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1757           0 :                 return WERR_INTERNAL_ERROR;
    1758             :         }
    1759             : 
    1760             :         /* rc4 encrypt sid and secret using sym key */
    1761          13 :         cipher_key.data = symkey;
    1762          13 :         cipher_key.size = sizeof(symkey);
    1763             : 
    1764          13 :         rc = gnutls_cipher_init(&cipher_hnd,
    1765             :                                 GNUTLS_CIPHER_ARCFOUR_128,
    1766             :                                 &cipher_key,
    1767             :                                 NULL);
    1768          13 :         if (rc != GNUTLS_E_SUCCESS) {
    1769           0 :                 return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
    1770             :         }
    1771          13 :         rc = gnutls_cipher_encrypt2(cipher_hnd,
    1772          13 :                                     encrypted_blob.data,
    1773             :                                     encrypted_blob.length,
    1774          13 :                                     encrypted_blob.data,
    1775             :                                     encrypted_blob.length);
    1776          13 :         gnutls_cipher_deinit(cipher_hnd);
    1777          13 :         if (rc != GNUTLS_E_SUCCESS) {
    1778           0 :                 return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
    1779             :         }
    1780             : 
    1781             :         /* create server wrap structure */
    1782             : 
    1783          13 :         server_side_wrapped.payload_length = rc4payload.secret_data.length;
    1784          13 :         server_side_wrapped.ciphertext_length = encrypted_blob.length;
    1785          13 :         server_side_wrapped.guid = guid;
    1786          13 :         server_side_wrapped.rc4encryptedpayload = encrypted_blob.data;
    1787             : 
    1788          13 :         ndr_err = ndr_push_struct_blob(&server_wrapped_blob, mem_ctx, &server_side_wrapped,
    1789             :                                        (ndr_push_flags_fn_t)ndr_push_bkrp_server_side_wrapped);
    1790          13 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1791           0 :                 return WERR_INTERNAL_ERROR;
    1792             :         }
    1793             : 
    1794          13 :         *(r->out.data_out) = server_wrapped_blob.data;
    1795          13 :         *(r->out.data_out_len) = server_wrapped_blob.length;
    1796             : 
    1797          13 :         return WERR_OK;
    1798             : }
    1799             : 
    1800          69 : static WERROR dcesrv_bkrp_BackupKey(struct dcesrv_call_state *dce_call,
    1801             :                                     TALLOC_CTX *mem_ctx, struct bkrp_BackupKey *r)
    1802             : {
    1803          69 :         WERROR error = WERR_INVALID_PARAMETER;
    1804           0 :         struct ldb_context *ldb_ctx;
    1805           0 :         bool is_rodc;
    1806          69 :         const char *addr = "unknown";
    1807             :         /* At which level we start to add more debug of what is done in the protocol */
    1808          69 :         const int debuglevel = 4;
    1809             : 
    1810          69 :         if (DEBUGLVL(debuglevel)) {
    1811           0 :                 const struct tsocket_address *remote_address;
    1812           0 :                 remote_address = dcesrv_connection_get_remote_address(dce_call->conn);
    1813           0 :                 if (tsocket_address_is_inet(remote_address, "ip")) {
    1814           0 :                         addr = tsocket_address_inet_addr_string(remote_address, mem_ctx);
    1815           0 :                         W_ERROR_HAVE_NO_MEMORY(addr);
    1816             :                 }
    1817             :         }
    1818             : 
    1819          69 :         if (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx) != ROLE_ACTIVE_DIRECTORY_DC) {
    1820           0 :                 return WERR_NOT_SUPPORTED;
    1821             :         }
    1822             : 
    1823             :         /*
    1824             :          * Save the current remote session details so they can used by the
    1825             :          * audit logging module. This allows the audit logging to report the
    1826             :          * remote users details, rather than the system users details.
    1827             :          */
    1828          69 :         ldb_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
    1829             : 
    1830          69 :         if (samdb_rodc(ldb_ctx, &is_rodc) != LDB_SUCCESS) {
    1831           0 :                 talloc_unlink(mem_ctx, ldb_ctx);
    1832           0 :                 return WERR_INVALID_PARAMETER;
    1833             :         }
    1834             : 
    1835          69 :         if (!is_rodc) {
    1836          69 :                 if(strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent),
    1837             :                         BACKUPKEY_RESTORE_GUID, strlen(BACKUPKEY_RESTORE_GUID)) == 0) {
    1838          27 :                         DEBUG(debuglevel, ("Client %s requested to decrypt a wrapped secret\n", addr));
    1839          27 :                         error = bkrp_generic_decrypt_data(dce_call, mem_ctx, r, ldb_ctx);
    1840             :                 }
    1841             : 
    1842          69 :                 if (strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent),
    1843             :                         BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID, strlen(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID)) == 0) {
    1844          13 :                         DEBUG(debuglevel, ("Client %s requested certificate for client wrapped secret\n", addr));
    1845          13 :                         error = bkrp_retrieve_client_wrap_key(dce_call, mem_ctx, r, ldb_ctx);
    1846             :                 }
    1847             : 
    1848          69 :                 if (strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent),
    1849             :                         BACKUPKEY_RESTORE_GUID_WIN2K, strlen(BACKUPKEY_RESTORE_GUID_WIN2K)) == 0) {
    1850          16 :                         DEBUG(debuglevel, ("Client %s requested to decrypt a server side wrapped secret\n", addr));
    1851          16 :                         error = bkrp_server_wrap_decrypt_data(dce_call, mem_ctx, r, ldb_ctx);
    1852             :                 }
    1853             : 
    1854          69 :                 if (strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent),
    1855             :                         BACKUPKEY_BACKUP_GUID, strlen(BACKUPKEY_BACKUP_GUID)) == 0) {
    1856          13 :                         DEBUG(debuglevel, ("Client %s requested a server wrapped secret\n", addr));
    1857          13 :                         error = bkrp_server_wrap_encrypt_data(dce_call, mem_ctx, r, ldb_ctx);
    1858             :                 }
    1859             :         }
    1860             :         /*else: I am a RODC so I don't handle backup key protocol */
    1861             : 
    1862          69 :         talloc_unlink(mem_ctx, ldb_ctx);
    1863          69 :         return error;
    1864             : }
    1865             : 
    1866             : /* include the generated boilerplate */
    1867             : #include "librpc/gen_ndr/ndr_backupkey_s.c"

Generated by: LCOV version 1.14