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 "heimdal/lib/hx509/hx_locl.h"
30 /* Our very special and valued secret */
31 /* No need to put const as we cast the array in uint8_t
32 * we will get a warning about the discared const
34 static const char secret
[] = "tata yoyo mais qu'est ce qu'il y a sous ton grand chapeau ?";
36 /* Get the SID from a user */
37 static const struct dom_sid
*get_user_sid(struct torture_context
*tctx
,
38 struct dcerpc_pipe
*p
,
42 struct lsa_ObjectAttribute attr
;
43 struct lsa_QosInfo qos
;
44 struct lsa_OpenPolicy2 r
;
47 struct policy_handle handle
;
48 struct lsa_LookupNames l
;
49 struct lsa_TransSidArray sids
;
50 struct lsa_RefDomainList
*domains
= NULL
;
51 struct lsa_String lsa_name
;
53 struct dom_sid
*result
;
55 struct dcerpc_pipe
*p2
;
56 struct dcerpc_binding_handle
*b
;
58 const char *domain
= cli_credentials_get_domain(cmdline_credentials
);
60 torture_assert_ntstatus_ok(tctx
,
61 torture_rpc_connection(tctx
, &p2
, &ndr_table_lsarpc
),
62 "could not open lsarpc pipe");
63 b
= p2
->binding_handle
;
65 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
69 qos
.impersonation_level
= 2;
71 qos
.effective_only
= 0;
75 attr
.object_name
= NULL
;
80 r
.in
.system_name
= "\\";
82 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
83 r
.out
.handle
= &handle
;
85 status
= dcerpc_lsa_OpenPolicy2_r(b
, tmp_ctx
, &r
);
86 if (!NT_STATUS_IS_OK(status
)) {
88 "OpenPolicy2 failed - %s\n",
93 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
95 "OpenPolicy2_ failed - %s\n",
96 nt_errstr(r
.out
.result
));
104 lsa_name
.string
= talloc_asprintf(tmp_ctx
, "%s\\%s", domain
, user
);
106 l
.in
.handle
= &handle
;
108 l
.in
.names
= &lsa_name
;
112 l
.out
.count
= &count
;
114 l
.out
.domains
= &domains
;
116 status
= dcerpc_lsa_LookupNames_r(b
, tmp_ctx
, &l
);
117 if (!NT_STATUS_IS_OK(status
)) {
118 torture_comment(tctx
,
119 "LookupNames of %s failed - %s\n",
122 talloc_free(tmp_ctx
);
126 if (domains
->count
== 0) {
130 result
= dom_sid_add_rid(mem_ctx
,
131 domains
->domains
[0].sid
,
132 l
.out
.sids
->sids
[0].rid
);
133 c
.in
.handle
= &handle
;
134 c
.out
.handle
= &handle
;
136 status
= dcerpc_lsa_Close_r(b
, tmp_ctx
, &c
);
138 if (!NT_STATUS_IS_OK(status
)) {
139 torture_comment(tctx
,
140 "dcerpc_lsa_Close failed - %s\n",
142 talloc_free(tmp_ctx
);
146 if (!NT_STATUS_IS_OK(c
.out
.result
)) {
147 torture_comment(tctx
,
148 "dcerpc_lsa_Close failed - %s\n",
149 nt_errstr(c
.out
.result
));
150 talloc_free(tmp_ctx
);
154 talloc_free(tmp_ctx
);
157 torture_comment(tctx
, "Get_user_sid finished\n");
162 * Create a bkrp_encrypted_secret_vX structure
163 * the version depends on the version parameter
164 * the structure is returned as a blob.
165 * The broken flag is to indicate if we want
166 * to create a non conform to specification structre
168 static DATA_BLOB
*create_unencryptedsecret(TALLOC_CTX
*mem_ctx
,
172 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
173 DATA_BLOB
*blob
= talloc_zero(mem_ctx
, DATA_BLOB
);
174 enum ndr_err_code ndr_err
;
177 struct bkrp_encrypted_secret_v2 unenc_sec
;
179 ZERO_STRUCT(unenc_sec
);
180 unenc_sec
.secret_len
= sizeof(secret
);
181 unenc_sec
.secret
= discard_const_p(uint8_t, secret
);
182 generate_random_buffer(unenc_sec
.payload_key
,
183 sizeof(unenc_sec
.payload_key
));
185 ndr_err
= ndr_push_struct_blob(blob
, blob
, &unenc_sec
,
186 (ndr_push_flags_fn_t
)ndr_push_bkrp_encrypted_secret_v2
);
187 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
192 /* The magic value is correctly set by the NDR push
193 * but we want to test the behavior of the server
194 * if a differrent value is provided
196 ((uint8_t*)blob
->data
)[4] = 79; /* A great year !!! */
201 struct bkrp_encrypted_secret_v3 unenc_sec
;
203 ZERO_STRUCT(unenc_sec
);
204 unenc_sec
.secret_len
= sizeof(secret
);
205 unenc_sec
.secret
= discard_const_p(uint8_t, secret
);
206 generate_random_buffer(unenc_sec
.payload_key
,
207 sizeof(unenc_sec
.payload_key
));
209 ndr_err
= ndr_push_struct_blob(blob
, blob
, &unenc_sec
,
210 (ndr_push_flags_fn_t
)ndr_push_bkrp_encrypted_secret_v3
);
211 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
217 * The magic value is correctly set by the NDR push
218 * but we want to test the behavior of the server
219 * if a differrent value is provided
221 ((uint8_t*)blob
->data
)[4] = 79; /* A great year !!! */
224 talloc_free(tmp_ctx
);
229 * Create an access check structure, the format depends on the version parameter.
230 * If broken is specified then we create a stucture that isn't conform to the
233 * If the structure can't be created then NULL is returned.
235 static DATA_BLOB
*create_access_check(struct torture_context
*tctx
,
236 struct dcerpc_pipe
*p
,
242 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
243 DATA_BLOB
*blob
= talloc_zero(mem_ctx
, DATA_BLOB
);
244 enum ndr_err_code ndr_err
;
245 const struct dom_sid
*sid
= get_user_sid(tctx
, p
, tmp_ctx
, user
);
252 struct bkrp_access_check_v2 access_struct
;
256 ZERO_STRUCT(access_struct
);
257 generate_random_buffer(nonce
, sizeof(nonce
));
258 access_struct
.nonce_len
= sizeof(nonce
);
259 access_struct
.nonce
= nonce
;
260 access_struct
.sid
= *sid
;
262 ndr_err
= ndr_push_struct_blob(blob
, blob
, &access_struct
,
263 (ndr_push_flags_fn_t
)ndr_push_bkrp_access_check_v2
);
264 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
269 * We pushed the whole structure including a null hash
270 * but the hash need to be calculated only up to the hash field
271 * so we reduce the size of what has to be calculated
275 SHA1_Update(&sctx
, blob
->data
,
276 blob
->length
- sizeof(access_struct
.hash
));
277 SHA1_Final(blob
->data
+ blob
->length
- sizeof(access_struct
.hash
),
280 /* Altering the SHA */
282 blob
->data
[blob
->length
- 1]++;
287 struct bkrp_access_check_v3 access_struct
;
288 struct hc_sha512state sctx
;
291 ZERO_STRUCT(access_struct
);
292 generate_random_buffer(nonce
, sizeof(nonce
));
293 access_struct
.nonce_len
= sizeof(nonce
);
294 access_struct
.nonce
= nonce
;
295 access_struct
.sid
= *sid
;
297 ndr_err
= ndr_push_struct_blob(blob
, blob
, &access_struct
,
298 (ndr_push_flags_fn_t
)ndr_push_bkrp_access_check_v3
);
299 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
303 /*We pushed the whole structure including a null hash
304 * but the hash need to be calculated only up to the hash field
305 * so we reduce the size of what has to be calculated
309 SHA512_Update(&sctx
, blob
->data
,
310 blob
->length
- sizeof(access_struct
.hash
));
311 SHA512_Final(blob
->data
+ blob
->length
- sizeof(access_struct
.hash
),
314 /* Altering the SHA */
316 blob
->data
[blob
->length
-1]++;
319 talloc_free(tmp_ctx
);
324 static DATA_BLOB
*encrypt_blob(struct torture_context
*tctx
,
328 DATA_BLOB
*to_encrypt
,
329 const AlgorithmIdentifier
*alg
)
333 heim_octet_string ivos
;
334 heim_octet_string
*encrypted
;
335 DATA_BLOB
*blob
= talloc_zero(mem_ctx
, DATA_BLOB
);
338 ivos
.data
= talloc_array(mem_ctx
, uint8_t, iv
->length
);
339 ivos
.length
= iv
->length
;
340 memcpy(ivos
.data
, iv
->data
, iv
->length
);
342 hx509_context_init(&hctx
);
343 res
= hx509_crypto_init(hctx
, NULL
, &alg
->algorithm
, &crypto
);
345 torture_comment(tctx
,
346 "error while doing the init of the crypto object\n");
347 hx509_context_free(&hctx
);
350 res
= hx509_crypto_set_key_data(crypto
, key
->data
, key
->length
);
352 torture_comment(tctx
,
353 "error while setting the key of the crypto object\n");
354 hx509_context_free(&hctx
);
358 hx509_crypto_set_padding(crypto
, HX509_CRYPTO_PADDING_NONE
);
359 res
= hx509_crypto_encrypt(crypto
,
365 torture_comment(tctx
, "error while encrypting\n");
366 hx509_crypto_destroy(crypto
);
367 hx509_context_free(&hctx
);
371 *blob
= data_blob_talloc(blob
, encrypted
->data
, encrypted
->length
);
372 der_free_octet_string(encrypted
);
374 hx509_crypto_destroy(crypto
);
375 hx509_context_free(&hctx
);
380 * Certs used for this protocol have a GUID in the issuer_uniq_id field.
381 * This function fetch it.
383 static struct GUID
*get_cert_guid(struct torture_context
*tctx
,
390 heim_bit_string subjectuniqid
;
394 struct GUID
*guid
= talloc_zero(mem_ctx
, struct GUID
);
397 hx509_context_init(&hctx
);
399 hret
= hx509_cert_init_data(hctx
, cert_data
, cert_len
, &cert
);
401 torture_comment(tctx
, "error while loading the cert\n");
402 hx509_context_free(&hctx
);
405 hret
= hx509_cert_get_issuer_unique_id(hctx
, cert
, &subjectuniqid
);
407 torture_comment(tctx
, "error while getting the issuer_uniq_id\n");
408 hx509_cert_free(cert
);
409 hx509_context_free(&hctx
);
413 /* The subjectuniqid is a bit string,
414 * which means that the real size has to be divided by 8
415 * to have the number of bytes
417 hx509_cert_free(cert
);
418 hx509_context_free(&hctx
);
419 size
= subjectuniqid
.length
/ 8;
420 data
= data_blob_const(subjectuniqid
.data
, size
);
422 status
= GUID_from_data_blob(&data
, guid
);
423 der_free_bit_string(&subjectuniqid
);
424 if (!NT_STATUS_IS_OK(status
)) {
432 * Encrypt a blob with the private key of the certificate
433 * passed as a parameter.
435 static DATA_BLOB
*encrypt_blob_pk(struct torture_context
*tctx
,
439 DATA_BLOB
*to_encrypt
)
443 heim_octet_string secretdata
;
444 heim_octet_string encrypted
;
445 heim_oid encryption_oid
;
449 hx509_context_init(&hctx
);
451 hret
= hx509_cert_init_data(hctx
, cert_data
, cert_len
, &cert
);
453 torture_comment(tctx
, "error while loading the cert\n");
454 hx509_context_free(&hctx
);
458 secretdata
.data
= to_encrypt
->data
;
459 secretdata
.length
= to_encrypt
->length
;
460 hret
= hx509_cert_public_encrypt(hctx
, &secretdata
,
461 cert
, &encryption_oid
,
463 hx509_cert_free(cert
);
464 hx509_context_free(&hctx
);
466 torture_comment(tctx
, "error while encrypting\n");
470 blob
= talloc_zero(mem_ctx
, DATA_BLOB
);
472 der_free_oid(&encryption_oid
);
473 der_free_octet_string(&encrypted
);
477 *blob
= data_blob_talloc(blob
, encrypted
.data
, encrypted
.length
);
478 der_free_octet_string(&encrypted
);
479 der_free_oid(&encryption_oid
);
480 if (blob
->data
== NULL
) {
488 static struct bkrp_BackupKey
*createRetreiveBackupKeyGUIDStruct(struct torture_context
*tctx
,
489 struct dcerpc_pipe
*p
, int version
, DATA_BLOB
*out
)
491 struct dcerpc_binding
*binding
= p
->binding
;
492 struct bkrp_client_side_wrapped data
;
493 struct GUID
*g
= talloc(tctx
, struct GUID
);
494 struct bkrp_BackupKey
*r
= talloc_zero(tctx
, struct bkrp_BackupKey
);
495 enum ndr_err_code ndr_err
;
503 binding
->flags
= binding
->flags
& (DCERPC_SEAL
|DCERPC_AUTH_SPNEGO
);
505 status
= GUID_from_string(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID
, g
);
506 if (!NT_STATUS_IS_OK(status
)) {
510 r
->in
.guidActionAgent
= g
;
511 data
.version
= version
;
512 ndr_err
= ndr_push_struct_blob(&blob
, tctx
, &data
,
513 (ndr_push_flags_fn_t
)ndr_push_bkrp_client_side_wrapped
);
514 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
517 r
->in
.data_in
= blob
.data
;
518 r
->in
.data_in_len
= blob
.length
;
519 r
->out
.data_out
= &out
->data
;
520 r
->out
.data_out_len
= talloc(r
, uint32_t);
524 static struct bkrp_BackupKey
*createRestoreGUIDStruct(struct torture_context
*tctx
,
525 struct dcerpc_pipe
*p
, int version
, DATA_BLOB
*out
,
529 bool broken_magic_secret
,
530 bool broken_magic_access
,
531 bool broken_hash_access
,
532 bool broken_cert_guid
)
534 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
535 struct bkrp_client_side_wrapped data
;
541 DATA_BLOB enc_sec_reverted
;
546 struct GUID
*guid
, *g
;
549 enum ndr_err_code ndr_err
;
552 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, version
, &out_blob
);
558 /* we take a fake user*/
561 user
= cli_credentials_get_username(cmdline_credentials
);
565 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
568 * We have to set it outside of the function createRetreiveBackupKeyGUIDStruct
569 * the len of the blob, this is due to the fact that they don't have the
570 * same size (one is 32bits the other 64bits)
572 out_blob
.length
= *r
->out
.data_out_len
;
574 sec
= create_unencryptedsecret(tctx
, broken_magic_secret
, version
);
579 xs
= create_access_check(tctx
, p
, tctx
, user
, broken_hash_access
, version
);
584 if (broken_magic_access
){
585 /* The start of the access_check structure contains the
586 * GUID of the certificate
591 enc_sec
= encrypt_blob_pk(tctx
, tctx
, out_blob
.data
, out_blob
.length
, sec
);
595 enc_sec_reverted
.data
= talloc_array(tctx
, uint8_t, enc_sec
->length
);
596 if (enc_sec_reverted
.data
== NULL
) {
599 enc_sec_reverted
.length
= enc_sec
->length
;
602 * We DO NOT revert the array on purpose it's in order to check that
603 * when the server is not able to decrypt then it answer the correct error
606 for(t
=0; t
< enc_sec
->length
; t
++) {
607 enc_sec_reverted
.data
[t
] = ((uint8_t*)enc_sec
->data
)[t
];
610 for(t
=0; t
< enc_sec
->length
; t
++) {
611 enc_sec_reverted
.data
[t
] = ((uint8_t*)enc_sec
->data
)[enc_sec
->length
- t
-1];
617 const AlgorithmIdentifier
*alg
= hx509_crypto_des_rsdi_ede3_cbc();
618 iv
.data
= sec
->data
+(size
- 8);
621 des3_key
.data
= sec
->data
+(size
- 32);
622 des3_key
.length
= 24;
624 enc_xs
= encrypt_blob(tctx
, tctx
, &des3_key
, &iv
, xs
, alg
);
627 const AlgorithmIdentifier
*alg
= hx509_crypto_aes256_cbc();
628 iv
.data
= sec
->data
+(size
-16);
631 aes_key
.data
= sec
->data
+(size
-48);
634 enc_xs
= encrypt_blob(tctx
, tctx
, &aes_key
, &iv
, xs
, alg
);
641 /* To cope with the fact that heimdal do padding at the end for the moment */
642 enc_xs
->length
= xs
->length
;
644 guid
= get_cert_guid(tctx
, tctx
, out_blob
.data
, out_blob
.length
);
649 if (broken_version
) {
652 data
.version
= version
;
656 data
.encrypted_secret
= enc_sec_reverted
.data
;
657 data
.access_check
= enc_xs
->data
;
658 data
.encrypted_secret_len
= enc_sec
->length
;
659 data
.access_check_len
= enc_xs
->length
;
661 /* We want the blob to persist after this function so we don't
662 * allocate it in the stack
664 blob2
= talloc(tctx
, DATA_BLOB
);
669 ndr_err
= ndr_push_struct_blob(blob2
, tctx
, &data
,
670 (ndr_push_flags_fn_t
)ndr_push_bkrp_client_side_wrapped
);
671 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
675 if (broken_cert_guid
) {
681 g
= talloc(tctx
, struct GUID
);
686 status
= GUID_from_string(BACKUPKEY_RESTORE_GUID
, g
);
687 if (!NT_STATUS_IS_OK(status
)) {
691 r
->in
.guidActionAgent
= g
;
692 r
->in
.data_in
= blob2
->data
;
693 r
->in
.data_in_len
= blob2
->length
;
695 r
->out
.data_out
= &(out
->data
);
696 r
->out
.data_out_len
= talloc(r
, uint32_t);
700 /* Check that we are able to receive the certificate of the DCs
701 * used for client wrap version of the backup key protocol
703 static bool test_RetreiveBackupKeyGUID(struct torture_context
*tctx
,
704 struct dcerpc_pipe
*p
)
706 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
708 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
714 if (p
->conn
->security_state
.auth_info
!= NULL
&&
715 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
716 torture_assert_ntstatus_ok(tctx
,
717 dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
720 out_blob
.length
= *r
->out
.data_out_len
;
721 torture_assert_werr_equal(tctx
,
724 "Wrong dce/rpc error code");
726 torture_assert_ntstatus_equal(tctx
,
727 dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
728 NT_STATUS_ACCESS_DENIED
,
734 /* Test to check the failure to recover a secret because the
735 * secret blob is not reversed
737 static bool test_RestoreGUID_ko(struct torture_context
*tctx
,
738 struct dcerpc_pipe
*p
)
740 enum ndr_err_code ndr_err
;
741 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
743 struct bkrp_client_side_unwrapped resp
;
745 if (p
->conn
->security_state
.auth_info
!= NULL
&&
746 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
747 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
748 true, false, false, false, false, false, false);
749 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
750 out_blob
.length
= *r
->out
.data_out_len
;
751 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
752 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
753 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_DATA
, "Wrong error code");
755 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
756 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
757 NT_STATUS_ACCESS_DENIED
, "Get GUID");
762 static bool test_RestoreGUID_wrongversion(struct torture_context
*tctx
,
763 struct dcerpc_pipe
*p
)
765 enum ndr_err_code ndr_err
;
766 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
768 struct bkrp_client_side_unwrapped resp
;
770 if (p
->conn
->security_state
.auth_info
!= NULL
&&
771 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
772 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
773 false, true, false, false, false, false, false);
774 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
775 out_blob
.length
= *r
->out
.data_out_len
;
776 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
777 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
778 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_PARAM
, "Wrong error code on wrong version");
780 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
781 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
782 NT_STATUS_ACCESS_DENIED
, "Get GUID");
787 static bool test_RestoreGUID_wronguser(struct torture_context
*tctx
,
788 struct dcerpc_pipe
*p
)
790 enum ndr_err_code ndr_err
;
791 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
793 struct bkrp_client_side_unwrapped resp
;
795 if (p
->conn
->security_state
.auth_info
!= NULL
&&
796 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
797 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
798 false, false, true, false, false, false, false);
799 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
800 out_blob
.length
= *r
->out
.data_out_len
;
801 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
802 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
803 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_ACCESS
, "Restore GUID");
805 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
806 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
807 NT_STATUS_ACCESS_DENIED
, "Get GUID");
812 static bool test_RestoreGUID_v3(struct torture_context
*tctx
,
813 struct dcerpc_pipe
*p
)
815 enum ndr_err_code ndr_err
;
816 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
818 struct bkrp_client_side_unwrapped resp
;
820 if (p
->conn
->security_state
.auth_info
!= NULL
&&
821 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
822 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 3, &out_blob
,
823 false, false, false, false, false, false, false);
824 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
825 out_blob
.length
= *r
->out
.data_out_len
;
826 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
827 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 1, "Unable to unmarshall bkrp_client_side_unwrapped");
828 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_OK
, "Restore GUID");
829 torture_assert_str_equal(tctx
, (char*)resp
.secret
.data
, secret
, "Wrong secret");
831 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
832 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
833 NT_STATUS_ACCESS_DENIED
, "Get GUID");
838 static bool test_RestoreGUID(struct torture_context
*tctx
,
839 struct dcerpc_pipe
*p
)
841 enum ndr_err_code ndr_err
;
842 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
844 struct bkrp_client_side_unwrapped resp
;
846 if (p
->conn
->security_state
.auth_info
!= NULL
&&
847 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
848 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
849 false, false, false, false, false, false, false);
850 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
851 out_blob
.length
= *r
->out
.data_out_len
;
852 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
853 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 1, "Unable to unmarshall bkrp_client_side_unwrapped");
854 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_OK
, "Restore GUID");
855 torture_assert_str_equal(tctx
, (char*)resp
.secret
.data
, secret
, "Wrong secret");
857 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
858 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
859 NT_STATUS_ACCESS_DENIED
, "Get GUID");
864 static bool test_RestoreGUID_badmagiconsecret(struct torture_context
*tctx
,
865 struct dcerpc_pipe
*p
)
867 enum ndr_err_code ndr_err
;
868 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
870 struct bkrp_client_side_unwrapped resp
;
872 if (p
->conn
->security_state
.auth_info
!= NULL
&&
873 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
874 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 3, &out_blob
,
875 false, false, false, true, false, false, false);
876 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
877 out_blob
.length
= *r
->out
.data_out_len
;
878 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
879 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
880 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_DATA
, "Wrong error code while providing bad magic in secret");
882 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
883 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
884 NT_STATUS_ACCESS_DENIED
, "Get GUID");
889 static bool test_RestoreGUID_emptyrequest(struct torture_context
*tctx
,
890 struct dcerpc_pipe
*p
)
892 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
895 if (p
->conn
->security_state
.auth_info
!= NULL
&&
896 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
897 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 3, &out_blob
,
898 false, false, false, true, false, false, true);
900 torture_assert_int_equal(tctx
, r
!= NULL
, 1, "Error while creating the restoreGUID struct");
901 r
->in
.data_in
= talloc(tctx
, uint8_t);
902 r
->in
.data_in_len
= 0;
904 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
905 out_blob
.length
= *r
->out
.data_out_len
;
906 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_PARAM
, "Bad error code on wrong has in access check");
908 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
909 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
910 NT_STATUS_ACCESS_DENIED
, "Get GUID");
915 static bool test_RestoreGUID_badcertguid(struct torture_context
*tctx
,
916 struct dcerpc_pipe
*p
)
918 enum ndr_err_code ndr_err
;
919 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
921 struct bkrp_client_side_unwrapped resp
;
923 if (p
->conn
->security_state
.auth_info
!= NULL
&&
924 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
925 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 3, &out_blob
,
926 false, false, false, false, false, false, true);
927 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
928 out_blob
.length
= *r
->out
.data_out_len
;
929 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
930 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
931 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_FILE_NOT_FOUND
, "Bad error code on wrong has in access check");
933 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
934 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
935 NT_STATUS_ACCESS_DENIED
, "Get GUID");
940 static bool test_RestoreGUID_badmagicaccesscheck(struct torture_context
*tctx
,
941 struct dcerpc_pipe
*p
)
943 enum ndr_err_code ndr_err
;
944 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
946 struct bkrp_client_side_unwrapped resp
;
948 if (p
->conn
->security_state
.auth_info
!= NULL
&&
949 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
950 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
951 false, false, false, false, true, false, false);
952 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
953 out_blob
.length
= *r
->out
.data_out_len
;
954 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
955 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
956 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_DATA
, "Bad error code on wrong has in access check");
958 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
959 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
960 NT_STATUS_ACCESS_DENIED
, "Get GUID");
965 static bool test_RestoreGUID_badhashaccesscheck(struct torture_context
*tctx
,
966 struct dcerpc_pipe
*p
)
968 enum ndr_err_code ndr_err
;
969 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
971 struct bkrp_client_side_unwrapped resp
;
973 if (p
->conn
->security_state
.auth_info
!= NULL
&&
974 p
->conn
->security_state
.auth_info
->auth_level
== 6) {
975 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
976 false, false, false, false, false, true, false);
977 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
978 out_blob
.length
= *r
->out
.data_out_len
;
979 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
980 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
981 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_DATA
, "Bad error code on wrong has in access check");
983 struct bkrp_BackupKey
*r
= createRetreiveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
984 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
985 NT_STATUS_ACCESS_DENIED
, "Get GUID");
990 struct torture_suite
*torture_rpc_backupkey(TALLOC_CTX
*mem_ctx
)
992 struct torture_rpc_tcase
*tcase
;
993 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "backupkey");
994 struct torture_test
*test
;
996 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "backupkey",
997 &ndr_table_backupkey
);
999 test
= torture_rpc_tcase_add_test(tcase
, "retreive_backup_key_guid",
1000 test_RetreiveBackupKeyGUID
);
1002 test
= torture_rpc_tcase_add_test(tcase
, "restore_guid",
1005 test
= torture_rpc_tcase_add_test(tcase
, "restore_guid version 3",
1006 test_RestoreGUID_v3
);
1008 /* We double the test in order to be sure that we don't mess stuff (ie. freeing static stuff */
1010 test
= torture_rpc_tcase_add_test(tcase
, "restore_guid_2nd",
1013 test
= torture_rpc_tcase_add_test(tcase
, "unable_to_decrypt_secret",
1014 test_RestoreGUID_ko
);
1016 test
= torture_rpc_tcase_add_test(tcase
, "wrong_user_restore_guid",
1017 test_RestoreGUID_wronguser
);
1019 test
= torture_rpc_tcase_add_test(tcase
, "wrong_version_restore_guid",
1020 test_RestoreGUID_wrongversion
);
1022 test
= torture_rpc_tcase_add_test(tcase
, "bad_magic_on_secret_restore_guid",
1023 test_RestoreGUID_badmagiconsecret
);
1025 test
= torture_rpc_tcase_add_test(tcase
, "bad_hash_on_secret_restore_guid",
1026 test_RestoreGUID_badhashaccesscheck
);
1028 test
= torture_rpc_tcase_add_test(tcase
, "bad_magic_on_accesscheck_restore_guid",
1029 test_RestoreGUID_badmagicaccesscheck
);
1031 test
= torture_rpc_tcase_add_test(tcase
, "bad_cert_guid_restore_guid",
1032 test_RestoreGUID_badcertguid
);
1034 test
= torture_rpc_tcase_add_test(tcase
, "empty_request_restore_guid",
1035 test_RestoreGUID_emptyrequest
);