s4-lib: Remove unused samdb_msg_set_int()
[Samba/bjacke.git] / source4 / torture / rpc / backupkey.c
blob442df14295459f378100e953541a34cd8f82882e
1 /*
2 Unix SMB/CIFS implementation.
3 test suite for backupkey remote protocol rpc operations
5 Copyright (C) Matthieu Patou 2010-2011
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "../libcli/security/security.h"
23 #include "librpc/gen_ndr/ndr_backupkey_c.h"
24 #include "librpc/gen_ndr/ndr_backupkey.h"
25 #include "librpc/gen_ndr/ndr_lsa_c.h"
26 #include "torture/rpc/torture_rpc.h"
27 #include "lib/cmdline/popt_common.h"
28 #include <com_err.h>
29 #include <hcrypto/sha.h>
30 #include <system/network.h>
31 #include <hx509.h>
32 #include <der.h>
35 /* Our very special and valued secret */
36 /* No need to put const as we cast the array in uint8_t
37 * we will get a warning about the discared const
39 static const char secret[] = "tata yoyo mais qu'est ce qu'il y a sous ton grand chapeau ?";
41 /* Get the SID from a user */
42 static const struct dom_sid *get_user_sid(struct torture_context *tctx,
43 struct dcerpc_pipe *p,
44 TALLOC_CTX *mem_ctx,
45 const char *user)
47 struct lsa_ObjectAttribute attr;
48 struct lsa_QosInfo qos;
49 struct lsa_OpenPolicy2 r;
50 struct lsa_Close c;
51 NTSTATUS status;
52 struct policy_handle handle;
53 struct lsa_LookupNames l;
54 struct lsa_TransSidArray sids;
55 struct lsa_RefDomainList *domains = NULL;
56 struct lsa_String lsa_name;
57 uint32_t count = 0;
58 struct dom_sid *result;
59 TALLOC_CTX *tmp_ctx;
60 struct dcerpc_pipe *p2;
61 struct dcerpc_binding_handle *b;
63 const char *domain = cli_credentials_get_domain(cmdline_credentials);
65 torture_assert_ntstatus_ok(tctx,
66 torture_rpc_connection(tctx, &p2, &ndr_table_lsarpc),
67 "could not open lsarpc pipe");
68 b = p2->binding_handle;
70 if (!(tmp_ctx = talloc_new(mem_ctx))) {
71 return NULL;
73 qos.len = 0;
74 qos.impersonation_level = 2;
75 qos.context_mode = 1;
76 qos.effective_only = 0;
78 attr.len = 0;
79 attr.root_dir = NULL;
80 attr.object_name = NULL;
81 attr.attributes = 0;
82 attr.sec_desc = NULL;
83 attr.sec_qos = &qos;
85 r.in.system_name = "\\";
86 r.in.attr = &attr;
87 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
88 r.out.handle = &handle;
90 status = dcerpc_lsa_OpenPolicy2_r(b, tmp_ctx, &r);
91 if (!NT_STATUS_IS_OK(status)) {
92 torture_comment(tctx,
93 "OpenPolicy2 failed - %s\n",
94 nt_errstr(status));
95 talloc_free(tmp_ctx);
96 return NULL;
98 if (!NT_STATUS_IS_OK(r.out.result)) {
99 torture_comment(tctx,
100 "OpenPolicy2_ failed - %s\n",
101 nt_errstr(r.out.result));
102 talloc_free(tmp_ctx);
103 return NULL;
106 sids.count = 0;
107 sids.sids = NULL;
109 lsa_name.string = talloc_asprintf(tmp_ctx, "%s\\%s", domain, user);
111 l.in.handle = &handle;
112 l.in.num_names = 1;
113 l.in.names = &lsa_name;
114 l.in.sids = &sids;
115 l.in.level = 1;
116 l.in.count = &count;
117 l.out.count = &count;
118 l.out.sids = &sids;
119 l.out.domains = &domains;
121 status = dcerpc_lsa_LookupNames_r(b, tmp_ctx, &l);
122 if (!NT_STATUS_IS_OK(status)) {
123 torture_comment(tctx,
124 "LookupNames of %s failed - %s\n",
125 lsa_name.string,
126 nt_errstr(status));
127 talloc_free(tmp_ctx);
128 return NULL;
131 if (domains->count == 0) {
132 return NULL;
135 result = dom_sid_add_rid(mem_ctx,
136 domains->domains[0].sid,
137 l.out.sids->sids[0].rid);
138 c.in.handle = &handle;
139 c.out.handle = &handle;
141 status = dcerpc_lsa_Close_r(b, tmp_ctx, &c);
143 if (!NT_STATUS_IS_OK(status)) {
144 torture_comment(tctx,
145 "dcerpc_lsa_Close failed - %s\n",
146 nt_errstr(status));
147 talloc_free(tmp_ctx);
148 return NULL;
151 if (!NT_STATUS_IS_OK(c.out.result)) {
152 torture_comment(tctx,
153 "dcerpc_lsa_Close failed - %s\n",
154 nt_errstr(c.out.result));
155 talloc_free(tmp_ctx);
156 return NULL;
159 talloc_free(tmp_ctx);
160 talloc_free(p2);
162 torture_comment(tctx, "Get_user_sid finished\n");
163 return result;
167 * Create a bkrp_encrypted_secret_vX structure
168 * the version depends on the version parameter
169 * the structure is returned as a blob.
170 * The broken flag is to indicate if we want
171 * to create a non conform to specification structre
173 static DATA_BLOB *create_unencryptedsecret(TALLOC_CTX *mem_ctx,
174 bool broken,
175 int version)
177 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
178 DATA_BLOB *blob = talloc_zero(mem_ctx, DATA_BLOB);
179 enum ndr_err_code ndr_err;
181 if (version == 2) {
182 struct bkrp_encrypted_secret_v2 unenc_sec;
184 ZERO_STRUCT(unenc_sec);
185 unenc_sec.secret_len = sizeof(secret);
186 unenc_sec.secret = discard_const_p(uint8_t, secret);
187 generate_random_buffer(unenc_sec.payload_key,
188 sizeof(unenc_sec.payload_key));
190 ndr_err = ndr_push_struct_blob(blob, blob, &unenc_sec,
191 (ndr_push_flags_fn_t)ndr_push_bkrp_encrypted_secret_v2);
192 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
193 return NULL;
196 if (broken) {
197 /* The magic value is correctly set by the NDR push
198 * but we want to test the behavior of the server
199 * if a differrent value is provided
201 ((uint8_t*)blob->data)[4] = 79; /* A great year !!! */
205 if (version == 3) {
206 struct bkrp_encrypted_secret_v3 unenc_sec;
208 ZERO_STRUCT(unenc_sec);
209 unenc_sec.secret_len = sizeof(secret);
210 unenc_sec.secret = discard_const_p(uint8_t, secret);
211 generate_random_buffer(unenc_sec.payload_key,
212 sizeof(unenc_sec.payload_key));
214 ndr_err = ndr_push_struct_blob(blob, blob, &unenc_sec,
215 (ndr_push_flags_fn_t)ndr_push_bkrp_encrypted_secret_v3);
216 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
217 return NULL;
220 if (broken) {
222 * The magic value is correctly set by the NDR push
223 * but we want to test the behavior of the server
224 * if a differrent value is provided
226 ((uint8_t*)blob->data)[4] = 79; /* A great year !!! */
229 talloc_free(tmp_ctx);
230 return blob;
234 * Create an access check structure, the format depends on the version parameter.
235 * If broken is specified then we create a stucture that isn't conform to the
236 * specification.
238 * If the structure can't be created then NULL is returned.
240 static DATA_BLOB *create_access_check(struct torture_context *tctx,
241 struct dcerpc_pipe *p,
242 TALLOC_CTX *mem_ctx,
243 const char *user,
244 bool broken,
245 uint32_t version)
247 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
248 DATA_BLOB *blob = talloc_zero(mem_ctx, DATA_BLOB);
249 enum ndr_err_code ndr_err;
250 const struct dom_sid *sid = get_user_sid(tctx, p, tmp_ctx, user);
252 if (sid == NULL) {
253 return NULL;
256 if (version == 2) {
257 struct bkrp_access_check_v2 access_struct;
258 struct sha sctx;
259 uint8_t nonce[32];
261 ZERO_STRUCT(access_struct);
262 generate_random_buffer(nonce, sizeof(nonce));
263 access_struct.nonce_len = sizeof(nonce);
264 access_struct.nonce = nonce;
265 access_struct.sid = *sid;
267 ndr_err = ndr_push_struct_blob(blob, blob, &access_struct,
268 (ndr_push_flags_fn_t)ndr_push_bkrp_access_check_v2);
269 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
270 return NULL;
274 * We pushed the whole structure including a null hash
275 * but the hash need to be calculated only up to the hash field
276 * so we reduce the size of what has to be calculated
279 SHA1_Init(&sctx);
280 SHA1_Update(&sctx, blob->data,
281 blob->length - sizeof(access_struct.hash));
282 SHA1_Final(blob->data + blob->length - sizeof(access_struct.hash),
283 &sctx);
285 /* Altering the SHA */
286 if (broken) {
287 blob->data[blob->length - 1]++;
291 if (version == 3) {
292 struct bkrp_access_check_v3 access_struct;
293 struct hc_sha512state sctx;
294 uint8_t nonce[32];
296 ZERO_STRUCT(access_struct);
297 generate_random_buffer(nonce, sizeof(nonce));
298 access_struct.nonce_len = sizeof(nonce);
299 access_struct.nonce = nonce;
300 access_struct.sid = *sid;
302 ndr_err = ndr_push_struct_blob(blob, blob, &access_struct,
303 (ndr_push_flags_fn_t)ndr_push_bkrp_access_check_v3);
304 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
305 return NULL;
308 /*We pushed the whole structure including a null hash
309 * but the hash need to be calculated only up to the hash field
310 * so we reduce the size of what has to be calculated
313 SHA512_Init(&sctx);
314 SHA512_Update(&sctx, blob->data,
315 blob->length - sizeof(access_struct.hash));
316 SHA512_Final(blob->data + blob->length - sizeof(access_struct.hash),
317 &sctx);
319 /* Altering the SHA */
320 if (broken) {
321 blob->data[blob->length -1]++;
324 talloc_free(tmp_ctx);
325 return blob;
329 static DATA_BLOB *encrypt_blob(struct torture_context *tctx,
330 TALLOC_CTX *mem_ctx,
331 DATA_BLOB *key,
332 DATA_BLOB *iv,
333 DATA_BLOB *to_encrypt,
334 const AlgorithmIdentifier *alg)
336 hx509_crypto crypto;
337 hx509_context hctx;
338 heim_octet_string ivos;
339 heim_octet_string *encrypted;
340 DATA_BLOB *blob = talloc_zero(mem_ctx, DATA_BLOB);
341 int res;
343 ivos.data = talloc_array(mem_ctx, uint8_t, iv->length);
344 ivos.length = iv->length;
345 memcpy(ivos.data, iv->data, iv->length);
347 hx509_context_init(&hctx);
348 res = hx509_crypto_init(hctx, NULL, &alg->algorithm, &crypto);
349 if (res) {
350 torture_comment(tctx,
351 "error while doing the init of the crypto object\n");
352 hx509_context_free(&hctx);
353 return NULL;
355 res = hx509_crypto_set_key_data(crypto, key->data, key->length);
356 if (res) {
357 torture_comment(tctx,
358 "error while setting the key of the crypto object\n");
359 hx509_context_free(&hctx);
360 return NULL;
363 hx509_crypto_set_padding(crypto, HX509_CRYPTO_PADDING_NONE);
364 res = hx509_crypto_encrypt(crypto,
365 to_encrypt->data,
366 to_encrypt->length,
367 &ivos,
368 &encrypted);
369 if (res) {
370 torture_comment(tctx, "error while encrypting\n");
371 hx509_crypto_destroy(crypto);
372 hx509_context_free(&hctx);
373 return NULL;
376 *blob = data_blob_talloc(blob, encrypted->data, encrypted->length);
377 der_free_octet_string(encrypted);
378 free(encrypted);
379 hx509_crypto_destroy(crypto);
380 hx509_context_free(&hctx);
381 return blob;
385 * Certs used for this protocol have a GUID in the issuer_uniq_id field.
386 * This function fetch it.
388 static struct GUID *get_cert_guid(struct torture_context *tctx,
389 TALLOC_CTX *mem_ctx,
390 uint8_t *cert_data,
391 uint32_t cert_len)
393 hx509_context hctx;
394 hx509_cert cert;
395 heim_bit_string subjectuniqid;
396 DATA_BLOB data;
397 int hret;
398 uint32_t size;
399 struct GUID *guid = talloc_zero(mem_ctx, struct GUID);
400 NTSTATUS status;
402 hx509_context_init(&hctx);
404 hret = hx509_cert_init_data(hctx, cert_data, cert_len, &cert);
405 if (hret) {
406 torture_comment(tctx, "error while loading the cert\n");
407 hx509_context_free(&hctx);
408 return NULL;
410 hret = hx509_cert_get_issuer_unique_id(hctx, cert, &subjectuniqid);
411 if (hret) {
412 torture_comment(tctx, "error while getting the issuer_uniq_id\n");
413 hx509_cert_free(cert);
414 hx509_context_free(&hctx);
415 return NULL;
418 /* The subjectuniqid is a bit string,
419 * which means that the real size has to be divided by 8
420 * to have the number of bytes
422 hx509_cert_free(cert);
423 hx509_context_free(&hctx);
424 size = subjectuniqid.length / 8;
425 data = data_blob_const(subjectuniqid.data, size);
427 status = GUID_from_data_blob(&data, guid);
428 der_free_bit_string(&subjectuniqid);
429 if (!NT_STATUS_IS_OK(status)) {
430 return NULL;
433 return guid;
437 * Encrypt a blob with the private key of the certificate
438 * passed as a parameter.
440 static DATA_BLOB *encrypt_blob_pk(struct torture_context *tctx,
441 TALLOC_CTX *mem_ctx,
442 uint8_t *cert_data,
443 uint32_t cert_len,
444 DATA_BLOB *to_encrypt)
446 hx509_context hctx;
447 hx509_cert cert;
448 heim_octet_string secretdata;
449 heim_octet_string encrypted;
450 heim_oid encryption_oid;
451 DATA_BLOB *blob;
452 int hret;
454 hx509_context_init(&hctx);
456 hret = hx509_cert_init_data(hctx, cert_data, cert_len, &cert);
457 if (hret) {
458 torture_comment(tctx, "error while loading the cert\n");
459 hx509_context_free(&hctx);
460 return NULL;
463 secretdata.data = to_encrypt->data;
464 secretdata.length = to_encrypt->length;
465 hret = hx509_cert_public_encrypt(hctx, &secretdata,
466 cert, &encryption_oid,
467 &encrypted);
468 hx509_cert_free(cert);
469 hx509_context_free(&hctx);
470 if (hret) {
471 torture_comment(tctx, "error while encrypting\n");
472 return NULL;
475 blob = talloc_zero(mem_ctx, DATA_BLOB);
476 if (blob == NULL) {
477 der_free_oid(&encryption_oid);
478 der_free_octet_string(&encrypted);
479 return NULL;
482 *blob = data_blob_talloc(blob, encrypted.data, encrypted.length);
483 der_free_octet_string(&encrypted);
484 der_free_oid(&encryption_oid);
485 if (blob->data == NULL) {
486 return NULL;
489 return blob;
493 static struct bkrp_BackupKey *createRetreiveBackupKeyGUIDStruct(struct torture_context *tctx,
494 struct dcerpc_pipe *p, int version, DATA_BLOB *out)
496 struct dcerpc_binding *binding = p->binding;
497 struct bkrp_client_side_wrapped data;
498 struct GUID *g = talloc(tctx, struct GUID);
499 struct bkrp_BackupKey *r = talloc_zero(tctx, struct bkrp_BackupKey);
500 enum ndr_err_code ndr_err;
501 DATA_BLOB blob;
502 NTSTATUS status;
504 if (r == NULL) {
505 return NULL;
508 binding->flags = binding->flags & (DCERPC_SEAL|DCERPC_AUTH_SPNEGO);
509 ZERO_STRUCT(data);
510 status = GUID_from_string(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID, g);
511 if (!NT_STATUS_IS_OK(status)) {
512 return NULL;
515 r->in.guidActionAgent = g;
516 data.version = version;
517 ndr_err = ndr_push_struct_blob(&blob, tctx, &data,
518 (ndr_push_flags_fn_t)ndr_push_bkrp_client_side_wrapped);
519 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
520 return NULL;
522 r->in.data_in = blob.data;
523 r->in.data_in_len = blob.length;
524 r->out.data_out = &out->data;
525 r->out.data_out_len = talloc(r, uint32_t);
526 return r;
529 static struct bkrp_BackupKey *createRestoreGUIDStruct(struct torture_context *tctx,
530 struct dcerpc_pipe *p, int version, DATA_BLOB *out,
531 bool norevert,
532 bool broken_version,
533 bool broken_user,
534 bool broken_magic_secret,
535 bool broken_magic_access,
536 bool broken_hash_access,
537 bool broken_cert_guid)
539 struct dcerpc_binding_handle *b = p->binding_handle;
540 struct bkrp_client_side_wrapped data;
541 DATA_BLOB *xs;
542 DATA_BLOB *sec;
543 DATA_BLOB *enc_sec;
544 DATA_BLOB *enc_xs;
545 DATA_BLOB *blob2;
546 DATA_BLOB enc_sec_reverted;
547 DATA_BLOB des3_key;
548 DATA_BLOB aes_key;
549 DATA_BLOB iv;
550 DATA_BLOB out_blob;
551 struct GUID *guid, *g;
552 int t;
553 uint32_t size;
554 enum ndr_err_code ndr_err;
555 NTSTATUS status;
556 const char *user;
557 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(tctx, p, version, &out_blob);
558 if (r == NULL) {
559 return NULL;
562 if (broken_user) {
563 /* we take a fake user*/
564 user = "guest";
565 } else {
566 user = cli_credentials_get_username(cmdline_credentials);
570 torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
571 "Get GUID");
573 * We have to set it outside of the function createRetreiveBackupKeyGUIDStruct
574 * the len of the blob, this is due to the fact that they don't have the
575 * same size (one is 32bits the other 64bits)
577 out_blob.length = *r->out.data_out_len;
579 sec = create_unencryptedsecret(tctx, broken_magic_secret, version);
580 if (sec == NULL) {
581 return NULL;
584 xs = create_access_check(tctx, p, tctx, user, broken_hash_access, version);
585 if (xs == NULL) {
586 return NULL;
589 if (broken_magic_access){
590 /* The start of the access_check structure contains the
591 * GUID of the certificate
593 xs->data[0]++;
596 enc_sec = encrypt_blob_pk(tctx, tctx, out_blob.data, out_blob.length, sec);
597 if (!enc_sec) {
598 return NULL;
600 enc_sec_reverted.data = talloc_array(tctx, uint8_t, enc_sec->length);
601 if (enc_sec_reverted.data == NULL) {
602 return NULL;
604 enc_sec_reverted.length = enc_sec->length;
607 * We DO NOT revert the array on purpose it's in order to check that
608 * when the server is not able to decrypt then it answer the correct error
610 if (norevert) {
611 for(t=0; t< enc_sec->length; t++) {
612 enc_sec_reverted.data[t] = ((uint8_t*)enc_sec->data)[t];
614 } else {
615 for(t=0; t< enc_sec->length; t++) {
616 enc_sec_reverted.data[t] = ((uint8_t*)enc_sec->data)[enc_sec->length - t -1];
620 size = sec->length;
621 if (version ==2) {
622 const AlgorithmIdentifier *alg = hx509_crypto_des_rsdi_ede3_cbc();
623 iv.data = sec->data+(size - 8);
624 iv.length = 8;
626 des3_key.data = sec->data+(size - 32);
627 des3_key.length = 24;
629 enc_xs = encrypt_blob(tctx, tctx, &des3_key, &iv, xs, alg);
631 if (version == 3) {
632 const AlgorithmIdentifier *alg = hx509_crypto_aes256_cbc();
633 iv.data = sec->data+(size-16);
634 iv.length = 16;
636 aes_key.data = sec->data+(size-48);
637 aes_key.length = 32;
639 enc_xs = encrypt_blob(tctx, tctx, &aes_key, &iv, xs, alg);
642 if (!enc_xs) {
643 return NULL;
646 /* To cope with the fact that heimdal do padding at the end for the moment */
647 enc_xs->length = xs->length;
649 guid = get_cert_guid(tctx, tctx, out_blob.data, out_blob.length);
650 if (guid == NULL) {
651 return NULL;
654 if (broken_version) {
655 data.version = 1;
656 } else {
657 data.version = version;
660 data.guid = *guid;
661 data.encrypted_secret = enc_sec_reverted.data;
662 data.access_check = enc_xs->data;
663 data.encrypted_secret_len = enc_sec->length;
664 data.access_check_len = enc_xs->length;
666 /* We want the blob to persist after this function so we don't
667 * allocate it in the stack
669 blob2 = talloc(tctx, DATA_BLOB);
670 if (blob2 == NULL) {
671 return NULL;
674 ndr_err = ndr_push_struct_blob(blob2, tctx, &data,
675 (ndr_push_flags_fn_t)ndr_push_bkrp_client_side_wrapped);
676 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
677 return NULL;
680 if (broken_cert_guid) {
681 blob2->data[12]++;
684 ZERO_STRUCT(*r);
686 g = talloc(tctx, struct GUID);
687 if (g == NULL) {
688 return NULL;
691 status = GUID_from_string(BACKUPKEY_RESTORE_GUID, g);
692 if (!NT_STATUS_IS_OK(status)) {
693 return NULL;
696 r->in.guidActionAgent = g;
697 r->in.data_in = blob2->data;
698 r->in.data_in_len = blob2->length;
699 r->in.param = 0;
700 r->out.data_out = &(out->data);
701 r->out.data_out_len = talloc(r, uint32_t);
702 return r;
705 /* Check that we are able to receive the certificate of the DCs
706 * used for client wrap version of the backup key protocol
708 static bool test_RetreiveBackupKeyGUID(struct torture_context *tctx,
709 struct dcerpc_pipe *p)
711 struct dcerpc_binding_handle *b = p->binding_handle;
712 DATA_BLOB out_blob;
713 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
715 if (r == NULL) {
716 return false;
719 if (p->conn->security_state.auth_info != NULL &&
720 p->conn->security_state.auth_info->auth_level == 6) {
721 torture_assert_ntstatus_ok(tctx,
722 dcerpc_bkrp_BackupKey_r(b, tctx, r),
723 "Get GUID");
725 out_blob.length = *r->out.data_out_len;
726 torture_assert_werr_equal(tctx,
727 r->out.result,
728 WERR_OK,
729 "Wrong dce/rpc error code");
730 } else {
731 torture_assert_ntstatus_equal(tctx,
732 dcerpc_bkrp_BackupKey_r(b, tctx, r),
733 NT_STATUS_ACCESS_DENIED,
734 "Get GUID");
736 return true;
739 /* Test to check the failure to recover a secret because the
740 * secret blob is not reversed
742 static bool test_RestoreGUID_ko(struct torture_context *tctx,
743 struct dcerpc_pipe *p)
745 enum ndr_err_code ndr_err;
746 struct dcerpc_binding_handle *b = p->binding_handle;
747 DATA_BLOB out_blob;
748 struct bkrp_client_side_unwrapped resp;
750 if (p->conn->security_state.auth_info != NULL &&
751 p->conn->security_state.auth_info->auth_level == 6) {
752 struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob,
753 true, false, false, false, false, false, false);
754 torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
755 out_blob.length = *r->out.data_out_len;
756 ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
757 torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
758 torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_DATA, "Wrong error code");
759 } else {
760 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
761 torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
762 NT_STATUS_ACCESS_DENIED, "Get GUID");
764 return true;
767 static bool test_RestoreGUID_wrongversion(struct torture_context *tctx,
768 struct dcerpc_pipe *p)
770 enum ndr_err_code ndr_err;
771 struct dcerpc_binding_handle *b = p->binding_handle;
772 DATA_BLOB out_blob;
773 struct bkrp_client_side_unwrapped resp;
775 if (p->conn->security_state.auth_info != NULL &&
776 p->conn->security_state.auth_info->auth_level == 6) {
777 struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob,
778 false, true, false, false, false, false, false);
779 torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
780 out_blob.length = *r->out.data_out_len;
781 ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
782 torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
783 torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_PARAM, "Wrong error code on wrong version");
784 } else {
785 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
786 torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
787 NT_STATUS_ACCESS_DENIED, "Get GUID");
789 return true;
792 static bool test_RestoreGUID_wronguser(struct torture_context *tctx,
793 struct dcerpc_pipe *p)
795 enum ndr_err_code ndr_err;
796 struct dcerpc_binding_handle *b = p->binding_handle;
797 DATA_BLOB out_blob;
798 struct bkrp_client_side_unwrapped resp;
800 if (p->conn->security_state.auth_info != NULL &&
801 p->conn->security_state.auth_info->auth_level == 6) {
802 struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob,
803 false, false, true, false, false, false, false);
804 torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
805 out_blob.length = *r->out.data_out_len;
806 ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
807 torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
808 torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_ACCESS, "Restore GUID");
809 } else {
810 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
811 torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
812 NT_STATUS_ACCESS_DENIED, "Get GUID");
814 return true;
817 static bool test_RestoreGUID_v3(struct torture_context *tctx,
818 struct dcerpc_pipe *p)
820 enum ndr_err_code ndr_err;
821 struct dcerpc_binding_handle *b = p->binding_handle;
822 DATA_BLOB out_blob;
823 struct bkrp_client_side_unwrapped resp;
825 if (p->conn->security_state.auth_info != NULL &&
826 p->conn->security_state.auth_info->auth_level == 6) {
827 struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 3, &out_blob,
828 false, false, false, false, false, false, false);
829 torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
830 out_blob.length = *r->out.data_out_len;
831 ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
832 torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 1, "Unable to unmarshall bkrp_client_side_unwrapped");
833 torture_assert_werr_equal(tctx, r->out.result, WERR_OK, "Restore GUID");
834 torture_assert_str_equal(tctx, (char*)resp.secret.data, secret, "Wrong secret");
835 } else {
836 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
837 torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
838 NT_STATUS_ACCESS_DENIED, "Get GUID");
840 return true;
843 static bool test_RestoreGUID(struct torture_context *tctx,
844 struct dcerpc_pipe *p)
846 enum ndr_err_code ndr_err;
847 struct dcerpc_binding_handle *b = p->binding_handle;
848 DATA_BLOB out_blob;
849 struct bkrp_client_side_unwrapped resp;
851 if (p->conn->security_state.auth_info != NULL &&
852 p->conn->security_state.auth_info->auth_level == 6) {
853 struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob,
854 false, false, false, false, false, false, false);
855 torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
856 out_blob.length = *r->out.data_out_len;
857 ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
858 torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 1, "Unable to unmarshall bkrp_client_side_unwrapped");
859 torture_assert_werr_equal(tctx, r->out.result, WERR_OK, "Restore GUID");
860 torture_assert_str_equal(tctx, (char*)resp.secret.data, secret, "Wrong secret");
861 } else {
862 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
863 torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
864 NT_STATUS_ACCESS_DENIED, "Get GUID");
866 return true;
869 static bool test_RestoreGUID_badmagiconsecret(struct torture_context *tctx,
870 struct dcerpc_pipe *p)
872 enum ndr_err_code ndr_err;
873 struct dcerpc_binding_handle *b = p->binding_handle;
874 DATA_BLOB out_blob;
875 struct bkrp_client_side_unwrapped resp;
877 if (p->conn->security_state.auth_info != NULL &&
878 p->conn->security_state.auth_info->auth_level == 6) {
879 struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 3, &out_blob,
880 false, false, false, true, false, false, false);
881 torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
882 out_blob.length = *r->out.data_out_len;
883 ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
884 torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
885 torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_DATA, "Wrong error code while providing bad magic in secret");
886 } else {
887 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
888 torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
889 NT_STATUS_ACCESS_DENIED, "Get GUID");
891 return true;
894 static bool test_RestoreGUID_emptyrequest(struct torture_context *tctx,
895 struct dcerpc_pipe *p)
897 struct dcerpc_binding_handle *b = p->binding_handle;
898 DATA_BLOB out_blob;
900 if (p->conn->security_state.auth_info != NULL &&
901 p->conn->security_state.auth_info->auth_level == 6) {
902 struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 3, &out_blob,
903 false, false, false, true, false, false, true);
905 torture_assert_int_equal(tctx, r != NULL, 1, "Error while creating the restoreGUID struct");
906 r->in.data_in = talloc(tctx, uint8_t);
907 r->in.data_in_len = 0;
908 r->in.param = 0;
909 torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
910 out_blob.length = *r->out.data_out_len;
911 torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_PARAM, "Bad error code on wrong has in access check");
912 } else {
913 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
914 torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
915 NT_STATUS_ACCESS_DENIED, "Get GUID");
917 return true;
920 static bool test_RestoreGUID_badcertguid(struct torture_context *tctx,
921 struct dcerpc_pipe *p)
923 enum ndr_err_code ndr_err;
924 struct dcerpc_binding_handle *b = p->binding_handle;
925 DATA_BLOB out_blob;
926 struct bkrp_client_side_unwrapped resp;
928 if (p->conn->security_state.auth_info != NULL &&
929 p->conn->security_state.auth_info->auth_level == 6) {
930 struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 3, &out_blob,
931 false, false, false, false, false, false, true);
932 torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
933 out_blob.length = *r->out.data_out_len;
934 ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
935 torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
936 torture_assert_werr_equal(tctx, r->out.result, WERR_FILE_NOT_FOUND, "Bad error code on wrong has in access check");
937 } else {
938 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
939 torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
940 NT_STATUS_ACCESS_DENIED, "Get GUID");
942 return true;
945 static bool test_RestoreGUID_badmagicaccesscheck(struct torture_context *tctx,
946 struct dcerpc_pipe *p)
948 enum ndr_err_code ndr_err;
949 struct dcerpc_binding_handle *b = p->binding_handle;
950 DATA_BLOB out_blob;
951 struct bkrp_client_side_unwrapped resp;
953 if (p->conn->security_state.auth_info != NULL &&
954 p->conn->security_state.auth_info->auth_level == 6) {
955 struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob,
956 false, false, false, false, true, false, false);
957 torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
958 out_blob.length = *r->out.data_out_len;
959 ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
960 torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
961 torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_DATA, "Bad error code on wrong has in access check");
962 } else {
963 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
964 torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
965 NT_STATUS_ACCESS_DENIED, "Get GUID");
967 return true;
970 static bool test_RestoreGUID_badhashaccesscheck(struct torture_context *tctx,
971 struct dcerpc_pipe *p)
973 enum ndr_err_code ndr_err;
974 struct dcerpc_binding_handle *b = p->binding_handle;
975 DATA_BLOB out_blob;
976 struct bkrp_client_side_unwrapped resp;
978 if (p->conn->security_state.auth_info != NULL &&
979 p->conn->security_state.auth_info->auth_level == 6) {
980 struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob,
981 false, false, false, false, false, true, false);
982 torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
983 out_blob.length = *r->out.data_out_len;
984 ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
985 torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
986 torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_DATA, "Bad error code on wrong has in access check");
987 } else {
988 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
989 torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
990 NT_STATUS_ACCESS_DENIED, "Get GUID");
992 return true;
995 struct torture_suite *torture_rpc_backupkey(TALLOC_CTX *mem_ctx)
997 struct torture_rpc_tcase *tcase;
998 struct torture_suite *suite = torture_suite_create(mem_ctx, "backupkey");
999 struct torture_test *test;
1001 tcase = torture_suite_add_rpc_iface_tcase(suite, "backupkey",
1002 &ndr_table_backupkey);
1004 test = torture_rpc_tcase_add_test(tcase, "retreive_backup_key_guid",
1005 test_RetreiveBackupKeyGUID);
1007 test = torture_rpc_tcase_add_test(tcase, "restore_guid",
1008 test_RestoreGUID);
1010 test = torture_rpc_tcase_add_test(tcase, "restore_guid version 3",
1011 test_RestoreGUID_v3);
1013 /* We double the test in order to be sure that we don't mess stuff (ie. freeing static stuff */
1015 test = torture_rpc_tcase_add_test(tcase, "restore_guid_2nd",
1016 test_RestoreGUID);
1018 test = torture_rpc_tcase_add_test(tcase, "unable_to_decrypt_secret",
1019 test_RestoreGUID_ko);
1021 test = torture_rpc_tcase_add_test(tcase, "wrong_user_restore_guid",
1022 test_RestoreGUID_wronguser);
1024 test = torture_rpc_tcase_add_test(tcase, "wrong_version_restore_guid",
1025 test_RestoreGUID_wrongversion);
1027 test = torture_rpc_tcase_add_test(tcase, "bad_magic_on_secret_restore_guid",
1028 test_RestoreGUID_badmagiconsecret);
1030 test = torture_rpc_tcase_add_test(tcase, "bad_hash_on_secret_restore_guid",
1031 test_RestoreGUID_badhashaccesscheck);
1033 test = torture_rpc_tcase_add_test(tcase, "bad_magic_on_accesscheck_restore_guid",
1034 test_RestoreGUID_badmagicaccesscheck);
1036 test = torture_rpc_tcase_add_test(tcase, "bad_cert_guid_restore_guid",
1037 test_RestoreGUID_badcertguid);
1039 test = torture_rpc_tcase_add_test(tcase, "empty_request_restore_guid",
1040 test_RestoreGUID_emptyrequest);
1042 return suite;