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