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
= 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
;
508 binding
->flags
= binding
->flags
& (DCERPC_SEAL
|DCERPC_AUTH_SPNEGO
);
510 status
= GUID_from_string(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID
, g
);
511 if (!NT_STATUS_IS_OK(status
)) {
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
)) {
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);
529 static struct bkrp_BackupKey
*createRestoreGUIDStruct(struct torture_context
*tctx
,
530 struct dcerpc_pipe
*p
, int version
, DATA_BLOB
*out
,
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
;
546 DATA_BLOB enc_sec_reverted
;
551 struct GUID
*guid
, *g
;
554 enum ndr_err_code ndr_err
;
557 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, version
, &out_blob
);
563 /* we take a fake user*/
566 user
= cli_credentials_get_username(cmdline_credentials
);
570 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
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
);
584 xs
= create_access_check(tctx
, p
, tctx
, user
, broken_hash_access
, version
);
589 if (broken_magic_access
){
590 /* The start of the access_check structure contains the
591 * GUID of the certificate
596 enc_sec
= encrypt_blob_pk(tctx
, tctx
, out_blob
.data
, out_blob
.length
, sec
);
600 enc_sec_reverted
.data
= talloc_array(tctx
, uint8_t, enc_sec
->length
);
601 if (enc_sec_reverted
.data
== 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
611 for(t
=0; t
< enc_sec
->length
; t
++) {
612 enc_sec_reverted
.data
[t
] = ((uint8_t*)enc_sec
->data
)[t
];
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];
622 const AlgorithmIdentifier
*alg
= hx509_crypto_des_rsdi_ede3_cbc();
623 iv
.data
= sec
->data
+(size
- 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
);
632 const AlgorithmIdentifier
*alg
= hx509_crypto_aes256_cbc();
633 iv
.data
= sec
->data
+(size
-16);
636 aes_key
.data
= sec
->data
+(size
-48);
639 enc_xs
= encrypt_blob(tctx
, tctx
, &aes_key
, &iv
, xs
, alg
);
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
);
654 if (broken_version
) {
657 data
.version
= version
;
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
);
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
)) {
680 if (broken_cert_guid
) {
686 g
= talloc(tctx
, struct GUID
);
691 status
= GUID_from_string(BACKUPKEY_RESTORE_GUID
, g
);
692 if (!NT_STATUS_IS_OK(status
)) {
696 r
->in
.guidActionAgent
= g
;
697 r
->in
.data_in
= blob2
->data
;
698 r
->in
.data_in_len
= blob2
->length
;
700 r
->out
.data_out
= &(out
->data
);
701 r
->out
.data_out_len
= talloc(r
, uint32_t);
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
;
713 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
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
),
725 out_blob
.length
= *r
->out
.data_out_len
;
726 torture_assert_werr_equal(tctx
,
729 "Wrong dce/rpc error code");
731 torture_assert_ntstatus_equal(tctx
,
732 dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
733 NT_STATUS_ACCESS_DENIED
,
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
;
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");
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");
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
;
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");
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");
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
;
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");
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");
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
;
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");
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");
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
;
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");
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");
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
;
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");
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");
894 static bool test_RestoreGUID_emptyrequest(struct torture_context
*tctx
,
895 struct dcerpc_pipe
*p
)
897 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
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;
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");
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");
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
;
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");
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");
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
;
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");
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");
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
;
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");
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");
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",
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",
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
);