2 Unix SMB/CIFS implementation.
4 msDS-IntId attribute replication test.
6 Copyright (C) Kamen Mazdrashki <kamenim@samba.org> 2010
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "lib/cmdline/popt_common.h"
24 #include "librpc/gen_ndr/ndr_drsuapi_c.h"
25 #include "librpc/gen_ndr/ndr_drsblobs.h"
26 #include "libcli/cldap/cldap.h"
27 #include "torture/torture.h"
28 #include "../libcli/drsuapi/drsuapi.h"
29 #include "auth/gensec/gensec.h"
30 #include "param/param.h"
31 #include "dsdb/samdb/samdb.h"
32 #include "torture/rpc/torture_rpc.h"
33 #include "torture/drs/proto.h"
34 #include "lib/tsocket/tsocket.h"
35 #include "libcli/resolve/resolve.h"
37 struct DsSyncBindInfo
{
38 struct dcerpc_pipe
*drs_pipe
;
39 struct dcerpc_binding_handle
*drs_handle
;
40 struct drsuapi_DsBind req
;
41 struct GUID bind_guid
;
42 struct drsuapi_DsBindInfoCtr our_bind_info_ctr
;
43 struct drsuapi_DsBindInfo28 our_bind_info28
;
44 struct drsuapi_DsBindInfo28 peer_bind_info28
;
45 struct policy_handle bind_handle
;
49 struct dcerpc_binding
*server_binding
;
51 struct dcerpc_pipe
*drs_pipe
;
52 struct dcerpc_binding_handle
*drs_handle
;
54 DATA_BLOB gensec_skey
;
55 struct drsuapi_DsBindInfo48 srv_info48
;
56 struct policy_handle rpc_handle
;
59 struct DsIntIdTestCtx
{
61 const char *domain_dn
;
62 const char *config_dn
;
63 const char *schema_dn
;
65 /* what we need to do as 'Administrator' */
66 struct cli_credentials
*creds
;
67 struct DsaBindInfo dsa_bind
;
68 struct ldb_context
*ldb
;
72 /* Format string to create provision LDIF with */
73 #define PROVISION_LDIF_FMT \
74 "###########################################################\n" \
75 "# Format string with positional params:\n" \
76 "# 1 - (int) Unique ID between 1 and 2^16\n" \
77 "# 2 - (string) Domain DN\n" \
78 "###########################################################\n" \
80 "###########################################################\n" \
82 "###########################################################\n" \
83 "dn: CN=msds-intid-%1$d,CN=Schema,CN=Configuration,%2$s\n" \
85 "objectClass: top\n" \
86 "objectClass: attributeSchema\n" \
87 "cn: msds-intid-%1$d\n" \
88 "attributeID: 1.2.840.%1$d.1.5.9940\n" \
89 "attributeSyntax: 2.5.5.10\n" \
92 "isSingleValued: TRUE\n" \
93 "systemOnly: FALSE\n" \
95 "# schemaUpdateNow\n" \
97 "changeType: modify\n" \
98 "add: schemaUpdateNow\n" \
99 "schemaUpdateNow: 1\n" \
102 "###########################################################\n" \
103 "# Update User class\n" \
104 "###########################################################\n" \
105 "dn: CN=User,CN=Schema,CN=Configuration,%2$s\n" \
106 "changetype: modify\n" \
107 "add: mayContain\n" \
108 "mayContain: msdsIntid%1$d\n" \
111 "# schemaUpdateNow\n" \
113 "changeType: modify\n" \
114 "add: schemaUpdateNow\n" \
115 "schemaUpdateNow: 1\n" \
118 "###########################################################\n" \
119 "# create user to test with\n" \
120 "###########################################################\n" \
121 "dn: CN=dsIntId_usr_%1$d,CN=Users,%2$s\n" \
122 "changetype: add\n" \
123 "objectClass: user\n" \
124 "cn: dsIntId_usr_%1$d\n" \
125 "name: dsIntId_usr_%1$d\n" \
126 "displayName: dsIntId_usr_%1$d\n" \
127 "sAMAccountName: dsIntId_usr_%1$d\n" \
128 "msdsIntid%1$d: msDS-IntId-%1$d attribute value\n" \
132 static struct DsIntIdTestCtx
*_dsintid_create_context(struct torture_context
*tctx
)
135 struct DsIntIdTestCtx
*ctx
;
136 struct dcerpc_binding
*server_binding
;
137 const char *binding
= torture_setting_string(tctx
, "binding", NULL
);
139 /* Create test suite context */
140 ctx
= talloc_zero(tctx
, struct DsIntIdTestCtx
);
142 torture_result(tctx
, TORTURE_FAIL
, "Not enough memory!");
146 /* parse binding object */
147 status
= dcerpc_parse_binding(ctx
, binding
, &server_binding
);
148 if (!NT_STATUS_IS_OK(status
)) {
149 torture_result(tctx
, TORTURE_FAIL
,
150 "Bad binding string '%s': %s", binding
, nt_errstr(status
));
154 server_binding
->flags
|= DCERPC_SIGN
| DCERPC_SEAL
;
156 /* populate test suite context */
157 ctx
->creds
= cmdline_credentials
;
158 ctx
->dsa_bind
.server_binding
= server_binding
;
160 ctx
->ldap_url
= talloc_asprintf(ctx
, "ldap://%s", server_binding
->host
);
165 static bool _test_DsaBind(struct torture_context
*tctx
,
167 struct cli_credentials
*credentials
,
168 uint32_t req_extensions
,
169 struct DsaBindInfo
*bi
)
172 struct GUID bind_guid
;
173 struct drsuapi_DsBind r
;
174 struct drsuapi_DsBindInfoCtr bind_info_ctr
;
175 uint32_t supported_extensions
;
177 /* make DCE RPC connection */
178 status
= dcerpc_pipe_connect_b(mem_ctx
,
182 credentials
, tctx
->ev
, tctx
->lp_ctx
);
183 torture_assert_ntstatus_ok(tctx
, status
, "Failed to connect to server");
185 bi
->drs_handle
= bi
->drs_pipe
->binding_handle
;
187 status
= gensec_session_key(bi
->drs_pipe
->conn
->security_state
.generic_state
,
188 mem_ctx
, &bi
->gensec_skey
);
189 torture_assert_ntstatus_ok(tctx
, status
, "failed to get gensec session key");
191 /* Bind to DRSUAPI interface */
192 GUID_from_string(DRSUAPI_DS_BIND_GUID_W2K3
, &bind_guid
);
195 * Add flags that should be 1, according to MS docs.
196 * It turns out DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3
197 * is actually required in order for GetNCChanges() to
198 * return schemaInfo entry in the prefixMap returned.
199 * Use DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION so
200 * we are able to fetch sensitive data.
202 supported_extensions
= req_extensions
203 | DRSUAPI_SUPPORTED_EXTENSION_BASE
204 | DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATION
205 | DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MOD
206 | DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3
207 | DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION
;
209 ZERO_STRUCT(bind_info_ctr
);
210 bind_info_ctr
.length
= 28;
211 bind_info_ctr
.info
.info28
.supported_extensions
= supported_extensions
;
213 r
.in
.bind_guid
= &bind_guid
;
214 r
.in
.bind_info
= &bind_info_ctr
;
215 r
.out
.bind_handle
= &bi
->rpc_handle
;
217 status
= dcerpc_drsuapi_DsBind_r(bi
->drs_handle
, mem_ctx
, &r
);
218 torture_drsuapi_assert_call(tctx
, bi
->drs_pipe
, status
,
219 &r
, "dcerpc_drsuapi_DsBind_r");
222 switch (r
.out
.bind_info
->length
) {
224 struct drsuapi_DsBindInfo24
*info24
;
225 info24
= &r
.out
.bind_info
->info
.info24
;
226 bi
->srv_info48
.supported_extensions
= info24
->supported_extensions
;
227 bi
->srv_info48
.site_guid
= info24
->site_guid
;
228 bi
->srv_info48
.pid
= info24
->pid
;
232 struct drsuapi_DsBindInfo28
*info28
;
233 info28
= &r
.out
.bind_info
->info
.info28
;
234 bi
->srv_info48
.supported_extensions
= info28
->supported_extensions
;
235 bi
->srv_info48
.site_guid
= info28
->site_guid
;
236 bi
->srv_info48
.pid
= info28
->pid
;
237 bi
->srv_info48
.repl_epoch
= info28
->repl_epoch
;
241 bi
->srv_info48
= r
.out
.bind_info
->info
.info48
;
244 torture_result(tctx
, TORTURE_FAIL
,
245 "DsBind: unknown BindInfo length: %u",
246 r
.out
.bind_info
->length
);
250 /* check if server supports extensions we've requested */
251 if ((bi
->srv_info48
.supported_extensions
& req_extensions
) != req_extensions
) {
252 torture_result(tctx
, TORTURE_FAIL
,
253 "Server does not support requested extensions. "
254 "Requested: 0x%08X, Supported: 0x%08X",
255 req_extensions
, bi
->srv_info48
.supported_extensions
);
262 static bool _test_LDAPBind(struct torture_context
*tctx
,
264 struct cli_credentials
*credentials
,
265 const char *ldap_url
,
266 struct ldb_context
**_ldb
)
270 struct ldb_context
*ldb
;
272 const char *modules_option
[] = { "modules:paged_searches", NULL
};
273 ldb
= ldb_init(mem_ctx
, tctx
->ev
);
278 /* Despite us loading the schema from the AD server, we need
279 * the samba handlers to get the extended DN syntax stuff */
280 ret
= ldb_register_samba_handlers(ldb
);
281 if (ret
!= LDB_SUCCESS
) {
286 ldb_set_modules_dir(ldb
, modules_path(ldb
, "ldb"));
288 if (ldb_set_opaque(ldb
, "credentials", credentials
) != LDB_SUCCESS
) {
293 if (ldb_set_opaque(ldb
, "loadparm", tctx
->lp_ctx
) != LDB_SUCCESS
) {
298 ret
= ldb_connect(ldb
, ldap_url
, 0, modules_option
);
299 if (ret
!= LDB_SUCCESS
) {
301 torture_assert_int_equal(tctx
, ret
, LDB_SUCCESS
, "Failed to make LDB connection to target");
309 static bool _test_provision(struct torture_context
*tctx
, struct DsIntIdTestCtx
*ctx
)
314 struct ldb_ldif
*ldif
;
316 struct ldb_context
*ldb
= ctx
->ldb
;
318 /* We must have LDB connection ready by this time */
319 SMB_ASSERT(ldb
!= NULL
);
321 ctx
->domain_dn
= ldb_dn_get_linearized(ldb_get_default_basedn(ldb
));
322 torture_assert(tctx
, ctx
->domain_dn
!= NULL
, "Failed to get Domain DN");
324 ctx
->config_dn
= ldb_dn_get_linearized(ldb_get_config_basedn(ldb
));
325 torture_assert(tctx
, ctx
->config_dn
!= NULL
, "Failed to get Domain DN");
327 ctx
->schema_dn
= ldb_dn_get_linearized(ldb_get_schema_basedn(ldb
));
328 torture_assert(tctx
, ctx
->schema_dn
!= NULL
, "Failed to get Domain DN");
330 /* prepare LDIF to provision with */
331 attr_id
= generate_random() % 0xFFFF;
332 pstr
= ldif_str
= talloc_asprintf(ctx
, PROVISION_LDIF_FMT
,
333 attr_id
, ctx
->domain_dn
);
335 /* Provision test data */
336 while ((ldif
= ldb_ldif_read_string(ldb
, &pstr
)) != NULL
) {
337 switch (ldif
->changetype
) {
338 case LDB_CHANGETYPE_DELETE
:
339 ret
= ldb_delete(ldb
, ldif
->msg
->dn
);
341 case LDB_CHANGETYPE_MODIFY
:
342 ret
= ldb_modify(ldb
, ldif
->msg
);
344 case LDB_CHANGETYPE_ADD
:
346 ret
= ldb_add(ldb
, ldif
->msg
);
349 if (ret
!= LDB_SUCCESS
) {
350 char *msg
= talloc_asprintf(ctx
,
351 "Failed to apply ldif - %s (%s): \n%s",
354 ldb_ldif_write_string(ldb
, ctx
, ldif
));
355 torture_fail(tctx
, msg
);
358 ldb_ldif_read_free(ldb
, ldif
);
365 static bool _test_GetNCChanges(struct torture_context
*tctx
,
366 struct DsaBindInfo
*bi
,
367 const char *nc_dn_str
,
369 struct drsuapi_DsGetNCChangesCtr6
**_ctr6
)
372 struct drsuapi_DsGetNCChanges r
;
373 union drsuapi_DsGetNCChangesRequest req
;
374 struct drsuapi_DsReplicaObjectIdentifier nc
;
375 struct drsuapi_DsGetNCChangesCtr6
*ctr6_chunk
= NULL
;
376 struct drsuapi_DsGetNCChangesCtr6 ctr6
;
378 union drsuapi_DsGetNCChangesCtr ctr
;
380 struct dom_sid null_sid
;
382 ZERO_STRUCT(null_sid
);
384 /* fill-in Naming Context */
385 nc
.guid
= GUID_zero();
389 /* fill-in request fields */
390 req
.req8
.destination_dsa_guid
= GUID_random();
391 req
.req8
.source_dsa_invocation_id
= GUID_zero();
392 req
.req8
.naming_context
= &nc
;
393 req
.req8
.highwatermark
.tmp_highest_usn
= 0;
394 req
.req8
.highwatermark
.reserved_usn
= 0;
395 req
.req8
.highwatermark
.highest_usn
= 0;
396 req
.req8
.uptodateness_vector
= NULL
;
397 req
.req8
.replica_flags
= DRSUAPI_DRS_WRIT_REP
398 | DRSUAPI_DRS_INIT_SYNC
399 | DRSUAPI_DRS_PER_SYNC
400 | DRSUAPI_DRS_GET_ANC
401 | DRSUAPI_DRS_NEVER_SYNCED
403 req
.req8
.max_object_count
= 402;
404 req
.req8
.max_ndr_size
= 402116;
406 req
.req8
.extended_op
= DRSUAPI_EXOP_NONE
;
407 req
.req8
.fsmo_info
= 0;
408 req
.req8
.partial_attribute_set
= NULL
;
409 req
.req8
.partial_attribute_set_ex
= NULL
;
410 req
.req8
.mapping_ctr
.num_mappings
= 0;
411 req
.req8
.mapping_ctr
.mappings
= NULL
;
413 r
.in
.bind_handle
= &bi
->rpc_handle
;
418 r
.out
.level_out
= &_level
;
425 status
= dcerpc_drsuapi_DsGetNCChanges_r(bi
->drs_handle
, mem_ctx
, &r
);
426 torture_drsuapi_assert_call(tctx
, bi
->drs_pipe
, status
,
427 &r
, "dcerpc_drsuapi_DsGetNCChanges_r");
429 /* we expect to get level 6 reply */
430 torture_assert_int_equal(tctx
, _level
, 6, "Expected level 6 reply");
432 /* store this chunk for later use */
433 ctr6_chunk
= &r
.out
.ctr
->ctr6
;
435 if (!ctr6
.first_object
) {
438 struct drsuapi_DsReplicaObjectListItemEx
*cur
;
440 ctr6
.object_count
+= ctr6_chunk
->object_count
;
441 for (cur
= ctr6
.first_object
; cur
->next_object
; cur
= cur
->next_object
) {}
442 cur
->next_object
= ctr6_chunk
->first_object
;
444 /* TODO: store the chunk of linked_attributes if needed */
447 /* prepare for next request */
448 r
.in
.req
->req8
.highwatermark
= ctr6_chunk
->new_highwatermark
;
450 } while (ctr6_chunk
->more_data
);
452 *_ctr6
= talloc(mem_ctx
, struct drsuapi_DsGetNCChangesCtr6
);
453 torture_assert(mem_ctx
, *_ctr6
, "Not enough memory");
459 static char * _make_error_message(TALLOC_CTX
*mem_ctx
,
460 enum drsuapi_DsAttributeId drs_attid
,
461 const struct dsdb_attribute
*dsdb_attr
,
462 const struct drsuapi_DsReplicaObjectIdentifier
*identifier
)
464 return talloc_asprintf(mem_ctx
, "\nInvalid ATTID for %1$s (%2$s)\n"
465 " drs_attid: %3$11d (0x%3$08X)\n"
466 " msDS_IntId: %4$11d (0x%4$08X)\n"
467 " attributeId_id: %5$11d (0x%5$08X)",
468 dsdb_attr
->lDAPDisplayName
,
471 dsdb_attr
->msDS_IntId
,
472 dsdb_attr
->attributeID_id
);
476 * Fetch Schema NC and check ATTID values returned.
477 * When Schema partition is replicated, ATTID
478 * should always be made using prefixMap
480 static bool test_dsintid_schema(struct torture_context
*tctx
, struct DsIntIdTestCtx
*ctx
)
483 const struct dsdb_schema
*ldap_schema
;
484 struct drsuapi_DsGetNCChangesCtr6
*ctr6
= NULL
;
485 const struct dsdb_attribute
*dsdb_attr
;
486 const struct drsuapi_DsReplicaAttribute
*drs_attr
;
487 const struct drsuapi_DsReplicaAttributeCtr
*attr_ctr
;
488 const struct drsuapi_DsReplicaObjectListItemEx
*cur
;
489 const struct drsuapi_DsReplicaLinkedAttribute
*la
;
492 mem_ctx
= talloc_new(ctx
);
493 torture_assert(tctx
, mem_ctx
, "Not enough memory");
495 /* fetch whole Schema partition */
496 torture_comment(tctx
, "Fetch partition: %s\n", ctx
->schema_dn
);
497 if (!_test_GetNCChanges(tctx
, &ctx
->dsa_bind
, ctx
->schema_dn
, mem_ctx
, &ctr6
)) {
498 torture_fail(tctx
, "_test_GetNCChanges() failed");
501 /* load schema if not loaded yet */
502 torture_comment(tctx
, "Loading schema...\n");
503 if (!drs_util_dsdb_schema_load_ldb(tctx
, ctx
->ldb
, &ctr6
->mapping_ctr
, false)) {
504 torture_fail(tctx
, "drs_util_dsdb_schema_load_ldb() failed");
506 ldap_schema
= dsdb_get_schema(ctx
->ldb
, NULL
);
508 /* verify ATTIDs fetched */
509 torture_comment(tctx
, "Verify ATTIDs fetched\n");
510 for (cur
= ctr6
->first_object
; cur
; cur
= cur
->next_object
) {
511 attr_ctr
= &cur
->object
.attribute_ctr
;
512 for (i
= 0; i
< attr_ctr
->num_attributes
; i
++) {
513 drs_attr
= &attr_ctr
->attributes
[i
];
514 dsdb_attr
= dsdb_attribute_by_attributeID_id(ldap_schema
,
518 drs_attr
->attid
== dsdb_attr
->attributeID_id
,
519 _make_error_message(ctx
, drs_attr
->attid
,
521 cur
->object
.identifier
));
522 if (dsdb_attr
->msDS_IntId
) {
524 drs_attr
->attid
!= dsdb_attr
->msDS_IntId
,
525 _make_error_message(ctx
, drs_attr
->attid
,
527 cur
->object
.identifier
));
532 /* verify ATTIDs for Linked Attributes */
533 torture_comment(tctx
, "Verify ATTIDs for Linked Attributes (%u)\n",
534 ctr6
->linked_attributes_count
);
535 for (i
= 0; i
< ctr6
->linked_attributes_count
; i
++) {
536 la
= &ctr6
->linked_attributes
[i
];
537 dsdb_attr
= dsdb_attribute_by_attributeID_id(ldap_schema
, la
->attid
);
540 la
->attid
== dsdb_attr
->attributeID_id
,
541 _make_error_message(ctx
, la
->attid
,
544 if (dsdb_attr
->msDS_IntId
) {
546 la
->attid
!= dsdb_attr
->msDS_IntId
,
547 _make_error_message(ctx
, la
->attid
,
553 talloc_free(mem_ctx
);
559 * Fetch non-Schema NC and check ATTID values returned.
560 * When non-Schema partition is replicated, ATTID
561 * should be msDS-IntId value for the attribute
562 * if this value exists
564 static bool _test_dsintid(struct torture_context
*tctx
,
565 struct DsIntIdTestCtx
*ctx
,
566 const char *nc_dn_str
)
569 const struct dsdb_schema
*ldap_schema
;
570 struct drsuapi_DsGetNCChangesCtr6
*ctr6
= NULL
;
571 const struct dsdb_attribute
*dsdb_attr
;
572 const struct drsuapi_DsReplicaAttribute
*drs_attr
;
573 const struct drsuapi_DsReplicaAttributeCtr
*attr_ctr
;
574 const struct drsuapi_DsReplicaObjectListItemEx
*cur
;
575 const struct drsuapi_DsReplicaLinkedAttribute
*la
;
578 mem_ctx
= talloc_new(ctx
);
579 torture_assert(tctx
, mem_ctx
, "Not enough memory");
581 /* fetch whole Schema partition */
582 torture_comment(tctx
, "Fetch partition: %s\n", nc_dn_str
);
583 if (!_test_GetNCChanges(tctx
, &ctx
->dsa_bind
, nc_dn_str
, mem_ctx
, &ctr6
)) {
584 torture_fail(tctx
, "_test_GetNCChanges() failed");
587 /* load schema if not loaded yet */
588 torture_comment(tctx
, "Loading schema...\n");
589 if (!drs_util_dsdb_schema_load_ldb(tctx
, ctx
->ldb
, &ctr6
->mapping_ctr
, false)) {
590 torture_fail(tctx
, "drs_util_dsdb_schema_load_ldb() failed");
592 ldap_schema
= dsdb_get_schema(ctx
->ldb
, NULL
);
594 /* verify ATTIDs fetched */
595 torture_comment(tctx
, "Verify ATTIDs fetched\n");
596 for (cur
= ctr6
->first_object
; cur
; cur
= cur
->next_object
) {
597 attr_ctr
= &cur
->object
.attribute_ctr
;
598 for (i
= 0; i
< attr_ctr
->num_attributes
; i
++) {
599 drs_attr
= &attr_ctr
->attributes
[i
];
600 dsdb_attr
= dsdb_attribute_by_attributeID_id(ldap_schema
,
602 if (dsdb_attr
->msDS_IntId
) {
604 drs_attr
->attid
== dsdb_attr
->msDS_IntId
,
605 _make_error_message(ctx
, drs_attr
->attid
,
607 cur
->object
.identifier
));
610 drs_attr
->attid
== dsdb_attr
->attributeID_id
,
611 _make_error_message(ctx
, drs_attr
->attid
,
613 cur
->object
.identifier
));
618 /* verify ATTIDs for Linked Attributes */
619 torture_comment(tctx
, "Verify ATTIDs for Linked Attributes (%u)\n",
620 ctr6
->linked_attributes_count
);
621 for (i
= 0; i
< ctr6
->linked_attributes_count
; i
++) {
622 la
= &ctr6
->linked_attributes
[i
];
623 dsdb_attr
= dsdb_attribute_by_attributeID_id(ldap_schema
, la
->attid
);
625 if (dsdb_attr
->msDS_IntId
) {
627 la
->attid
== dsdb_attr
->msDS_IntId
,
628 _make_error_message(ctx
, la
->attid
,
633 la
->attid
== dsdb_attr
->attributeID_id
,
634 _make_error_message(ctx
, la
->attid
,
640 talloc_free(mem_ctx
);
646 * Fetch Domain NC and check ATTID values returned.
647 * When Domain partition is replicated, ATTID
648 * should be msDS-IntId value for the attribute
649 * if this value exists
651 static bool test_dsintid_configuration(struct torture_context
*tctx
, struct DsIntIdTestCtx
*ctx
)
653 return _test_dsintid(tctx
, ctx
, ctx
->config_dn
);
657 * Fetch Configuration NC and check ATTID values returned.
658 * When Configuration partition is replicated, ATTID
659 * should be msDS-IntId value for the attribute
660 * if this value exists
662 static bool test_dsintid_domain(struct torture_context
*tctx
, struct DsIntIdTestCtx
*ctx
)
664 return _test_dsintid(tctx
, ctx
, ctx
->domain_dn
);
669 * DSSYNC test case setup
671 static bool torture_dsintid_tcase_setup(struct torture_context
*tctx
, void **data
)
674 struct DsIntIdTestCtx
*ctx
;
676 *data
= ctx
= _dsintid_create_context(tctx
);
677 torture_assert(tctx
, ctx
, "test_create_context() failed");
679 bret
= _test_DsaBind(tctx
, ctx
, ctx
->creds
,
680 DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8
|
681 DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V6
,
683 torture_assert(tctx
, bret
, "_test_DsaBind() failed");
685 bret
= _test_LDAPBind(tctx
, ctx
, ctx
->creds
, ctx
->ldap_url
, &ctx
->ldb
);
686 torture_assert(tctx
, bret
, "_test_LDAPBind() failed");
688 bret
= _test_provision(tctx
, ctx
);
689 torture_assert(tctx
, bret
, "_test_provision() failed");
695 * DSSYNC test case cleanup
697 static bool torture_dsintid_tcase_teardown(struct torture_context
*tctx
, void *data
)
699 struct DsIntIdTestCtx
*ctx
;
700 struct drsuapi_DsUnbind r
;
701 struct policy_handle bind_handle
;
703 ctx
= talloc_get_type(data
, struct DsIntIdTestCtx
);
706 r
.out
.bind_handle
= &bind_handle
;
708 /* Release DRSUAPI handle */
709 r
.in
.bind_handle
= &ctx
->dsa_bind
.rpc_handle
;
710 dcerpc_drsuapi_DsUnbind_r(ctx
->dsa_bind
.drs_handle
, ctx
, &r
);
718 * DSSYNC test case implementation
720 void torture_drs_rpc_dsintid_tcase(struct torture_suite
*suite
)
722 typedef bool (*run_func
) (struct torture_context
*test
, void *tcase_data
);
724 struct torture_test
*test
;
725 struct torture_tcase
*tcase
= torture_suite_add_tcase(suite
, "msDSIntId");
727 torture_tcase_set_fixture(tcase
,
728 torture_dsintid_tcase_setup
,
729 torture_dsintid_tcase_teardown
);
731 test
= torture_tcase_add_simple_test(tcase
, "Schema", (run_func
)test_dsintid_schema
);
732 test
= torture_tcase_add_simple_test(tcase
, "Configuration", (run_func
)test_dsintid_configuration
);
733 test
= torture_tcase_add_simple_test(tcase
, "Domain", (run_func
)test_dsintid_domain
);