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