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