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/>.
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"
29 #include <hcrypto/sha.h>
30 #include <system/network.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
,
47 struct lsa_ObjectAttribute attr
;
48 struct lsa_QosInfo qos
;
49 struct lsa_OpenPolicy2 r
;
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
;
58 struct dom_sid
*result
;
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
))) {
74 qos
.impersonation_level
= 2;
76 qos
.effective_only
= 0;
80 attr
.object_name
= NULL
;
85 r
.in
.system_name
= "\\";
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
)) {
93 "OpenPolicy2 failed - %s\n",
98 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
100 "OpenPolicy2_ failed - %s\n",
101 nt_errstr(r
.out
.result
));
102 talloc_free(tmp_ctx
);
109 lsa_name
.string
= talloc_asprintf(tmp_ctx
, "%s\\%s", domain
, user
);
111 l
.in
.handle
= &handle
;
113 l
.in
.names
= &lsa_name
;
117 l
.out
.count
= &count
;
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",
127 talloc_free(tmp_ctx
);
131 if (domains
->count
== 0) {
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",
147 talloc_free(tmp_ctx
);
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
);
159 talloc_free(tmp_ctx
);
162 torture_comment(tctx
, "Get_user_sid finished\n");
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
,
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
;
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
)) {
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 !!! */
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
)) {
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
);
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
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
,
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
);
257 struct bkrp_access_check_v2 access_struct
;
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
)) {
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
280 SHA1_Update(&sctx
, blob
->data
,
281 blob
->length
- sizeof(access_struct
.hash
));
282 SHA1_Final(blob
->data
+ blob
->length
- sizeof(access_struct
.hash
),
285 /* Altering the SHA */
287 blob
->data
[blob
->length
- 1]++;
292 struct bkrp_access_check_v3 access_struct
;
293 struct hc_sha512state sctx
;
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
)) {
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
314 SHA512_Update(&sctx
, blob
->data
,
315 blob
->length
- sizeof(access_struct
.hash
));
316 SHA512_Final(blob
->data
+ blob
->length
- sizeof(access_struct
.hash
),
319 /* Altering the SHA */
321 blob
->data
[blob
->length
-1]++;
324 talloc_free(tmp_ctx
);
329 static DATA_BLOB
*encrypt_blob(struct torture_context
*tctx
,
333 DATA_BLOB
*to_encrypt
,
334 const AlgorithmIdentifier
*alg
)
338 heim_octet_string ivos
;
339 heim_octet_string
*encrypted
;
340 DATA_BLOB
*blob
= talloc_zero(mem_ctx
, DATA_BLOB
);
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
);
350 torture_comment(tctx
,
351 "error while doing the init of the crypto object\n");
352 hx509_context_free(&hctx
);
355 res
= hx509_crypto_set_key_data(crypto
, key
->data
, key
->length
);
357 torture_comment(tctx
,
358 "error while setting the key of the crypto object\n");
359 hx509_context_free(&hctx
);
363 hx509_crypto_set_padding(crypto
, HX509_CRYPTO_PADDING_NONE
);
364 res
= hx509_crypto_encrypt(crypto
,
370 torture_comment(tctx
, "error while encrypting\n");
371 hx509_crypto_destroy(crypto
);
372 hx509_context_free(&hctx
);
376 *blob
= data_blob_talloc(blob
, encrypted
->data
, encrypted
->length
);
377 der_free_octet_string(encrypted
);
379 hx509_crypto_destroy(crypto
);
380 hx509_context_free(&hctx
);
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
,
395 heim_bit_string subjectuniqid
;
399 struct GUID
*guid
= talloc_zero(mem_ctx
, struct GUID
);
402 hx509_context_init(&hctx
);
404 hret
= hx509_cert_init_data(hctx
, cert_data
, cert_len
, &cert
);
406 torture_comment(tctx
, "error while loading the cert\n");
407 hx509_context_free(&hctx
);
410 hret
= hx509_cert_get_issuer_unique_id(hctx
, cert
, &subjectuniqid
);
412 torture_comment(tctx
, "error while getting the issuer_uniq_id\n");
413 hx509_cert_free(cert
);
414 hx509_context_free(&hctx
);
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
)) {
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
,
444 DATA_BLOB
*to_encrypt
)
448 heim_octet_string secretdata
;
449 heim_octet_string encrypted
;
450 heim_oid encryption_oid
;
454 hx509_context_init(&hctx
);
456 hret
= hx509_cert_init_data(hctx
, cert_data
, cert_len
, &cert
);
458 torture_comment(tctx
, "error while loading the cert\n");
459 hx509_context_free(&hctx
);
463 secretdata
.data
= to_encrypt
->data
;
464 secretdata
.length
= to_encrypt
->length
;
465 hret
= hx509_cert_public_encrypt(hctx
, &secretdata
,
466 cert
, &encryption_oid
,
468 hx509_cert_free(cert
);
469 hx509_context_free(&hctx
);
471 torture_comment(tctx
, "error while encrypting\n");
475 blob
= talloc_zero(mem_ctx
, DATA_BLOB
);
477 der_free_oid(&encryption_oid
);
478 der_free_octet_string(&encrypted
);
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
) {
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
;
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
;
508 binding
= dcerpc_binding_dup(tctx
, p
->binding
);
509 if (binding
== NULL
) {
513 status
= dcerpc_binding_set_flags(binding
, DCERPC_SEAL
|DCERPC_AUTH_SPNEGO
, 0);
514 if (!NT_STATUS_IS_OK(status
)) {
519 status
= GUID_from_string(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID
, g
);
520 if (!NT_STATUS_IS_OK(status
)) {
524 r
->in
.guidActionAgent
= g
;
525 data
.version
= version
;
526 ndr_err
= ndr_push_struct_blob(&blob
, tctx
, &data
,
527 (ndr_push_flags_fn_t
)ndr_push_bkrp_client_side_wrapped
);
528 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
531 r
->in
.data_in
= blob
.data
;
532 r
->in
.data_in_len
= blob
.length
;
533 r
->out
.data_out
= &out
->data
;
534 r
->out
.data_out_len
= talloc(r
, uint32_t);
538 static struct bkrp_BackupKey
*createRestoreGUIDStruct(struct torture_context
*tctx
,
539 struct dcerpc_pipe
*p
, int version
, DATA_BLOB
*out
,
543 bool broken_magic_secret
,
544 bool broken_magic_access
,
545 bool broken_hash_access
,
546 bool broken_cert_guid
)
548 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
549 struct bkrp_client_side_wrapped data
;
555 DATA_BLOB enc_sec_reverted
;
560 struct GUID
*guid
, *g
;
563 enum ndr_err_code ndr_err
;
566 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, version
, &out_blob
);
572 /* we take a fake user*/
575 user
= cli_credentials_get_username(cmdline_credentials
);
579 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
582 * We have to set it outside of the function createRetreiveBackupKeyGUIDStruct
583 * the len of the blob, this is due to the fact that they don't have the
584 * same size (one is 32bits the other 64bits)
586 out_blob
.length
= *r
->out
.data_out_len
;
588 sec
= create_unencryptedsecret(tctx
, broken_magic_secret
, version
);
593 xs
= create_access_check(tctx
, p
, tctx
, user
, broken_hash_access
, version
);
598 if (broken_magic_access
){
599 /* The start of the access_check structure contains the
600 * GUID of the certificate
605 enc_sec
= encrypt_blob_pk(tctx
, tctx
, out_blob
.data
, out_blob
.length
, sec
);
609 enc_sec_reverted
.data
= talloc_array(tctx
, uint8_t, enc_sec
->length
);
610 if (enc_sec_reverted
.data
== NULL
) {
613 enc_sec_reverted
.length
= enc_sec
->length
;
616 * We DO NOT revert the array on purpose it's in order to check that
617 * when the server is not able to decrypt then it answer the correct error
620 for(t
=0; t
< enc_sec
->length
; t
++) {
621 enc_sec_reverted
.data
[t
] = ((uint8_t*)enc_sec
->data
)[t
];
624 for(t
=0; t
< enc_sec
->length
; t
++) {
625 enc_sec_reverted
.data
[t
] = ((uint8_t*)enc_sec
->data
)[enc_sec
->length
- t
-1];
631 const AlgorithmIdentifier
*alg
= hx509_crypto_des_rsdi_ede3_cbc();
632 iv
.data
= sec
->data
+(size
- 8);
635 des3_key
.data
= sec
->data
+(size
- 32);
636 des3_key
.length
= 24;
638 enc_xs
= encrypt_blob(tctx
, tctx
, &des3_key
, &iv
, xs
, alg
);
641 const AlgorithmIdentifier
*alg
= hx509_crypto_aes256_cbc();
642 iv
.data
= sec
->data
+(size
-16);
645 aes_key
.data
= sec
->data
+(size
-48);
648 enc_xs
= encrypt_blob(tctx
, tctx
, &aes_key
, &iv
, xs
, alg
);
655 /* To cope with the fact that heimdal do padding at the end for the moment */
656 enc_xs
->length
= xs
->length
;
658 guid
= get_cert_guid(tctx
, tctx
, out_blob
.data
, out_blob
.length
);
663 if (broken_version
) {
666 data
.version
= version
;
670 data
.encrypted_secret
= enc_sec_reverted
.data
;
671 data
.access_check
= enc_xs
->data
;
672 data
.encrypted_secret_len
= enc_sec
->length
;
673 data
.access_check_len
= enc_xs
->length
;
675 /* We want the blob to persist after this function so we don't
676 * allocate it in the stack
678 blob2
= talloc(tctx
, DATA_BLOB
);
683 ndr_err
= ndr_push_struct_blob(blob2
, tctx
, &data
,
684 (ndr_push_flags_fn_t
)ndr_push_bkrp_client_side_wrapped
);
685 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
689 if (broken_cert_guid
) {
695 g
= talloc(tctx
, struct GUID
);
700 status
= GUID_from_string(BACKUPKEY_RESTORE_GUID
, g
);
701 if (!NT_STATUS_IS_OK(status
)) {
705 r
->in
.guidActionAgent
= g
;
706 r
->in
.data_in
= blob2
->data
;
707 r
->in
.data_in_len
= blob2
->length
;
709 r
->out
.data_out
= &(out
->data
);
710 r
->out
.data_out_len
= talloc(r
, uint32_t);
714 /* Check that we are able to receive the certificate of the DCs
715 * used for client wrap version of the backup key protocol
717 static bool test_RetreiveBackupKeyGUID(struct torture_context
*tctx
,
718 struct dcerpc_pipe
*p
)
720 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
722 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
728 if (p
->conn
->security_state
.auth_info
!= NULL
&&
729 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
730 torture_assert_ntstatus_ok(tctx
,
731 dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
734 out_blob
.length
= *r
->out
.data_out_len
;
735 torture_assert_werr_equal(tctx
,
738 "Wrong dce/rpc error code");
740 torture_assert_ntstatus_equal(tctx
,
741 dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
742 NT_STATUS_ACCESS_DENIED
,
748 /* Test to check the failure to recover a secret because the
749 * secret blob is not reversed
751 static bool test_RestoreGUID_ko(struct torture_context
*tctx
,
752 struct dcerpc_pipe
*p
)
754 enum ndr_err_code ndr_err
;
755 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
757 struct bkrp_client_side_unwrapped resp
;
759 if (p
->conn
->security_state
.auth_info
!= NULL
&&
760 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
761 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
762 true, false, false, false, false, false, false);
763 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
764 out_blob
.length
= *r
->out
.data_out_len
;
765 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
766 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
767 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_DATA
, "Wrong error code");
769 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
770 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
771 NT_STATUS_ACCESS_DENIED
, "Get GUID");
776 static bool test_RestoreGUID_wrongversion(struct torture_context
*tctx
,
777 struct dcerpc_pipe
*p
)
779 enum ndr_err_code ndr_err
;
780 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
782 struct bkrp_client_side_unwrapped resp
;
784 if (p
->conn
->security_state
.auth_info
!= NULL
&&
785 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
786 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
787 false, true, false, false, false, false, false);
788 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
789 out_blob
.length
= *r
->out
.data_out_len
;
790 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
791 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
792 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_PARAM
, "Wrong error code on wrong version");
794 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
795 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
796 NT_STATUS_ACCESS_DENIED
, "Get GUID");
801 static bool test_RestoreGUID_wronguser(struct torture_context
*tctx
,
802 struct dcerpc_pipe
*p
)
804 enum ndr_err_code ndr_err
;
805 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
807 struct bkrp_client_side_unwrapped resp
;
809 if (p
->conn
->security_state
.auth_info
!= NULL
&&
810 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
811 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
812 false, false, true, false, false, false, false);
813 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
814 out_blob
.length
= *r
->out
.data_out_len
;
815 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
816 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
817 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_ACCESS
, "Restore GUID");
819 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
820 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
821 NT_STATUS_ACCESS_DENIED
, "Get GUID");
826 static bool test_RestoreGUID_v3(struct torture_context
*tctx
,
827 struct dcerpc_pipe
*p
)
829 enum ndr_err_code ndr_err
;
830 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
832 struct bkrp_client_side_unwrapped resp
;
834 if (p
->conn
->security_state
.auth_info
!= NULL
&&
835 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
836 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 3, &out_blob
,
837 false, false, false, false, false, false, false);
838 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
839 out_blob
.length
= *r
->out
.data_out_len
;
840 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
841 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 1, "Unable to unmarshall bkrp_client_side_unwrapped");
842 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_OK
, "Restore GUID");
843 torture_assert_str_equal(tctx
, (char*)resp
.secret
.data
, secret
, "Wrong secret");
845 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
846 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
847 NT_STATUS_ACCESS_DENIED
, "Get GUID");
852 static bool test_RestoreGUID(struct torture_context
*tctx
,
853 struct dcerpc_pipe
*p
)
855 enum ndr_err_code ndr_err
;
856 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
858 struct bkrp_client_side_unwrapped resp
;
860 if (p
->conn
->security_state
.auth_info
!= NULL
&&
861 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
862 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
863 false, false, false, false, false, false, false);
864 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
865 out_blob
.length
= *r
->out
.data_out_len
;
866 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
867 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 1, "Unable to unmarshall bkrp_client_side_unwrapped");
868 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_OK
, "Restore GUID");
869 torture_assert_str_equal(tctx
, (char*)resp
.secret
.data
, secret
, "Wrong secret");
871 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
872 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
873 NT_STATUS_ACCESS_DENIED
, "Get GUID");
878 static bool test_RestoreGUID_badmagiconsecret(struct torture_context
*tctx
,
879 struct dcerpc_pipe
*p
)
881 enum ndr_err_code ndr_err
;
882 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
884 struct bkrp_client_side_unwrapped resp
;
886 if (p
->conn
->security_state
.auth_info
!= NULL
&&
887 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
888 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 3, &out_blob
,
889 false, false, false, true, false, false, false);
890 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
891 out_blob
.length
= *r
->out
.data_out_len
;
892 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
893 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
894 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_DATA
, "Wrong error code while providing bad magic in secret");
896 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
897 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
898 NT_STATUS_ACCESS_DENIED
, "Get GUID");
903 static bool test_RestoreGUID_emptyrequest(struct torture_context
*tctx
,
904 struct dcerpc_pipe
*p
)
906 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
909 if (p
->conn
->security_state
.auth_info
!= NULL
&&
910 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
911 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 3, &out_blob
,
912 false, false, false, true, false, false, true);
914 torture_assert_int_equal(tctx
, r
!= NULL
, 1, "Error while creating the restoreGUID struct");
915 r
->in
.data_in
= talloc(tctx
, uint8_t);
916 r
->in
.data_in_len
= 0;
918 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
919 out_blob
.length
= *r
->out
.data_out_len
;
920 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_PARAM
, "Bad error code on wrong has in access check");
922 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
923 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
924 NT_STATUS_ACCESS_DENIED
, "Get GUID");
929 static bool test_RestoreGUID_badcertguid(struct torture_context
*tctx
,
930 struct dcerpc_pipe
*p
)
932 enum ndr_err_code ndr_err
;
933 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
935 struct bkrp_client_side_unwrapped resp
;
937 if (p
->conn
->security_state
.auth_info
!= NULL
&&
938 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
939 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 3, &out_blob
,
940 false, false, false, false, false, false, true);
941 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
942 out_blob
.length
= *r
->out
.data_out_len
;
943 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
944 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
945 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_FILE_NOT_FOUND
, "Bad error code on wrong has in access check");
947 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
948 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
949 NT_STATUS_ACCESS_DENIED
, "Get GUID");
954 static bool test_RestoreGUID_badmagicaccesscheck(struct torture_context
*tctx
,
955 struct dcerpc_pipe
*p
)
957 enum ndr_err_code ndr_err
;
958 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
960 struct bkrp_client_side_unwrapped resp
;
962 if (p
->conn
->security_state
.auth_info
!= NULL
&&
963 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
964 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
965 false, false, false, false, true, false, false);
966 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
967 out_blob
.length
= *r
->out
.data_out_len
;
968 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
969 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
970 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_DATA
, "Bad error code on wrong has in access check");
972 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
973 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
974 NT_STATUS_ACCESS_DENIED
, "Get GUID");
979 static bool test_RestoreGUID_badhashaccesscheck(struct torture_context
*tctx
,
980 struct dcerpc_pipe
*p
)
982 enum ndr_err_code ndr_err
;
983 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
985 struct bkrp_client_side_unwrapped resp
;
987 if (p
->conn
->security_state
.auth_info
!= NULL
&&
988 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
989 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
990 false, false, false, false, false, true, false);
991 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
992 out_blob
.length
= *r
->out
.data_out_len
;
993 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
994 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
995 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_DATA
, "Bad error code on wrong has in access check");
997 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
998 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
999 NT_STATUS_ACCESS_DENIED
, "Get GUID");
1004 struct torture_suite
*torture_rpc_backupkey(TALLOC_CTX
*mem_ctx
)
1006 struct torture_rpc_tcase
*tcase
;
1007 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "backupkey");
1009 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "backupkey",
1010 &ndr_table_backupkey
);
1012 torture_rpc_tcase_add_test(tcase
, "retreive_backup_key_guid",
1013 test_RetreiveBackupKeyGUID
);
1015 torture_rpc_tcase_add_test(tcase
, "restore_guid",
1018 torture_rpc_tcase_add_test(tcase
, "restore_guid version 3",
1019 test_RestoreGUID_v3
);
1021 /* We double the test in order to be sure that we don't mess stuff (ie. freeing static stuff */
1023 torture_rpc_tcase_add_test(tcase
, "restore_guid_2nd",
1026 torture_rpc_tcase_add_test(tcase
, "unable_to_decrypt_secret",
1027 test_RestoreGUID_ko
);
1029 torture_rpc_tcase_add_test(tcase
, "wrong_user_restore_guid",
1030 test_RestoreGUID_wronguser
);
1032 torture_rpc_tcase_add_test(tcase
, "wrong_version_restore_guid",
1033 test_RestoreGUID_wrongversion
);
1035 torture_rpc_tcase_add_test(tcase
, "bad_magic_on_secret_restore_guid",
1036 test_RestoreGUID_badmagiconsecret
);
1038 torture_rpc_tcase_add_test(tcase
, "bad_hash_on_secret_restore_guid",
1039 test_RestoreGUID_badhashaccesscheck
);
1041 torture_rpc_tcase_add_test(tcase
, "bad_magic_on_accesscheck_restore_guid",
1042 test_RestoreGUID_badmagicaccesscheck
);
1044 torture_rpc_tcase_add_test(tcase
, "bad_cert_guid_restore_guid",
1045 test_RestoreGUID_badcertguid
);
1047 torture_rpc_tcase_add_test(tcase
, "empty_request_restore_guid",
1048 test_RestoreGUID_emptyrequest
);