backupkey: Improve function names and comments for clarity
[Samba.git] / source4 / rpc_server / backupkey / dcesrv_backupkey.c
bloba6484cdd9ea2f6951654feb36249eb3daa55af58
1 /*
2 Unix SMB/CIFS implementation.
4 endpoint server for the backupkey interface
6 Copyright (C) Matthieu Patou <mat@samba.org> 2010
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.
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.
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/>.
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 <der.h>
38 #include "../lib/tsocket/tsocket.h"
39 #include "../libcli/security/security.h"
41 #define BACKUPKEY_MIN_VERSION 2
42 #define BACKUPKEY_MAX_VERSION 3
44 static const unsigned rsa_with_var_num[] = { 1, 2, 840, 113549, 1, 1, 1 };
45 /* Equivalent to asn1_oid_id_pkcs1_rsaEncryption*/
46 static const AlgorithmIdentifier _hx509_signature_rsa_with_var_num = {
47 { 7, discard_const_p(unsigned, rsa_with_var_num) }, NULL
50 static NTSTATUS set_lsa_secret(TALLOC_CTX *mem_ctx,
51 struct ldb_context *ldb,
52 const char *name,
53 const DATA_BLOB *secret)
55 struct ldb_message *msg;
56 struct ldb_result *res;
57 struct ldb_dn *domain_dn;
58 struct ldb_dn *system_dn;
59 struct ldb_val val;
60 int ret;
61 char *name2;
62 struct timeval now = timeval_current();
63 NTTIME nt_now = timeval_to_nttime(&now);
64 const char *attrs[] = {
65 NULL
68 domain_dn = ldb_get_default_basedn(ldb);
69 if (!domain_dn) {
70 return NT_STATUS_INTERNAL_ERROR;
73 msg = ldb_msg_new(mem_ctx);
74 if (msg == NULL) {
75 return NT_STATUS_NO_MEMORY;
79 * This function is a lot like dcesrv_lsa_CreateSecret
80 * in the rpc_server/lsa directory
81 * The reason why we duplicate the effort here is that:
82 * * we want to keep the former function static
83 * * we want to avoid the burden of doing LSA calls
84 * when we can just manipulate the secrets directly
85 * * taillor the function to the particular needs of backup protocol
88 system_dn = samdb_search_dn(ldb, msg, domain_dn, "(&(objectClass=container)(cn=System))");
89 if (system_dn == NULL) {
90 talloc_free(msg);
91 return NT_STATUS_NO_MEMORY;
94 name2 = talloc_asprintf(msg, "%s Secret", name);
95 if (name2 == NULL) {
96 talloc_free(msg);
97 return NT_STATUS_NO_MEMORY;
100 ret = ldb_search(ldb, mem_ctx, &res, system_dn, LDB_SCOPE_SUBTREE, attrs,
101 "(&(cn=%s)(objectclass=secret))",
102 ldb_binary_encode_string(mem_ctx, name2));
104 if (ret != LDB_SUCCESS || res->count != 0 ) {
105 DEBUG(2, ("Secret %s already exists !\n", name2));
106 talloc_free(msg);
107 return NT_STATUS_OBJECT_NAME_COLLISION;
111 * We don't care about previous value as we are
112 * here only if the key didn't exists before
115 msg->dn = ldb_dn_copy(mem_ctx, system_dn);
116 if (msg->dn == NULL) {
117 talloc_free(msg);
118 return NT_STATUS_NO_MEMORY;
120 if (!ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
121 talloc_free(msg);
122 return NT_STATUS_NO_MEMORY;
125 ret = ldb_msg_add_string(msg, "cn", name2);
126 if (ret != LDB_SUCCESS) {
127 talloc_free(msg);
128 return NT_STATUS_NO_MEMORY;
130 ret = ldb_msg_add_string(msg, "objectClass", "secret");
131 if (ret != LDB_SUCCESS) {
132 talloc_free(msg);
133 return NT_STATUS_NO_MEMORY;
135 ret = samdb_msg_add_uint64(ldb, mem_ctx, msg, "priorSetTime", nt_now);
136 if (ret != LDB_SUCCESS) {
137 talloc_free(msg);
138 return NT_STATUS_NO_MEMORY;
140 val.data = secret->data;
141 val.length = secret->length;
142 ret = ldb_msg_add_value(msg, "currentValue", &val, NULL);
143 if (ret != LDB_SUCCESS) {
144 talloc_free(msg);
145 return NT_STATUS_NO_MEMORY;
147 ret = samdb_msg_add_uint64(ldb, mem_ctx, msg, "lastSetTime", nt_now);
148 if (ret != LDB_SUCCESS) {
149 talloc_free(msg);
150 return NT_STATUS_NO_MEMORY;
154 * create the secret with DSDB_MODIFY_RELAX
155 * otherwise dsdb/samdb/ldb_modules/objectclass.c forbid
156 * the create of LSA secret object
158 ret = dsdb_add(ldb, msg, DSDB_MODIFY_RELAX);
159 if (ret != LDB_SUCCESS) {
160 DEBUG(2,("Failed to create secret record %s: %s\n",
161 ldb_dn_get_linearized(msg->dn),
162 ldb_errstring(ldb)));
163 talloc_free(msg);
164 return NT_STATUS_ACCESS_DENIED;
167 talloc_free(msg);
168 return NT_STATUS_OK;
171 /* This function is pretty much like dcesrv_lsa_QuerySecret */
172 static NTSTATUS get_lsa_secret(TALLOC_CTX *mem_ctx,
173 struct ldb_context *ldb,
174 const char *name,
175 DATA_BLOB *secret)
177 TALLOC_CTX *tmp_mem;
178 struct ldb_result *res;
179 struct ldb_dn *domain_dn;
180 struct ldb_dn *system_dn;
181 const struct ldb_val *val;
182 uint8_t *data;
183 const char *attrs[] = {
184 "currentValue",
185 NULL
187 int ret;
189 secret->data = NULL;
190 secret->length = 0;
192 domain_dn = ldb_get_default_basedn(ldb);
193 if (!domain_dn) {
194 return NT_STATUS_INTERNAL_ERROR;
197 tmp_mem = talloc_new(mem_ctx);
198 if (tmp_mem == NULL) {
199 return NT_STATUS_NO_MEMORY;
202 system_dn = samdb_search_dn(ldb, tmp_mem, domain_dn, "(&(objectClass=container)(cn=System))");
203 if (system_dn == NULL) {
204 talloc_free(tmp_mem);
205 return NT_STATUS_NO_MEMORY;
208 ret = ldb_search(ldb, mem_ctx, &res, system_dn, LDB_SCOPE_SUBTREE, attrs,
209 "(&(cn=%s Secret)(objectclass=secret))",
210 ldb_binary_encode_string(tmp_mem, name));
212 if (ret != LDB_SUCCESS || res->count == 0) {
213 talloc_free(tmp_mem);
215 * Important NOT to use NT_STATUS_OBJECT_NAME_NOT_FOUND
216 * as this return value is used to detect the case
217 * when we have the secret but without the currentValue
218 * (case RODC)
220 return NT_STATUS_RESOURCE_NAME_NOT_FOUND;
223 if (res->count > 1) {
224 DEBUG(2, ("Secret %s collision\n", name));
225 talloc_free(tmp_mem);
226 return NT_STATUS_INTERNAL_DB_CORRUPTION;
229 val = ldb_msg_find_ldb_val(res->msgs[0], "currentValue");
230 if (val == NULL) {
232 * The secret object is here but we don't have the secret value
233 * The most common case is a RODC
235 talloc_free(tmp_mem);
236 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
239 data = val->data;
240 secret->data = talloc_move(mem_ctx, &data);
241 secret->length = val->length;
243 talloc_free(tmp_mem);
244 return NT_STATUS_OK;
247 static DATA_BLOB *reverse_and_get_blob(TALLOC_CTX *mem_ctx, BIGNUM *bn)
249 DATA_BLOB blob;
250 DATA_BLOB *rev = talloc(mem_ctx, DATA_BLOB);
251 uint32_t i;
253 blob.length = BN_num_bytes(bn);
254 blob.data = talloc_array(mem_ctx, uint8_t, blob.length);
256 if (blob.data == NULL) {
257 return NULL;
260 BN_bn2bin(bn, blob.data);
262 rev->data = talloc_array(mem_ctx, uint8_t, blob.length);
263 if (rev->data == NULL) {
264 return NULL;
267 for(i=0; i < blob.length; i++) {
268 rev->data[i] = blob.data[blob.length - i -1];
270 rev->length = blob.length;
271 talloc_free(blob.data);
272 return rev;
275 static BIGNUM *reverse_and_get_bignum(TALLOC_CTX *mem_ctx, DATA_BLOB *blob)
277 BIGNUM *ret;
278 DATA_BLOB rev;
279 uint32_t i;
281 rev.data = talloc_array(mem_ctx, uint8_t, blob->length);
282 if (rev.data == NULL) {
283 return NULL;
286 for(i=0; i < blob->length; i++) {
287 rev.data[i] = blob->data[blob->length - i -1];
289 rev.length = blob->length;
291 ret = BN_bin2bn(rev.data, rev.length, NULL);
292 talloc_free(rev.data);
294 return ret;
297 static NTSTATUS get_pk_from_raw_keypair_params(TALLOC_CTX *ctx,
298 struct bkrp_exported_RSA_key_pair *keypair,
299 hx509_private_key *pk)
301 hx509_context hctx;
302 RSA *rsa;
303 struct hx509_private_key_ops *ops;
305 hx509_context_init(&hctx);
306 ops = hx509_find_private_alg(&_hx509_signature_rsa_with_var_num.algorithm);
307 if (ops == NULL) {
308 DEBUG(2, ("Not supported algorithm\n"));
309 return NT_STATUS_INTERNAL_ERROR;
312 if (hx509_private_key_init(pk, ops, NULL) != 0) {
313 hx509_context_free(&hctx);
314 return NT_STATUS_NO_MEMORY;
317 rsa = RSA_new();
318 if (rsa ==NULL) {
319 hx509_context_free(&hctx);
320 return NT_STATUS_INVALID_PARAMETER;
323 rsa->n = reverse_and_get_bignum(ctx, &(keypair->modulus));
324 if (rsa->n == NULL) {
325 RSA_free(rsa);
326 hx509_context_free(&hctx);
327 return NT_STATUS_INVALID_PARAMETER;
329 rsa->d = reverse_and_get_bignum(ctx, &(keypair->private_exponent));
330 if (rsa->d == NULL) {
331 RSA_free(rsa);
332 hx509_context_free(&hctx);
333 return NT_STATUS_INVALID_PARAMETER;
335 rsa->p = reverse_and_get_bignum(ctx, &(keypair->prime1));
336 if (rsa->p == NULL) {
337 RSA_free(rsa);
338 hx509_context_free(&hctx);
339 return NT_STATUS_INVALID_PARAMETER;
341 rsa->q = reverse_and_get_bignum(ctx, &(keypair->prime2));
342 if (rsa->q == NULL) {
343 RSA_free(rsa);
344 hx509_context_free(&hctx);
345 return NT_STATUS_INVALID_PARAMETER;
347 rsa->dmp1 = reverse_and_get_bignum(ctx, &(keypair->exponent1));
348 if (rsa->dmp1 == NULL) {
349 RSA_free(rsa);
350 hx509_context_free(&hctx);
351 return NT_STATUS_INVALID_PARAMETER;
353 rsa->dmq1 = reverse_and_get_bignum(ctx, &(keypair->exponent2));
354 if (rsa->dmq1 == NULL) {
355 RSA_free(rsa);
356 hx509_context_free(&hctx);
357 return NT_STATUS_INVALID_PARAMETER;
359 rsa->iqmp = reverse_and_get_bignum(ctx, &(keypair->coefficient));
360 if (rsa->iqmp == NULL) {
361 RSA_free(rsa);
362 hx509_context_free(&hctx);
363 return NT_STATUS_INVALID_PARAMETER;
365 rsa->e = reverse_and_get_bignum(ctx, &(keypair->public_exponent));
366 if (rsa->e == NULL) {
367 RSA_free(rsa);
368 hx509_context_free(&hctx);
369 return NT_STATUS_INVALID_PARAMETER;
372 hx509_private_key_assign_rsa(*pk, rsa);
374 hx509_context_free(&hctx);
375 return NT_STATUS_OK;
378 static WERROR get_and_verify_access_check(TALLOC_CTX *sub_ctx,
379 uint32_t version,
380 uint8_t *key_and_iv,
381 uint8_t *access_check,
382 uint32_t access_check_len,
383 struct auth_session_info *session_info)
385 heim_octet_string iv;
386 heim_octet_string access_check_os;
387 hx509_crypto crypto;
389 DATA_BLOB blob_us;
390 uint32_t key_len;
391 uint32_t iv_len;
392 int res;
393 enum ndr_err_code ndr_err;
394 hx509_context hctx;
396 struct dom_sid *access_sid = NULL;
397 struct dom_sid *caller_sid = NULL;
399 /* This one should not be freed */
400 const AlgorithmIdentifier *alg;
402 switch (version) {
403 case 2:
404 key_len = 24;
405 iv_len = 8;
406 alg = hx509_crypto_des_rsdi_ede3_cbc();
407 break;
409 case 3:
410 key_len = 32;
411 iv_len = 16;
412 alg =hx509_crypto_aes256_cbc();
413 break;
415 default:
416 return WERR_INVALID_DATA;
419 hx509_context_init(&hctx);
420 res = hx509_crypto_init(hctx, NULL,
421 &(alg->algorithm),
422 &crypto);
423 hx509_context_free(&hctx);
425 if (res != 0) {
426 return WERR_INVALID_DATA;
429 res = hx509_crypto_set_key_data(crypto, key_and_iv, key_len);
431 iv.data = talloc_memdup(sub_ctx, key_len + key_and_iv, iv_len);
432 iv.length = iv_len;
434 if (res != 0) {
435 hx509_crypto_destroy(crypto);
436 return WERR_INVALID_DATA;
439 hx509_crypto_set_padding(crypto, HX509_CRYPTO_PADDING_NONE);
440 res = hx509_crypto_decrypt(crypto,
441 access_check,
442 access_check_len,
443 &iv,
444 &access_check_os);
446 if (res != 0) {
447 hx509_crypto_destroy(crypto);
448 return WERR_INVALID_DATA;
451 blob_us.data = access_check_os.data;
452 blob_us.length = access_check_os.length;
454 hx509_crypto_destroy(crypto);
456 switch (version) {
457 case 2:
459 uint32_t hash_size = 20;
460 uint8_t hash[hash_size];
461 struct sha sctx;
462 struct bkrp_access_check_v2 uncrypted_accesscheckv2;
464 ndr_err = ndr_pull_struct_blob(&blob_us, sub_ctx, &uncrypted_accesscheckv2,
465 (ndr_pull_flags_fn_t)ndr_pull_bkrp_access_check_v2);
466 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
467 /* Unable to unmarshall */
468 der_free_octet_string(&access_check_os);
469 return WERR_INVALID_DATA;
471 if (uncrypted_accesscheckv2.magic != 0x1) {
472 /* wrong magic */
473 der_free_octet_string(&access_check_os);
474 return WERR_INVALID_DATA;
477 SHA1_Init(&sctx);
478 SHA1_Update(&sctx, blob_us.data, blob_us.length - hash_size);
479 SHA1_Final(hash, &sctx);
480 der_free_octet_string(&access_check_os);
482 * We free it after the sha1 calculation because blob.data
483 * point to the same area
486 if (memcmp(hash, uncrypted_accesscheckv2.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;
490 access_sid = &(uncrypted_accesscheckv2.sid);
491 break;
493 case 3:
495 uint32_t hash_size = 64;
496 uint8_t hash[hash_size];
497 struct hc_sha512state sctx;
498 struct bkrp_access_check_v3 uncrypted_accesscheckv3;
500 ndr_err = ndr_pull_struct_blob(&blob_us, sub_ctx, &uncrypted_accesscheckv3,
501 (ndr_pull_flags_fn_t)ndr_pull_bkrp_access_check_v3);
502 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
503 /* Unable to unmarshall */
504 der_free_octet_string(&access_check_os);
505 return WERR_INVALID_DATA;
507 if (uncrypted_accesscheckv3.magic != 0x1) {
508 /* wrong magic */
509 der_free_octet_string(&access_check_os);
510 return WERR_INVALID_DATA;
513 SHA512_Init(&sctx);
514 SHA512_Update(&sctx, blob_us.data, blob_us.length - hash_size);
515 SHA512_Final(hash, &sctx);
516 der_free_octet_string(&access_check_os);
518 * We free it after the sha1 calculation because blob.data
519 * point to the same area
522 if (memcmp(hash, uncrypted_accesscheckv3.hash, hash_size) != 0) {
523 DEBUG(2, ("Wrong hash value in the access check in backup key remote protocol\n"));
524 return WERR_INVALID_DATA;
526 access_sid = &(uncrypted_accesscheckv3.sid);
527 break;
529 default:
530 /* Never reached normally as we filtered at the switch / case level */
531 return WERR_INVALID_DATA;
534 caller_sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
536 if (!dom_sid_equal(caller_sid, access_sid)) {
537 return WERR_INVALID_ACCESS;
539 return WERR_OK;
543 * We have some data, such as saved website or IMAP passwords that the
544 * client has in profile on-disk. This needs to be decrypted. This
545 * version gives the server the data over the network (protected by
546 * the X.509 certificate and public key encryption, and asks that it
547 * be decrypted returned for short-term use, protected only by the
548 * negotiated transport encryption.
550 * The data is NOT stored in the LSA, but a X.509 certificate, public
551 * and private keys used to encrypt the data will be stored. There is
552 * only one active encryption key pair and certificate per domain, it
553 * is pointed at with G$BCKUPKEY_PREFERRED in the LSA secrets store.
555 * The potentially multiple valid decrypting key pairs are in turn
556 * stored in the LSA secrets store as G$BCKUPKEY_keyGuidString.
559 static WERROR bkrp_client_wrap_decrypt_data(struct dcesrv_call_state *dce_call,
560 TALLOC_CTX *mem_ctx,
561 struct bkrp_BackupKey *r,
562 struct ldb_context *ldb_ctx)
564 struct bkrp_client_side_wrapped uncrypt_request;
565 DATA_BLOB blob;
566 enum ndr_err_code ndr_err;
567 char *guid_string;
568 char *cert_secret_name;
569 DATA_BLOB secret;
570 DATA_BLOB *uncrypted;
571 NTSTATUS status;
573 blob.data = r->in.data_in;
574 blob.length = r->in.data_in_len;
576 if (r->in.data_in_len == 0 || r->in.data_in == NULL) {
577 return WERR_INVALID_PARAM;
580 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &uncrypt_request,
581 (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_wrapped);
582 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
583 return WERR_INVALID_PARAM;
586 if (uncrypt_request.version < BACKUPKEY_MIN_VERSION) {
587 return WERR_INVALID_PARAMETER;
590 if (uncrypt_request.version > BACKUPKEY_MAX_VERSION) {
591 return WERR_INVALID_PARAMETER;
594 guid_string = GUID_string(mem_ctx, &uncrypt_request.guid);
595 if (guid_string == NULL) {
596 return WERR_NOMEM;
599 cert_secret_name = talloc_asprintf(mem_ctx,
600 "BCKUPKEY_%s",
601 guid_string);
602 if (cert_secret_name == NULL) {
603 return WERR_NOMEM;
606 status = get_lsa_secret(mem_ctx,
607 ldb_ctx,
608 cert_secret_name,
609 &secret);
610 if (!NT_STATUS_IS_OK(status)) {
611 DEBUG(10, ("Error while fetching secret %s\n", cert_secret_name));
612 if (NT_STATUS_EQUAL(status,NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
613 /* we do not have the real secret attribute */
614 return WERR_INVALID_PARAMETER;
615 } else {
616 return WERR_FILE_NOT_FOUND;
620 if (secret.length != 0) {
621 hx509_context hctx;
622 struct bkrp_exported_RSA_key_pair keypair;
623 hx509_private_key pk;
624 uint32_t i, res;
625 heim_octet_string reversed_secret;
626 heim_octet_string uncrypted_secret;
627 AlgorithmIdentifier alg;
628 DATA_BLOB blob_us;
629 WERROR werr;
631 ndr_err = ndr_pull_struct_blob(&secret, mem_ctx, &keypair, (ndr_pull_flags_fn_t)ndr_pull_bkrp_exported_RSA_key_pair);
632 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
633 DEBUG(2, ("Unable to parse the ndr encoded cert in key %s\n", cert_secret_name));
634 return WERR_FILE_NOT_FOUND;
637 status = get_pk_from_raw_keypair_params(mem_ctx, &keypair, &pk);
638 if (!NT_STATUS_IS_OK(status)) {
639 return WERR_INTERNAL_ERROR;
642 reversed_secret.data = talloc_array(mem_ctx, uint8_t,
643 uncrypt_request.encrypted_secret_len);
644 if (reversed_secret.data == NULL) {
645 hx509_private_key_free(&pk);
646 return WERR_NOMEM;
649 /* The secret has to be reversed ... */
650 for(i=0; i< uncrypt_request.encrypted_secret_len; i++) {
651 uint8_t *reversed = (uint8_t *)reversed_secret.data;
652 uint8_t *uncrypt = uncrypt_request.encrypted_secret;
653 reversed[i] = uncrypt[uncrypt_request.encrypted_secret_len - 1 - i];
655 reversed_secret.length = uncrypt_request.encrypted_secret_len;
658 * Let's try to decrypt the secret now that
659 * we have the private key ...
661 hx509_context_init(&hctx);
662 res = hx509_private_key_private_decrypt(hctx, &reversed_secret,
663 &alg.algorithm, pk,
664 &uncrypted_secret);
665 hx509_context_free(&hctx);
666 hx509_private_key_free(&pk);
667 if (res != 0) {
668 /* We are not able to decrypt the secret, looks like something is wrong */
669 return WERR_INVALID_DATA;
671 blob_us.data = uncrypted_secret.data;
672 blob_us.length = uncrypted_secret.length;
674 if (uncrypt_request.version == 2) {
675 struct bkrp_encrypted_secret_v2 uncrypted_secretv2;
677 ndr_err = ndr_pull_struct_blob(&blob_us, mem_ctx, &uncrypted_secretv2,
678 (ndr_pull_flags_fn_t)ndr_pull_bkrp_encrypted_secret_v2);
679 der_free_octet_string(&uncrypted_secret);
680 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
681 /* Unable to unmarshall */
682 return WERR_INVALID_DATA;
684 if (uncrypted_secretv2.magic != 0x20) {
685 /* wrong magic */
686 return WERR_INVALID_DATA;
689 werr = get_and_verify_access_check(mem_ctx, 2,
690 uncrypted_secretv2.payload_key,
691 uncrypt_request.access_check,
692 uncrypt_request.access_check_len,
693 dce_call->conn->auth_state.session_info);
694 if (!W_ERROR_IS_OK(werr)) {
695 return werr;
697 uncrypted = talloc(mem_ctx, DATA_BLOB);
698 if (uncrypted == NULL) {
699 return WERR_INVALID_DATA;
702 uncrypted->data = uncrypted_secretv2.secret;
703 uncrypted->length = uncrypted_secretv2.secret_len;
705 if (uncrypt_request.version == 3) {
706 struct bkrp_encrypted_secret_v3 uncrypted_secretv3;
708 ndr_err = ndr_pull_struct_blob(&blob_us, mem_ctx, &uncrypted_secretv3,
709 (ndr_pull_flags_fn_t)ndr_pull_bkrp_encrypted_secret_v3);
711 der_free_octet_string(&uncrypted_secret);
712 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
713 /* Unable to unmarshall */
714 return WERR_INVALID_DATA;
717 if (uncrypted_secretv3.magic1 != 0x30 ||
718 uncrypted_secretv3.magic2 != 0x6610 ||
719 uncrypted_secretv3.magic3 != 0x800e) {
720 /* wrong magic */
721 return WERR_INVALID_DATA;
725 * Confirm that the caller is permitted to
726 * read this particular data. Because one key
727 * pair is used per domain, the caller could
728 * have stolen the profile data on-disk and
729 * would otherwise be able to read the
730 * passwords.
733 werr = get_and_verify_access_check(mem_ctx, 3,
734 uncrypted_secretv3.payload_key,
735 uncrypt_request.access_check,
736 uncrypt_request.access_check_len,
737 dce_call->conn->auth_state.session_info);
738 if (!W_ERROR_IS_OK(werr)) {
739 return werr;
742 uncrypted = talloc(mem_ctx, DATA_BLOB);
743 if (uncrypted == NULL) {
744 return WERR_INVALID_DATA;
747 uncrypted->data = uncrypted_secretv3.secret;
748 uncrypted->length = uncrypted_secretv3.secret_len;
752 * Yeah if we are here all looks pretty good:
753 * - hash is ok
754 * - user sid is the same as the one in access check
755 * - we were able to decrypt the whole stuff
759 if (uncrypted->data == NULL) {
760 return WERR_INVALID_DATA;
763 /* There is a magic value a the beginning of the data
764 * we can use an adhoc structure but as the
765 * parent structure is just an array of bytes it a lot of work
766 * work just prepending 4 bytes
768 *(r->out.data_out) = talloc_zero_array(mem_ctx, uint8_t, uncrypted->length + 4);
769 W_ERROR_HAVE_NO_MEMORY(*(r->out.data_out));
770 memcpy(4+*(r->out.data_out), uncrypted->data, uncrypted->length);
771 *(r->out.data_out_len) = uncrypted->length + 4;
773 return WERR_OK;
776 static WERROR create_heimdal_rsa_key(TALLOC_CTX *ctx, hx509_context *hctx,
777 hx509_private_key *pk, RSA **_rsa)
779 BIGNUM *pub_expo;
780 RSA *rsa;
781 int ret;
782 uint8_t *p0, *p;
783 size_t len;
784 int bits = 2048;
785 int RSA_returned_bits;
787 *_rsa = NULL;
789 pub_expo = BN_new();
790 if(pub_expo == NULL) {
791 return WERR_INTERNAL_ERROR;
794 /* set the public expo to 65537 like everyone */
795 BN_set_word(pub_expo, 0x10001);
797 rsa = RSA_new();
798 if(rsa == NULL) {
799 BN_free(pub_expo);
800 return WERR_INTERNAL_ERROR;
803 while (RSA_returned_bits != bits) {
804 ret = RSA_generate_key_ex(rsa, bits, pub_expo, NULL);
805 if(ret != 1) {
806 RSA_free(rsa);
807 BN_free(pub_expo);
808 return WERR_INTERNAL_ERROR;
810 RSA_returned_bits = BN_num_bits(rsa->n);
811 DEBUG(6, ("RSA_generate_key_ex returned %d Bits\n", RSA_returned_bits));
813 BN_free(pub_expo);
815 len = i2d_RSAPrivateKey(rsa, NULL);
816 if (len < 1) {
817 RSA_free(rsa);
818 return WERR_INTERNAL_ERROR;
821 p0 = p = talloc_array(ctx, uint8_t, len);
822 if (p == NULL) {
823 RSA_free(rsa);
824 return WERR_INTERNAL_ERROR;
827 len = i2d_RSAPrivateKey(rsa, &p);
828 if (len < 1) {
829 RSA_free(rsa);
830 talloc_free(p0);
831 return WERR_INTERNAL_ERROR;
835 * To dump the key we can use :
836 * rk_dumpdata("h5lkey", p0, len);
838 ret = hx509_parse_private_key(*hctx, &_hx509_signature_rsa_with_var_num ,
839 p0, len, HX509_KEY_FORMAT_DER, pk);
840 memset(p0, 0, len);
841 talloc_free(p0);
842 if (ret !=0) {
843 RSA_free(rsa);
844 return WERR_INTERNAL_ERROR;
847 *_rsa = rsa;
848 return WERR_OK;
851 static WERROR self_sign_cert(TALLOC_CTX *ctx, hx509_context *hctx, hx509_request *req,
852 time_t lifetime, hx509_private_key *private_key,
853 hx509_cert *cert, DATA_BLOB *guidblob)
855 SubjectPublicKeyInfo spki;
856 hx509_name subject = NULL;
857 hx509_ca_tbs tbs;
858 struct heim_bit_string uniqueid;
859 struct heim_integer serialnumber;
860 int ret, i;
862 uniqueid.data = talloc_memdup(ctx, guidblob->data, guidblob->length);
863 if (uniqueid.data == NULL) {
864 return WERR_NOMEM;
866 /* uniqueid is a bit string in which each byte represent 1 bit (1 or 0)
867 * so as 1 byte is 8 bits we need to provision 8 times more space as in the
868 * blob
870 uniqueid.length = 8 * guidblob->length;
872 serialnumber.data = talloc_array(ctx, uint8_t,
873 guidblob->length);
874 if (serialnumber.data == NULL) {
875 talloc_free(uniqueid.data);
876 return WERR_NOMEM;
879 /* Native AD generates certificates with serialnumber in reversed notation */
880 for (i = 0; i < guidblob->length; i++) {
881 uint8_t *reversed = (uint8_t *)serialnumber.data;
882 uint8_t *uncrypt = guidblob->data;
883 reversed[i] = uncrypt[guidblob->length - 1 - i];
885 serialnumber.length = guidblob->length;
886 serialnumber.negative = 0;
888 memset(&spki, 0, sizeof(spki));
890 ret = hx509_request_get_name(*hctx, *req, &subject);
891 if (ret !=0) {
892 goto fail_subject;
894 ret = hx509_request_get_SubjectPublicKeyInfo(*hctx, *req, &spki);
895 if (ret !=0) {
896 goto fail_spki;
899 ret = hx509_ca_tbs_init(*hctx, &tbs);
900 if (ret !=0) {
901 goto fail_tbs;
904 ret = hx509_ca_tbs_set_spki(*hctx, tbs, &spki);
905 if (ret !=0) {
906 goto fail;
908 ret = hx509_ca_tbs_set_subject(*hctx, tbs, subject);
909 if (ret !=0) {
910 goto fail;
912 ret = hx509_ca_tbs_set_ca(*hctx, tbs, 1);
913 if (ret !=0) {
914 goto fail;
916 ret = hx509_ca_tbs_set_notAfter_lifetime(*hctx, tbs, lifetime);
917 if (ret !=0) {
918 goto fail;
920 ret = hx509_ca_tbs_set_unique(*hctx, tbs, &uniqueid, &uniqueid);
921 if (ret !=0) {
922 goto fail;
924 ret = hx509_ca_tbs_set_serialnumber(*hctx, tbs, &serialnumber);
925 if (ret !=0) {
926 goto fail;
928 ret = hx509_ca_sign_self(*hctx, tbs, *private_key, cert);
929 if (ret !=0) {
930 goto fail;
932 hx509_name_free(&subject);
933 free_SubjectPublicKeyInfo(&spki);
934 hx509_ca_tbs_free(&tbs);
936 return WERR_OK;
938 fail:
939 hx509_ca_tbs_free(&tbs);
940 fail_tbs:
941 free_SubjectPublicKeyInfo(&spki);
942 fail_spki:
943 hx509_name_free(&subject);
944 fail_subject:
945 talloc_free(uniqueid.data);
946 talloc_free(serialnumber.data);
947 return WERR_INTERNAL_ERROR;
950 static WERROR create_req(TALLOC_CTX *ctx, hx509_context *hctx, hx509_request *req,
951 hx509_private_key *signer,RSA **rsa, const char *dn)
953 int ret;
954 SubjectPublicKeyInfo key;
956 hx509_name name;
957 WERROR werr;
959 werr = create_heimdal_rsa_key(ctx, hctx, signer, rsa);
960 if (!W_ERROR_IS_OK(werr)) {
961 return werr;
964 hx509_request_init(*hctx, req);
965 ret = hx509_parse_name(*hctx, dn, &name);
966 if (ret != 0) {
967 RSA_free(*rsa);
968 hx509_private_key_free(signer);
969 hx509_request_free(req);
970 hx509_name_free(&name);
971 return WERR_INTERNAL_ERROR;
974 ret = hx509_request_set_name(*hctx, *req, name);
975 if (ret != 0) {
976 RSA_free(*rsa);
977 hx509_private_key_free(signer);
978 hx509_request_free(req);
979 hx509_name_free(&name);
980 return WERR_INTERNAL_ERROR;
982 hx509_name_free(&name);
984 ret = hx509_private_key2SPKI(*hctx, *signer, &key);
985 if (ret != 0) {
986 RSA_free(*rsa);
987 hx509_private_key_free(signer);
988 hx509_request_free(req);
989 return WERR_INTERNAL_ERROR;
991 ret = hx509_request_set_SubjectPublicKeyInfo(*hctx, *req, &key);
992 if (ret != 0) {
993 RSA_free(*rsa);
994 hx509_private_key_free(signer);
995 free_SubjectPublicKeyInfo(&key);
996 hx509_request_free(req);
997 return WERR_INTERNAL_ERROR;
1000 free_SubjectPublicKeyInfo(&key);
1002 return WERR_OK;
1005 /* Return an error when we fail to generate a certificate */
1006 static WERROR generate_bkrp_cert(TALLOC_CTX *ctx, struct dcesrv_call_state *dce_call, struct ldb_context *ldb_ctx, const char *dn)
1008 heim_octet_string data;
1009 WERROR werr;
1010 RSA *rsa;
1011 hx509_context hctx;
1012 hx509_private_key pk;
1013 hx509_request req;
1014 hx509_cert cert;
1015 DATA_BLOB blob;
1016 DATA_BLOB blobkeypair;
1017 DATA_BLOB *tmp;
1018 int ret;
1019 bool ok = true;
1020 struct GUID guid = GUID_random();
1021 NTSTATUS status;
1022 char *secret_name;
1023 struct bkrp_exported_RSA_key_pair keypair;
1024 enum ndr_err_code ndr_err;
1025 uint32_t nb_seconds_validity = 3600 * 24 * 365;
1027 DEBUG(6, ("Trying to generate a certificate\n"));
1028 hx509_context_init(&hctx);
1029 werr = create_req(ctx, &hctx, &req, &pk, &rsa, dn);
1030 if (!W_ERROR_IS_OK(werr)) {
1031 hx509_context_free(&hctx);
1032 return werr;
1035 status = GUID_to_ndr_blob(&guid, ctx, &blob);
1036 if (!NT_STATUS_IS_OK(status)) {
1037 hx509_context_free(&hctx);
1038 hx509_private_key_free(&pk);
1039 RSA_free(rsa);
1040 return WERR_INVALID_DATA;
1043 werr = self_sign_cert(ctx, &hctx, &req, nb_seconds_validity, &pk, &cert, &blob);
1044 if (!W_ERROR_IS_OK(werr)) {
1045 hx509_private_key_free(&pk);
1046 hx509_context_free(&hctx);
1047 return WERR_INVALID_DATA;
1050 ret = hx509_cert_binary(hctx, cert, &data);
1051 if (ret !=0) {
1052 hx509_cert_free(cert);
1053 hx509_private_key_free(&pk);
1054 hx509_context_free(&hctx);
1055 return WERR_INVALID_DATA;
1058 keypair.cert.data = talloc_memdup(ctx, data.data, data.length);
1059 keypair.cert.length = data.length;
1062 * Heimdal's bignum are big endian and the
1063 * structure expect it to be in little endian
1064 * so we reverse the buffer to make it work
1066 tmp = reverse_and_get_blob(ctx, rsa->e);
1067 if (tmp == NULL) {
1068 ok = false;
1069 } else {
1070 keypair.public_exponent = *tmp;
1071 SMB_ASSERT(tmp->length <= 4);
1073 * The value is now in little endian but if can happen that the length is
1074 * less than 4 bytes.
1075 * So if we have less than 4 bytes we pad with zeros so that it correctly
1076 * fit into the structure.
1078 if (tmp->length < 4) {
1080 * We need the expo to fit 4 bytes
1082 keypair.public_exponent.data = talloc_zero_array(ctx, uint8_t, 4);
1083 memcpy(keypair.public_exponent.data, tmp->data, tmp->length);
1084 keypair.public_exponent.length = 4;
1088 tmp = reverse_and_get_blob(ctx,rsa->d);
1089 if (tmp == NULL) {
1090 ok = false;
1091 } else {
1092 keypair.private_exponent = *tmp;
1095 tmp = reverse_and_get_blob(ctx,rsa->n);
1096 if (tmp == NULL) {
1097 ok = false;
1098 } else {
1099 keypair.modulus = *tmp;
1102 tmp = reverse_and_get_blob(ctx,rsa->p);
1103 if (tmp == NULL) {
1104 ok = false;
1105 } else {
1106 keypair.prime1 = *tmp;
1109 tmp = reverse_and_get_blob(ctx,rsa->q);
1110 if (tmp == NULL) {
1111 ok = false;
1112 } else {
1113 keypair.prime2 = *tmp;
1116 tmp = reverse_and_get_blob(ctx,rsa->dmp1);
1117 if (tmp == NULL) {
1118 ok = false;
1119 } else {
1120 keypair.exponent1 = *tmp;
1123 tmp = reverse_and_get_blob(ctx,rsa->dmq1);
1124 if (tmp == NULL) {
1125 ok = false;
1126 } else {
1127 keypair.exponent2 = *tmp;
1130 tmp = reverse_and_get_blob(ctx,rsa->iqmp);
1131 if (tmp == NULL) {
1132 ok = false;
1133 } else {
1134 keypair.coefficient = *tmp;
1137 /* One of the keypair allocation was wrong */
1138 if (ok == false) {
1139 der_free_octet_string(&data);
1140 hx509_cert_free(cert);
1141 hx509_private_key_free(&pk);
1142 hx509_context_free(&hctx);
1143 RSA_free(rsa);
1144 return WERR_INVALID_DATA;
1146 keypair.certificate_len = keypair.cert.length;
1147 ndr_err = ndr_push_struct_blob(&blobkeypair, ctx, &keypair, (ndr_push_flags_fn_t)ndr_push_bkrp_exported_RSA_key_pair);
1148 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1149 der_free_octet_string(&data);
1150 hx509_cert_free(cert);
1151 hx509_private_key_free(&pk);
1152 hx509_context_free(&hctx);
1153 RSA_free(rsa);
1154 return WERR_INVALID_DATA;
1157 secret_name = talloc_asprintf(ctx, "BCKUPKEY_%s", GUID_string(ctx, &guid));
1158 if (secret_name == NULL) {
1159 der_free_octet_string(&data);
1160 hx509_cert_free(cert);
1161 hx509_private_key_free(&pk);
1162 hx509_context_free(&hctx);
1163 RSA_free(rsa);
1164 return WERR_OUTOFMEMORY;
1167 status = set_lsa_secret(ctx, ldb_ctx, secret_name, &blobkeypair);
1168 if (!NT_STATUS_IS_OK(status)) {
1169 DEBUG(2, ("Failed to save the secret %s\n", secret_name));
1171 talloc_free(secret_name);
1173 GUID_to_ndr_blob(&guid, ctx, &blob);
1174 status = set_lsa_secret(ctx, ldb_ctx, "BCKUPKEY_PREFERRED", &blob);
1175 if (!NT_STATUS_IS_OK(status)) {
1176 DEBUG(2, ("Failed to save the secret BCKUPKEY_PREFERRED\n"));
1179 der_free_octet_string(&data);
1180 hx509_cert_free(cert);
1181 hx509_private_key_free(&pk);
1182 hx509_context_free(&hctx);
1183 RSA_free(rsa);
1184 return WERR_OK;
1187 static WERROR bkrp_retrieve_client_wrap_key(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1188 struct bkrp_BackupKey *r, struct ldb_context *ldb_ctx)
1190 struct GUID guid;
1191 char *guid_string;
1192 DATA_BLOB secret;
1193 enum ndr_err_code ndr_err;
1194 NTSTATUS status;
1197 * here we basicaly need to return our certificate
1198 * search for lsa secret BCKUPKEY_PREFERRED first
1201 status = get_lsa_secret(mem_ctx,
1202 ldb_ctx,
1203 "BCKUPKEY_PREFERRED",
1204 &secret);
1205 if (!NT_STATUS_IS_OK(status)) {
1206 DEBUG(10, ("Error while fetching secret BCKUPKEY_PREFERRED\n"));
1207 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1208 /* Ok we can be in this case if there was no certs */
1209 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
1210 char *dn = talloc_asprintf(mem_ctx, "CN=%s",
1211 lpcfg_realm(lp_ctx));
1213 WERROR werr = generate_bkrp_cert(mem_ctx, dce_call, ldb_ctx, dn);
1214 if (!W_ERROR_IS_OK(werr)) {
1215 return WERR_INVALID_PARAMETER;
1217 status = get_lsa_secret(mem_ctx,
1218 ldb_ctx,
1219 "BCKUPKEY_PREFERRED",
1220 &secret);
1222 if (!NT_STATUS_IS_OK(status)) {
1223 /* Ok we really don't manage to get this certs ...*/
1224 DEBUG(2, ("Unable to locate BCKUPKEY_PREFERRED after cert generation\n"));
1225 return WERR_FILE_NOT_FOUND;
1227 } else {
1228 /* In theory we should NEVER reach this point as it
1229 should only appear in a rodc server */
1230 /* we do not have the real secret attribute */
1231 return WERR_INVALID_PARAMETER;
1235 if (secret.length != 0) {
1236 char *cert_secret_name;
1238 status = GUID_from_ndr_blob(&secret, &guid);
1239 if (!NT_STATUS_IS_OK(status)) {
1240 return WERR_FILE_NOT_FOUND;
1243 guid_string = GUID_string(mem_ctx, &guid);
1244 if (guid_string == NULL) {
1245 /* We return file not found because the client
1246 * expect this error
1248 return WERR_FILE_NOT_FOUND;
1251 cert_secret_name = talloc_asprintf(mem_ctx,
1252 "BCKUPKEY_%s",
1253 guid_string);
1254 status = get_lsa_secret(mem_ctx,
1255 ldb_ctx,
1256 cert_secret_name,
1257 &secret);
1258 if (!NT_STATUS_IS_OK(status)) {
1259 return WERR_FILE_NOT_FOUND;
1262 if (secret.length != 0) {
1263 struct bkrp_exported_RSA_key_pair keypair;
1264 ndr_err = ndr_pull_struct_blob(&secret, mem_ctx, &keypair,
1265 (ndr_pull_flags_fn_t)ndr_pull_bkrp_exported_RSA_key_pair);
1266 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1267 return WERR_FILE_NOT_FOUND;
1269 *(r->out.data_out_len) = keypair.cert.length;
1270 *(r->out.data_out) = talloc_memdup(mem_ctx, keypair.cert.data, keypair.cert.length);
1271 W_ERROR_HAVE_NO_MEMORY(*(r->out.data_out));
1272 return WERR_OK;
1273 } else {
1274 DEBUG(10, ("No or broken secret called %s\n", cert_secret_name));
1275 return WERR_FILE_NOT_FOUND;
1277 } else {
1278 DEBUG(10, ("No secret BCKUPKEY_PREFERRED\n"));
1279 return WERR_FILE_NOT_FOUND;
1282 return WERR_NOT_SUPPORTED;
1285 static WERROR bkrp_do_uncrypt_server_wrap_key(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1286 struct bkrp_BackupKey *r ,struct ldb_context *ldb_ctx)
1288 return WERR_NOT_SUPPORTED;
1291 static WERROR bkrp_do_retrieve_server_wrap_key(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1292 struct bkrp_BackupKey *r ,struct ldb_context *ldb_ctx)
1294 return WERR_NOT_SUPPORTED;
1297 static WERROR dcesrv_bkrp_BackupKey(struct dcesrv_call_state *dce_call,
1298 TALLOC_CTX *mem_ctx, struct bkrp_BackupKey *r)
1300 WERROR error = WERR_INVALID_PARAM;
1301 struct ldb_context *ldb_ctx;
1302 bool is_rodc;
1303 const char *addr = "unknown";
1304 /* At which level we start to add more debug of what is done in the protocol */
1305 const int debuglevel = 4;
1307 if (DEBUGLVL(debuglevel)) {
1308 const struct tsocket_address *remote_address;
1309 remote_address = dcesrv_connection_get_remote_address(dce_call->conn);
1310 if (tsocket_address_is_inet(remote_address, "ip")) {
1311 addr = tsocket_address_inet_addr_string(remote_address, mem_ctx);
1312 W_ERROR_HAVE_NO_MEMORY(addr);
1316 if (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx) != ROLE_ACTIVE_DIRECTORY_DC) {
1317 return WERR_NOT_SUPPORTED;
1320 if (!dce_call->conn->auth_state.auth_info ||
1321 dce_call->conn->auth_state.auth_info->auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
1322 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
1325 ldb_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
1326 dce_call->conn->dce_ctx->lp_ctx,
1327 system_session(dce_call->conn->dce_ctx->lp_ctx), 0);
1329 if (samdb_rodc(ldb_ctx, &is_rodc) != LDB_SUCCESS) {
1330 talloc_unlink(mem_ctx, ldb_ctx);
1331 return WERR_INVALID_PARAM;
1334 if (!is_rodc) {
1335 if(strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent),
1336 BACKUPKEY_RESTORE_GUID, strlen(BACKUPKEY_RESTORE_GUID)) == 0) {
1337 DEBUG(debuglevel, ("Client %s requested to decrypt a client side wrapped secret\n", addr));
1338 error = bkrp_client_wrap_decrypt_data(dce_call, mem_ctx, r, ldb_ctx);
1341 if (strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent),
1342 BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID, strlen(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID)) == 0) {
1343 DEBUG(debuglevel, ("Client %s requested certificate for client wrapped secret\n", addr));
1344 error = bkrp_retrieve_client_wrap_key(dce_call, mem_ctx, r, ldb_ctx);
1347 if (strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent),
1348 BACKUPKEY_RESTORE_GUID_WIN2K, strlen(BACKUPKEY_RESTORE_GUID_WIN2K)) == 0) {
1349 DEBUG(debuglevel, ("Client %s requested to decrypt a server side wrapped secret, not implemented yet\n", addr));
1350 error = bkrp_do_uncrypt_server_wrap_key(dce_call, mem_ctx, r, ldb_ctx);
1353 if (strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent),
1354 BACKUPKEY_BACKUP_GUID, strlen(BACKUPKEY_BACKUP_GUID)) == 0) {
1355 DEBUG(debuglevel, ("Client %s requested a server wrapped secret, not implemented yet\n", addr));
1356 error = bkrp_do_retrieve_server_wrap_key(dce_call, mem_ctx, r, ldb_ctx);
1359 /*else: I am a RODC so I don't handle backup key protocol */
1361 talloc_unlink(mem_ctx, ldb_ctx);
1362 return error;
1365 /* include the generated boilerplate */
1366 #include "librpc/gen_ndr/ndr_backupkey_s.c"