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