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