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"
28 #include <hcrypto/sha.h>
29 #include <system/network.h>
34 /* Our very special and valued secret */
35 /* No need to put const as we cast the array in uint8_t
36 * we will get a warning about the discared const
38 static const char secret
[] = "tata yoyo mais qu'est ce qu'il y a sous ton grand chapeau ?";
40 /* Get the SID from a user */
41 static const struct dom_sid
*get_user_sid(struct torture_context
*tctx
,
42 struct dcerpc_pipe
*p
,
46 struct lsa_ObjectAttribute attr
;
47 struct lsa_QosInfo qos
;
48 struct lsa_OpenPolicy2 r
;
51 struct policy_handle handle
;
52 struct lsa_LookupNames l
;
53 struct lsa_TransSidArray sids
;
54 struct lsa_RefDomainList
*domains
= NULL
;
55 struct lsa_String lsa_name
;
57 struct dom_sid
*result
;
59 struct dcerpc_pipe
*p2
;
60 struct dcerpc_binding_handle
*b
;
62 const char *domain
= cli_credentials_get_domain(cmdline_credentials
);
64 torture_assert_ntstatus_ok(tctx
,
65 torture_rpc_connection(tctx
, &p2
, &ndr_table_lsarpc
),
66 "could not open lsarpc pipe");
67 b
= p2
->binding_handle
;
69 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
73 qos
.impersonation_level
= 2;
75 qos
.effective_only
= 0;
79 attr
.object_name
= NULL
;
84 r
.in
.system_name
= "\\";
86 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
87 r
.out
.handle
= &handle
;
89 status
= dcerpc_lsa_OpenPolicy2_r(b
, tmp_ctx
, &r
);
90 if (!NT_STATUS_IS_OK(status
)) {
92 "OpenPolicy2 failed - %s\n",
97 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
99 "OpenPolicy2_ failed - %s\n",
100 nt_errstr(r
.out
.result
));
101 talloc_free(tmp_ctx
);
108 lsa_name
.string
= talloc_asprintf(tmp_ctx
, "%s\\%s", domain
, user
);
110 l
.in
.handle
= &handle
;
112 l
.in
.names
= &lsa_name
;
116 l
.out
.count
= &count
;
118 l
.out
.domains
= &domains
;
120 status
= dcerpc_lsa_LookupNames_r(b
, tmp_ctx
, &l
);
121 if (!NT_STATUS_IS_OK(status
)) {
122 torture_comment(tctx
,
123 "LookupNames of %s failed - %s\n",
126 talloc_free(tmp_ctx
);
130 if (domains
->count
== 0) {
134 result
= dom_sid_add_rid(mem_ctx
,
135 domains
->domains
[0].sid
,
136 l
.out
.sids
->sids
[0].rid
);
137 c
.in
.handle
= &handle
;
138 c
.out
.handle
= &handle
;
140 status
= dcerpc_lsa_Close_r(b
, tmp_ctx
, &c
);
142 if (!NT_STATUS_IS_OK(status
)) {
143 torture_comment(tctx
,
144 "dcerpc_lsa_Close failed - %s\n",
146 talloc_free(tmp_ctx
);
150 if (!NT_STATUS_IS_OK(c
.out
.result
)) {
151 torture_comment(tctx
,
152 "dcerpc_lsa_Close failed - %s\n",
153 nt_errstr(c
.out
.result
));
154 talloc_free(tmp_ctx
);
158 talloc_free(tmp_ctx
);
161 torture_comment(tctx
, "Get_user_sid finished\n");
166 * Create a bkrp_encrypted_secret_vX structure
167 * the version depends on the version parameter
168 * the structure is returned as a blob.
169 * The broken flag is to indicate if we want
170 * to create a non conform to specification structre
172 static DATA_BLOB
*create_unencryptedsecret(TALLOC_CTX
*mem_ctx
,
176 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
177 DATA_BLOB
*blob
= talloc_zero(mem_ctx
, DATA_BLOB
);
178 enum ndr_err_code ndr_err
;
181 struct bkrp_encrypted_secret_v2 unenc_sec
;
183 ZERO_STRUCT(unenc_sec
);
184 unenc_sec
.secret_len
= sizeof(secret
);
185 unenc_sec
.secret
= discard_const_p(uint8_t, secret
);
186 generate_random_buffer(unenc_sec
.payload_key
,
187 sizeof(unenc_sec
.payload_key
));
189 ndr_err
= ndr_push_struct_blob(blob
, blob
, &unenc_sec
,
190 (ndr_push_flags_fn_t
)ndr_push_bkrp_encrypted_secret_v2
);
191 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
196 /* The magic value is correctly set by the NDR push
197 * but we want to test the behavior of the server
198 * if a differrent value is provided
200 ((uint8_t*)blob
->data
)[4] = 79; /* A great year !!! */
205 struct bkrp_encrypted_secret_v3 unenc_sec
;
207 ZERO_STRUCT(unenc_sec
);
208 unenc_sec
.secret_len
= sizeof(secret
);
209 unenc_sec
.secret
= discard_const_p(uint8_t, secret
);
210 generate_random_buffer(unenc_sec
.payload_key
,
211 sizeof(unenc_sec
.payload_key
));
213 ndr_err
= ndr_push_struct_blob(blob
, blob
, &unenc_sec
,
214 (ndr_push_flags_fn_t
)ndr_push_bkrp_encrypted_secret_v3
);
215 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
221 * The magic value is correctly set by the NDR push
222 * but we want to test the behavior of the server
223 * if a differrent value is provided
225 ((uint8_t*)blob
->data
)[4] = 79; /* A great year !!! */
228 talloc_free(tmp_ctx
);
233 * Create an access check structure, the format depends on the version parameter.
234 * If broken is specified then we create a stucture that isn't conform to the
237 * If the structure can't be created then NULL is returned.
239 static DATA_BLOB
*create_access_check(struct torture_context
*tctx
,
240 struct dcerpc_pipe
*p
,
246 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
247 DATA_BLOB
*blob
= talloc_zero(mem_ctx
, DATA_BLOB
);
248 enum ndr_err_code ndr_err
;
249 const struct dom_sid
*sid
= get_user_sid(tctx
, p
, tmp_ctx
, user
);
256 struct bkrp_access_check_v2 access_struct
;
260 ZERO_STRUCT(access_struct
);
261 generate_random_buffer(nonce
, sizeof(nonce
));
262 access_struct
.nonce_len
= sizeof(nonce
);
263 access_struct
.nonce
= nonce
;
264 access_struct
.sid
= *sid
;
266 ndr_err
= ndr_push_struct_blob(blob
, blob
, &access_struct
,
267 (ndr_push_flags_fn_t
)ndr_push_bkrp_access_check_v2
);
268 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
273 * We pushed the whole structure including a null hash
274 * but the hash need to be calculated only up to the hash field
275 * so we reduce the size of what has to be calculated
279 SHA1_Update(&sctx
, blob
->data
,
280 blob
->length
- sizeof(access_struct
.hash
));
281 SHA1_Final(blob
->data
+ blob
->length
- sizeof(access_struct
.hash
),
284 /* Altering the SHA */
286 blob
->data
[blob
->length
- 1]++;
291 struct bkrp_access_check_v3 access_struct
;
292 struct hc_sha512state sctx
;
295 ZERO_STRUCT(access_struct
);
296 generate_random_buffer(nonce
, sizeof(nonce
));
297 access_struct
.nonce_len
= sizeof(nonce
);
298 access_struct
.nonce
= nonce
;
299 access_struct
.sid
= *sid
;
301 ndr_err
= ndr_push_struct_blob(blob
, blob
, &access_struct
,
302 (ndr_push_flags_fn_t
)ndr_push_bkrp_access_check_v3
);
303 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
307 /*We pushed the whole structure including a null hash
308 * but the hash need to be calculated only up to the hash field
309 * so we reduce the size of what has to be calculated
313 SHA512_Update(&sctx
, blob
->data
,
314 blob
->length
- sizeof(access_struct
.hash
));
315 SHA512_Final(blob
->data
+ blob
->length
- sizeof(access_struct
.hash
),
318 /* Altering the SHA */
320 blob
->data
[blob
->length
-1]++;
323 talloc_free(tmp_ctx
);
328 static DATA_BLOB
*encrypt_blob(struct torture_context
*tctx
,
332 DATA_BLOB
*to_encrypt
,
333 const AlgorithmIdentifier
*alg
)
337 heim_octet_string ivos
;
338 heim_octet_string
*encrypted
;
339 DATA_BLOB
*blob
= talloc_zero(mem_ctx
, DATA_BLOB
);
342 ivos
.data
= talloc_array(mem_ctx
, uint8_t, iv
->length
);
343 ivos
.length
= iv
->length
;
344 memcpy(ivos
.data
, iv
->data
, iv
->length
);
346 hx509_context_init(&hctx
);
347 res
= hx509_crypto_init(hctx
, NULL
, &alg
->algorithm
, &crypto
);
349 torture_comment(tctx
,
350 "error while doing the init of the crypto object\n");
351 hx509_context_free(&hctx
);
354 res
= hx509_crypto_set_key_data(crypto
, key
->data
, key
->length
);
356 torture_comment(tctx
,
357 "error while setting the key of the crypto object\n");
358 hx509_context_free(&hctx
);
362 hx509_crypto_set_padding(crypto
, HX509_CRYPTO_PADDING_NONE
);
363 res
= hx509_crypto_encrypt(crypto
,
369 torture_comment(tctx
, "error while encrypting\n");
370 hx509_crypto_destroy(crypto
);
371 hx509_context_free(&hctx
);
375 *blob
= data_blob_talloc(blob
, encrypted
->data
, encrypted
->length
);
376 der_free_octet_string(encrypted
);
378 hx509_crypto_destroy(crypto
);
379 hx509_context_free(&hctx
);
384 * Certs used for this protocol have a GUID in the issuer_uniq_id field.
385 * This function fetch it.
387 static struct GUID
*get_cert_guid(struct torture_context
*tctx
,
394 heim_bit_string subjectuniqid
;
398 struct GUID
*guid
= talloc_zero(mem_ctx
, struct GUID
);
401 hx509_context_init(&hctx
);
403 hret
= hx509_cert_init_data(hctx
, cert_data
, cert_len
, &cert
);
405 torture_comment(tctx
, "error while loading the cert\n");
406 hx509_context_free(&hctx
);
409 hret
= hx509_cert_get_issuer_unique_id(hctx
, cert
, &subjectuniqid
);
411 torture_comment(tctx
, "error while getting the issuer_uniq_id\n");
412 hx509_cert_free(cert
);
413 hx509_context_free(&hctx
);
417 /* The subjectuniqid is a bit string,
418 * which means that the real size has to be divided by 8
419 * to have the number of bytes
421 hx509_cert_free(cert
);
422 hx509_context_free(&hctx
);
423 size
= subjectuniqid
.length
/ 8;
424 data
= data_blob_const(subjectuniqid
.data
, size
);
426 status
= GUID_from_data_blob(&data
, guid
);
427 der_free_bit_string(&subjectuniqid
);
428 if (!NT_STATUS_IS_OK(status
)) {
436 * Encrypt a blob with the private key of the certificate
437 * passed as a parameter.
439 static DATA_BLOB
*encrypt_blob_pk(struct torture_context
*tctx
,
443 DATA_BLOB
*to_encrypt
)
447 heim_octet_string secretdata
;
448 heim_octet_string encrypted
;
449 heim_oid encryption_oid
;
453 hx509_context_init(&hctx
);
455 hret
= hx509_cert_init_data(hctx
, cert_data
, cert_len
, &cert
);
457 torture_comment(tctx
, "error while loading the cert\n");
458 hx509_context_free(&hctx
);
462 secretdata
.data
= to_encrypt
->data
;
463 secretdata
.length
= to_encrypt
->length
;
464 hret
= hx509_cert_public_encrypt(hctx
, &secretdata
,
465 cert
, &encryption_oid
,
467 hx509_cert_free(cert
);
468 hx509_context_free(&hctx
);
470 torture_comment(tctx
, "error while encrypting\n");
474 blob
= talloc_zero(mem_ctx
, DATA_BLOB
);
476 der_free_oid(&encryption_oid
);
477 der_free_octet_string(&encrypted
);
481 *blob
= data_blob_talloc(blob
, encrypted
.data
, encrypted
.length
);
482 der_free_octet_string(&encrypted
);
483 der_free_oid(&encryption_oid
);
484 if (blob
->data
== NULL
) {
492 static struct bkrp_BackupKey
*createRetreiveBackupKeyGUIDStruct(struct torture_context
*tctx
,
493 struct dcerpc_pipe
*p
, int version
, DATA_BLOB
*out
)
495 struct dcerpc_binding
*binding
= p
->binding
;
496 struct bkrp_client_side_wrapped data
;
497 struct GUID
*g
= talloc(tctx
, struct GUID
);
498 struct bkrp_BackupKey
*r
= talloc_zero(tctx
, struct bkrp_BackupKey
);
499 enum ndr_err_code ndr_err
;
507 binding
->flags
= binding
->flags
& (DCERPC_SEAL
|DCERPC_AUTH_SPNEGO
);
509 status
= GUID_from_string(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID
, g
);
510 if (!NT_STATUS_IS_OK(status
)) {
514 r
->in
.guidActionAgent
= g
;
515 data
.version
= version
;
516 ndr_err
= ndr_push_struct_blob(&blob
, tctx
, &data
,
517 (ndr_push_flags_fn_t
)ndr_push_bkrp_client_side_wrapped
);
518 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
521 r
->in
.data_in
= blob
.data
;
522 r
->in
.data_in_len
= blob
.length
;
523 r
->out
.data_out
= &out
->data
;
524 r
->out
.data_out_len
= talloc(r
, uint32_t);
528 static struct bkrp_BackupKey
*createRestoreGUIDStruct(struct torture_context
*tctx
,
529 struct dcerpc_pipe
*p
, int version
, DATA_BLOB
*out
,
533 bool broken_magic_secret
,
534 bool broken_magic_access
,
535 bool broken_hash_access
,
536 bool broken_cert_guid
)
538 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
539 struct bkrp_client_side_wrapped data
;
545 DATA_BLOB enc_sec_reverted
;
550 struct GUID
*guid
, *g
;
553 enum ndr_err_code ndr_err
;
556 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, version
, &out_blob
);
562 /* we take a fake user*/
565 user
= cli_credentials_get_username(cmdline_credentials
);
569 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
572 * We have to set it outside of the function createRetreiveBackupKeyGUIDStruct
573 * the len of the blob, this is due to the fact that they don't have the
574 * same size (one is 32bits the other 64bits)
576 out_blob
.length
= *r
->out
.data_out_len
;
578 sec
= create_unencryptedsecret(tctx
, broken_magic_secret
, version
);
583 xs
= create_access_check(tctx
, p
, tctx
, user
, broken_hash_access
, version
);
588 if (broken_magic_access
){
589 /* The start of the access_check structure contains the
590 * GUID of the certificate
595 enc_sec
= encrypt_blob_pk(tctx
, tctx
, out_blob
.data
, out_blob
.length
, sec
);
599 enc_sec_reverted
.data
= talloc_array(tctx
, uint8_t, enc_sec
->length
);
600 if (enc_sec_reverted
.data
== NULL
) {
603 enc_sec_reverted
.length
= enc_sec
->length
;
606 * We DO NOT revert the array on purpose it's in order to check that
607 * when the server is not able to decrypt then it answer the correct error
610 for(t
=0; t
< enc_sec
->length
; t
++) {
611 enc_sec_reverted
.data
[t
] = ((uint8_t*)enc_sec
->data
)[t
];
614 for(t
=0; t
< enc_sec
->length
; t
++) {
615 enc_sec_reverted
.data
[t
] = ((uint8_t*)enc_sec
->data
)[enc_sec
->length
- t
-1];
621 const AlgorithmIdentifier
*alg
= hx509_crypto_des_rsdi_ede3_cbc();
622 iv
.data
= sec
->data
+(size
- 8);
625 des3_key
.data
= sec
->data
+(size
- 32);
626 des3_key
.length
= 24;
628 enc_xs
= encrypt_blob(tctx
, tctx
, &des3_key
, &iv
, xs
, alg
);
631 const AlgorithmIdentifier
*alg
= hx509_crypto_aes256_cbc();
632 iv
.data
= sec
->data
+(size
-16);
635 aes_key
.data
= sec
->data
+(size
-48);
638 enc_xs
= encrypt_blob(tctx
, tctx
, &aes_key
, &iv
, xs
, alg
);
645 /* To cope with the fact that heimdal do padding at the end for the moment */
646 enc_xs
->length
= xs
->length
;
648 guid
= get_cert_guid(tctx
, tctx
, out_blob
.data
, out_blob
.length
);
653 if (broken_version
) {
656 data
.version
= version
;
660 data
.encrypted_secret
= enc_sec_reverted
.data
;
661 data
.access_check
= enc_xs
->data
;
662 data
.encrypted_secret_len
= enc_sec
->length
;
663 data
.access_check_len
= enc_xs
->length
;
665 /* We want the blob to persist after this function so we don't
666 * allocate it in the stack
668 blob2
= talloc(tctx
, DATA_BLOB
);
673 ndr_err
= ndr_push_struct_blob(blob2
, tctx
, &data
,
674 (ndr_push_flags_fn_t
)ndr_push_bkrp_client_side_wrapped
);
675 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
679 if (broken_cert_guid
) {
685 g
= talloc(tctx
, struct GUID
);
690 status
= GUID_from_string(BACKUPKEY_RESTORE_GUID
, g
);
691 if (!NT_STATUS_IS_OK(status
)) {
695 r
->in
.guidActionAgent
= g
;
696 r
->in
.data_in
= blob2
->data
;
697 r
->in
.data_in_len
= blob2
->length
;
699 r
->out
.data_out
= &(out
->data
);
700 r
->out
.data_out_len
= talloc(r
, uint32_t);
704 /* Check that we are able to receive the certificate of the DCs
705 * used for client wrap version of the backup key protocol
707 static bool test_RetreiveBackupKeyGUID(struct torture_context
*tctx
,
708 struct dcerpc_pipe
*p
)
710 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
712 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
718 if (p
->conn
->security_state
.auth_info
!= NULL
&&
719 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
720 torture_assert_ntstatus_ok(tctx
,
721 dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
724 out_blob
.length
= *r
->out
.data_out_len
;
725 torture_assert_werr_equal(tctx
,
728 "Wrong dce/rpc error code");
730 torture_assert_ntstatus_equal(tctx
,
731 dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
732 NT_STATUS_ACCESS_DENIED
,
738 /* Test to check the failure to recover a secret because the
739 * secret blob is not reversed
741 static bool test_RestoreGUID_ko(struct torture_context
*tctx
,
742 struct dcerpc_pipe
*p
)
744 enum ndr_err_code ndr_err
;
745 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
747 struct bkrp_client_side_unwrapped resp
;
749 if (p
->conn
->security_state
.auth_info
!= NULL
&&
750 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
751 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
752 true, false, false, false, false, false, false);
753 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
754 out_blob
.length
= *r
->out
.data_out_len
;
755 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
756 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
757 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_DATA
, "Wrong error code");
759 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
760 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
761 NT_STATUS_ACCESS_DENIED
, "Get GUID");
766 static bool test_RestoreGUID_wrongversion(struct torture_context
*tctx
,
767 struct dcerpc_pipe
*p
)
769 enum ndr_err_code ndr_err
;
770 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
772 struct bkrp_client_side_unwrapped resp
;
774 if (p
->conn
->security_state
.auth_info
!= NULL
&&
775 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
776 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
777 false, true, false, false, false, false, false);
778 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
779 out_blob
.length
= *r
->out
.data_out_len
;
780 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
781 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
782 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_PARAM
, "Wrong error code on wrong version");
784 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
785 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
786 NT_STATUS_ACCESS_DENIED
, "Get GUID");
791 static bool test_RestoreGUID_wronguser(struct torture_context
*tctx
,
792 struct dcerpc_pipe
*p
)
794 enum ndr_err_code ndr_err
;
795 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
797 struct bkrp_client_side_unwrapped resp
;
799 if (p
->conn
->security_state
.auth_info
!= NULL
&&
800 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
801 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
802 false, false, true, false, false, false, false);
803 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
804 out_blob
.length
= *r
->out
.data_out_len
;
805 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
806 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
807 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_ACCESS
, "Restore GUID");
809 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
810 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
811 NT_STATUS_ACCESS_DENIED
, "Get GUID");
816 static bool test_RestoreGUID_v3(struct torture_context
*tctx
,
817 struct dcerpc_pipe
*p
)
819 enum ndr_err_code ndr_err
;
820 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
822 struct bkrp_client_side_unwrapped resp
;
824 if (p
->conn
->security_state
.auth_info
!= NULL
&&
825 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
826 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 3, &out_blob
,
827 false, false, false, false, false, false, false);
828 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
829 out_blob
.length
= *r
->out
.data_out_len
;
830 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
831 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 1, "Unable to unmarshall bkrp_client_side_unwrapped");
832 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_OK
, "Restore GUID");
833 torture_assert_str_equal(tctx
, (char*)resp
.secret
.data
, secret
, "Wrong secret");
835 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
836 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
837 NT_STATUS_ACCESS_DENIED
, "Get GUID");
842 static bool test_RestoreGUID(struct torture_context
*tctx
,
843 struct dcerpc_pipe
*p
)
845 enum ndr_err_code ndr_err
;
846 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
848 struct bkrp_client_side_unwrapped resp
;
850 if (p
->conn
->security_state
.auth_info
!= NULL
&&
851 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
852 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
853 false, false, false, false, false, false, false);
854 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
855 out_blob
.length
= *r
->out
.data_out_len
;
856 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
857 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 1, "Unable to unmarshall bkrp_client_side_unwrapped");
858 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_OK
, "Restore GUID");
859 torture_assert_str_equal(tctx
, (char*)resp
.secret
.data
, secret
, "Wrong secret");
861 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
862 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
863 NT_STATUS_ACCESS_DENIED
, "Get GUID");
868 static bool test_RestoreGUID_badmagiconsecret(struct torture_context
*tctx
,
869 struct dcerpc_pipe
*p
)
871 enum ndr_err_code ndr_err
;
872 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
874 struct bkrp_client_side_unwrapped resp
;
876 if (p
->conn
->security_state
.auth_info
!= NULL
&&
877 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
878 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 3, &out_blob
,
879 false, false, false, true, false, false, false);
880 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
881 out_blob
.length
= *r
->out
.data_out_len
;
882 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
883 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
884 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_DATA
, "Wrong error code while providing bad magic in secret");
886 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
887 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
888 NT_STATUS_ACCESS_DENIED
, "Get GUID");
893 static bool test_RestoreGUID_emptyrequest(struct torture_context
*tctx
,
894 struct dcerpc_pipe
*p
)
896 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
899 if (p
->conn
->security_state
.auth_info
!= NULL
&&
900 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
901 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 3, &out_blob
,
902 false, false, false, true, false, false, true);
904 torture_assert_int_equal(tctx
, r
!= NULL
, 1, "Error while creating the restoreGUID struct");
905 r
->in
.data_in
= talloc(tctx
, uint8_t);
906 r
->in
.data_in_len
= 0;
908 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
909 out_blob
.length
= *r
->out
.data_out_len
;
910 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_PARAM
, "Bad error code on wrong has in access check");
912 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
913 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
914 NT_STATUS_ACCESS_DENIED
, "Get GUID");
919 static bool test_RestoreGUID_badcertguid(struct torture_context
*tctx
,
920 struct dcerpc_pipe
*p
)
922 enum ndr_err_code ndr_err
;
923 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
925 struct bkrp_client_side_unwrapped resp
;
927 if (p
->conn
->security_state
.auth_info
!= NULL
&&
928 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
929 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 3, &out_blob
,
930 false, false, false, false, false, false, true);
931 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
932 out_blob
.length
= *r
->out
.data_out_len
;
933 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
934 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
935 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_FILE_NOT_FOUND
, "Bad error code on wrong has in access check");
937 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
938 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
939 NT_STATUS_ACCESS_DENIED
, "Get GUID");
944 static bool test_RestoreGUID_badmagicaccesscheck(struct torture_context
*tctx
,
945 struct dcerpc_pipe
*p
)
947 enum ndr_err_code ndr_err
;
948 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
950 struct bkrp_client_side_unwrapped resp
;
952 if (p
->conn
->security_state
.auth_info
!= NULL
&&
953 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
954 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
955 false, false, false, false, true, false, false);
956 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
957 out_blob
.length
= *r
->out
.data_out_len
;
958 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
959 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
960 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_DATA
, "Bad error code on wrong has in access check");
962 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
963 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
964 NT_STATUS_ACCESS_DENIED
, "Get GUID");
969 static bool test_RestoreGUID_badhashaccesscheck(struct torture_context
*tctx
,
970 struct dcerpc_pipe
*p
)
972 enum ndr_err_code ndr_err
;
973 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
975 struct bkrp_client_side_unwrapped resp
;
977 if (p
->conn
->security_state
.auth_info
!= NULL
&&
978 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
979 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
980 false, false, false, false, false, true, false);
981 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
982 out_blob
.length
= *r
->out
.data_out_len
;
983 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
984 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
985 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_DATA
, "Bad error code on wrong has in access check");
987 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
988 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
989 NT_STATUS_ACCESS_DENIED
, "Get GUID");
994 struct torture_suite
*torture_rpc_backupkey(TALLOC_CTX
*mem_ctx
)
996 struct torture_rpc_tcase
*tcase
;
997 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "backupkey");
998 struct torture_test
*test
;
1000 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "backupkey",
1001 &ndr_table_backupkey
);
1003 test
= torture_rpc_tcase_add_test(tcase
, "retreive_backup_key_guid",
1004 test_RetreiveBackupKeyGUID
);
1006 test
= torture_rpc_tcase_add_test(tcase
, "restore_guid",
1009 test
= torture_rpc_tcase_add_test(tcase
, "restore_guid version 3",
1010 test_RestoreGUID_v3
);
1012 /* We double the test in order to be sure that we don't mess stuff (ie. freeing static stuff */
1014 test
= torture_rpc_tcase_add_test(tcase
, "restore_guid_2nd",
1017 test
= torture_rpc_tcase_add_test(tcase
, "unable_to_decrypt_secret",
1018 test_RestoreGUID_ko
);
1020 test
= torture_rpc_tcase_add_test(tcase
, "wrong_user_restore_guid",
1021 test_RestoreGUID_wronguser
);
1023 test
= torture_rpc_tcase_add_test(tcase
, "wrong_version_restore_guid",
1024 test_RestoreGUID_wrongversion
);
1026 test
= torture_rpc_tcase_add_test(tcase
, "bad_magic_on_secret_restore_guid",
1027 test_RestoreGUID_badmagiconsecret
);
1029 test
= torture_rpc_tcase_add_test(tcase
, "bad_hash_on_secret_restore_guid",
1030 test_RestoreGUID_badhashaccesscheck
);
1032 test
= torture_rpc_tcase_add_test(tcase
, "bad_magic_on_accesscheck_restore_guid",
1033 test_RestoreGUID_badmagicaccesscheck
);
1035 test
= torture_rpc_tcase_add_test(tcase
, "bad_cert_guid_restore_guid",
1036 test_RestoreGUID_badcertguid
);
1038 test
= torture_rpc_tcase_add_test(tcase
, "empty_request_restore_guid",
1039 test_RestoreGUID_emptyrequest
);