2 Unix SMB/CIFS implementation.
4 DsGetNCChanges replication test
6 Copyright (C) Stefan (metze) Metzmacher 2005
7 Copyright (C) Brad Henry 2005
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "lib/cmdline/popt_common.h"
26 #include "librpc/gen_ndr/ndr_drsuapi_c.h"
27 #include "libcli/cldap/cldap.h"
28 #include "libcli/ldap/ldap_client.h"
29 #include "torture/torture.h"
30 #include "torture/ldap/proto.h"
32 struct DsSyncBindInfo
{
33 struct dcerpc_pipe
*pipe
;
34 struct drsuapi_DsBind req
;
35 struct GUID bind_guid
;
36 struct drsuapi_DsBindInfoCtr our_bind_info_ctr
;
37 struct drsuapi_DsBindInfo28 our_bind_info28
;
38 struct drsuapi_DsBindInfo28 peer_bind_info28
;
39 struct policy_handle bind_handle
;
42 struct DsSyncLDAPInfo
{
43 struct ldap_connection
*conn
;
47 struct dcerpc_binding
*drsuapi_binding
;
50 const char *site_name
;
52 const char *domain_dn
;
54 /* what we need to do as 'Administrator' */
56 struct cli_credentials
*credentials
;
57 struct DsSyncBindInfo drsuapi
;
58 struct DsSyncLDAPInfo ldap
;
61 /* what we need to do as the new dc machine account */
63 struct cli_credentials
*credentials
;
64 struct DsSyncBindInfo drsuapi
;
65 struct drsuapi_DsGetDCInfo2 dc_info2
;
66 struct GUID invocation_id
;
67 struct GUID object_guid
;
70 /* info about the old dc */
72 struct drsuapi_DsGetDomainControllerInfo dc_info
;
76 static struct DsSyncTest
*test_create_context(TALLOC_CTX
*mem_ctx
)
79 struct DsSyncTest
*ctx
;
80 struct drsuapi_DsBindInfo28
*our_bind_info28
;
81 struct drsuapi_DsBindInfoCtr
*our_bind_info_ctr
;
82 const char *binding
= lp_parm_string(-1, "torture", "binding");
83 ctx
= talloc_zero(mem_ctx
, struct DsSyncTest
);
84 if (!ctx
) return NULL
;
86 status
= dcerpc_parse_binding(ctx
, binding
, &ctx
->drsuapi_binding
);
87 if (!NT_STATUS_IS_OK(status
)) {
88 printf("Bad binding string %s\n", binding
);
91 ctx
->drsuapi_binding
->flags
|= DCERPC_SIGN
| DCERPC_SEAL
;
93 ctx
->ldap_url
= talloc_asprintf(ctx
, "ldap://%s/", ctx
->drsuapi_binding
->host
);
96 ctx
->admin
.credentials
= cmdline_credentials
;
98 our_bind_info28
= &ctx
->admin
.drsuapi
.our_bind_info28
;
99 our_bind_info28
->supported_extensions
= 0xFFFFFFFF;
100 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3
;
101 our_bind_info28
->site_guid
= GUID_zero();
102 our_bind_info28
->u1
= 0;
103 our_bind_info28
->repl_epoch
= 1;
105 our_bind_info_ctr
= &ctx
->admin
.drsuapi
.our_bind_info_ctr
;
106 our_bind_info_ctr
->length
= 28;
107 our_bind_info_ctr
->info
.info28
= *our_bind_info28
;
109 GUID_from_string(DRSUAPI_DS_BIND_GUID
, &ctx
->admin
.drsuapi
.bind_guid
);
111 ctx
->admin
.drsuapi
.req
.in
.bind_guid
= &ctx
->admin
.drsuapi
.bind_guid
;
112 ctx
->admin
.drsuapi
.req
.in
.bind_info
= our_bind_info_ctr
;
113 ctx
->admin
.drsuapi
.req
.out
.bind_handle
= &ctx
->admin
.drsuapi
.bind_handle
;
117 our_bind_info28
= &ctx
->new_dc
.drsuapi
.our_bind_info28
;
118 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_BASE
;
119 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_ASYNC_REPLICATION
;
120 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_REMOVEAPI
;
121 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_MOVEREQ_V2
;
122 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_GETCHG_COMPRESS
;
123 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V1
;
124 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATION
;
125 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTE
;
126 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRY_V2
;
127 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION
;
128 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V2
;
129 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MOD
;
130 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_CRYPTO_BIND
;
131 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_GET_REPL_INFO
;
132 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION
;
133 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V01
;
134 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_TRANSITIVE_MEMBERSHIP
;
135 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_ADD_SID_HISTORY
;
136 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3
;
137 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_GET_MEMBERSHIPS2
;
138 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V6
;
139 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_NONDOMAIN_NCS
;
140 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8
;
141 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V5
;
142 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V6
;
143 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3
;
144 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V7
;
145 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_VERIFY_OBJECT
;
146 if (lp_parm_bool(-1,"dssync","xpress",False
)) {
147 our_bind_info28
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_XPRESS_COMPRESS
;
149 our_bind_info28
->site_guid
= GUID_zero();
150 our_bind_info28
->u1
= 508;
151 our_bind_info28
->repl_epoch
= 0;
153 our_bind_info_ctr
= &ctx
->new_dc
.drsuapi
.our_bind_info_ctr
;
154 our_bind_info_ctr
->length
= 28;
155 our_bind_info_ctr
->info
.info28
= *our_bind_info28
;
157 GUID_from_string(DRSUAPI_DS_BIND_GUID_W2K3
, &ctx
->new_dc
.drsuapi
.bind_guid
);
159 ctx
->new_dc
.drsuapi
.req
.in
.bind_guid
= &ctx
->new_dc
.drsuapi
.bind_guid
;
160 ctx
->new_dc
.drsuapi
.req
.in
.bind_info
= our_bind_info_ctr
;
161 ctx
->new_dc
.drsuapi
.req
.out
.bind_handle
= &ctx
->new_dc
.drsuapi
.bind_handle
;
163 ctx
->new_dc
.invocation_id
= ctx
->new_dc
.drsuapi
.bind_guid
;
170 static BOOL
_test_DsBind(struct DsSyncTest
*ctx
, struct cli_credentials
*credentials
, struct DsSyncBindInfo
*b
)
174 struct event_context
*event
= NULL
;
176 status
= dcerpc_pipe_connect_b(ctx
,
177 &b
->pipe
, ctx
->drsuapi_binding
,
178 &dcerpc_table_drsuapi
,
181 if (!NT_STATUS_IS_OK(status
)) {
182 printf("Failed to connect to server as a BDC: %s\n", nt_errstr(status
));
186 status
= dcerpc_drsuapi_DsBind(b
->pipe
, ctx
, &b
->req
);
187 if (!NT_STATUS_IS_OK(status
)) {
188 const char *errstr
= nt_errstr(status
);
189 if (NT_STATUS_EQUAL(status
, NT_STATUS_NET_WRITE_FAULT
)) {
190 errstr
= dcerpc_errstr(ctx
, b
->pipe
->last_fault_code
);
192 printf("dcerpc_drsuapi_DsBind failed - %s\n", errstr
);
194 } else if (!W_ERROR_IS_OK(b
->req
.out
.result
)) {
195 printf("DsBind failed - %s\n", win_errstr(b
->req
.out
.result
));
199 ZERO_STRUCT(b
->peer_bind_info28
);
200 if (b
->req
.out
.bind_info
) {
201 switch (b
->req
.out
.bind_info
->length
) {
203 struct drsuapi_DsBindInfo24
*info24
;
204 info24
= &b
->req
.out
.bind_info
->info
.info24
;
205 b
->peer_bind_info28
.supported_extensions
= info24
->supported_extensions
;
206 b
->peer_bind_info28
.site_guid
= info24
->site_guid
;
207 b
->peer_bind_info28
.u1
= info24
->u1
;
208 b
->peer_bind_info28
.repl_epoch
= 0;
212 b
->peer_bind_info28
= b
->req
.out
.bind_info
->info
.info28
;
220 static BOOL
test_LDAPBind(struct DsSyncTest
*ctx
, struct cli_credentials
*credentials
, struct DsSyncLDAPInfo
*l
)
225 status
= torture_ldap_connection(ctx
, &l
->conn
, ctx
->ldap_url
);
226 if (!NT_STATUS_IS_OK(status
)) {
227 printf("failed to connect to LDAP: %s\n", ctx
->ldap_url
);
231 printf("connected to LDAP: %s\n", ctx
->ldap_url
);
233 status
= torture_ldap_bind_sasl(l
->conn
, credentials
);
234 if (!NT_STATUS_IS_OK(status
)) {
235 printf("failed to bind to LDAP:\n");
238 printf("bound to LDAP.\n");
243 static BOOL
test_GetInfo(struct DsSyncTest
*ctx
)
246 struct drsuapi_DsCrackNames r
;
247 struct drsuapi_DsNameString names
[1];
250 struct cldap_socket
*cldap
= cldap_socket_init(ctx
, NULL
);
251 struct cldap_netlogon search
;
253 r
.in
.bind_handle
= &ctx
->admin
.drsuapi
.bind_handle
;
255 r
.in
.req
.req1
.codepage
= 1252; /* western european */
256 r
.in
.req
.req1
.language
= 0x00000407; /* german */
257 r
.in
.req
.req1
.count
= 1;
258 r
.in
.req
.req1
.names
= names
;
259 r
.in
.req
.req1
.format_flags
= DRSUAPI_DS_NAME_FLAG_NO_FLAGS
;
260 r
.in
.req
.req1
.format_offered
= DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT
;
261 r
.in
.req
.req1
.format_desired
= DRSUAPI_DS_NAME_FORMAT_FQDN_1779
;
262 names
[0].str
= talloc_asprintf(ctx
, "%s\\", lp_workgroup());
264 status
= dcerpc_drsuapi_DsCrackNames(ctx
->admin
.drsuapi
.pipe
, ctx
, &r
);
265 if (!NT_STATUS_IS_OK(status
)) {
266 const char *errstr
= nt_errstr(status
);
267 if (NT_STATUS_EQUAL(status
, NT_STATUS_NET_WRITE_FAULT
)) {
268 errstr
= dcerpc_errstr(ctx
, ctx
->admin
.drsuapi
.pipe
->last_fault_code
);
270 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr
);
272 } else if (!W_ERROR_IS_OK(r
.out
.result
)) {
273 printf("DsCrackNames failed - %s\n", win_errstr(r
.out
.result
));
277 ctx
->domain_dn
= r
.out
.ctr
.ctr1
->array
[0].result_name
;
280 search
.in
.dest_address
= ctx
->drsuapi_binding
->host
;
281 search
.in
.acct_control
= -1;
282 search
.in
.version
= 6;
283 status
= cldap_netlogon(cldap
, ctx
, &search
);
284 if (!NT_STATUS_IS_OK(status
)) {
285 const char *errstr
= nt_errstr(status
);
286 ctx
->site_name
= talloc_asprintf(ctx
, "%s", "Default-First-Site-Name");
287 printf("cldap_netlogon() returned %s. Defaulting to Site-Name: %s\n", errstr
, ctx
->site_name
);
289 ctx
->site_name
= talloc_steal(ctx
, search
.out
.netlogon
.logon5
.client_site
);
290 printf("cldap_netlogon() returned Client Site-Name: %s.\n",ctx
->site_name
);
291 printf("cldap_netlogon() returned Server Site-Name: %s.\n",search
.out
.netlogon
.logon5
.server_site
);
297 static void test_analyse_objects(struct DsSyncTest
*ctx
,
298 struct drsuapi_DsReplicaObjectListItemEx
*cur
)
300 if (!lp_parm_bool(-1,"dssync","print_pwd_blobs",False
)) {
304 for (; cur
; cur
= cur
->next_object
) {
306 BOOL dn_printed
= False
;
309 if (!cur
->object
.identifier
) continue;
311 dn
= cur
->object
.identifier
->dn
;
313 for (i
=0; i
< cur
->object
.attribute_ctr
.num_attributes
; i
++) {
314 const char *name
= NULL
;
315 DATA_BLOB
*data
= NULL
;
316 struct drsuapi_DsReplicaAttribute
*attr
;
317 attr
= &cur
->object
.attribute_ctr
.attributes
[i
];
319 switch (attr
->attid
) {
320 case DRSUAPI_ATTRIBUTE_dBCSPwd
:
323 case DRSUAPI_ATTRIBUTE_unicodePwd
:
326 case DRSUAPI_ATTRIBUTE_ntPwdHistory
:
327 name
= "ntPwdHistory";
329 case DRSUAPI_ATTRIBUTE_lmPwdHistory
:
330 name
= "lmPwdHistory";
332 case DRSUAPI_ATTRIBUTE_supplementalCredentials
:
333 name
= "supplementalCredentials";
335 case DRSUAPI_ATTRIBUTE_priorValue
:
338 case DRSUAPI_ATTRIBUTE_currentValue
:
339 name
= "currentValue";
341 case DRSUAPI_ATTRIBUTE_trustAuthOutgoing
:
342 name
= "trustAuthOutgoing";
344 case DRSUAPI_ATTRIBUTE_trustAuthIncoming
:
345 name
= "trustAuthIncoming";
347 case DRSUAPI_ATTRIBUTE_initialAuthOutgoing
:
348 name
= "initialAuthOutgoing";
350 case DRSUAPI_ATTRIBUTE_initialAuthIncoming
:
351 name
= "initialAuthIncoming";
357 if (attr
->value_ctr
.num_values
!= 1) continue;
359 if (!attr
->value_ctr
.values
[0].blob
) continue;
361 data
= attr
->value_ctr
.values
[0].blob
;
364 DEBUG(0,("DN: %s\n", dn
));
367 DEBUGADD(0,("ATTR: %s data_blob.length=%lu\n",
368 name
, (long)data
->length
));
369 dump_data(0,data
->data
, data
->length
);
374 static BOOL
test_FetchData(struct DsSyncTest
*ctx
)
379 uint64_t highest_usn
= 0;
380 const char *partition
= NULL
;
381 struct drsuapi_DsGetNCChanges r
;
382 struct drsuapi_DsReplicaObjectIdentifier nc
;
383 struct drsuapi_DsGetNCChangesCtr1
*ctr1
= NULL
;
384 struct drsuapi_DsGetNCChangesCtr6
*ctr6
= NULL
;
385 int32_t out_level
= 0;
386 struct GUID null_guid
;
387 struct dom_sid null_sid
;
399 ZERO_STRUCT(null_guid
);
400 ZERO_STRUCT(null_sid
);
402 partition
= lp_parm_string(-1, "dssync", "partition");
403 if (partition
== NULL
) {
404 partition
= ctx
->domain_dn
;
405 printf("dssync:partition not specified, defaulting to %s.\n", ctx
->domain_dn
);
408 highest_usn
= lp_parm_int(-1, "dssync", "highest_usn", 0);
410 for (i
=0; i
< ARRAY_SIZE(array
); i
++) {
411 printf("testing DsGetNCChanges level %d\n",
414 r
.in
.bind_handle
= &ctx
->new_dc
.drsuapi
.bind_handle
;
415 r
.in
.level
= &array
[i
].level
;
417 switch (*r
.in
.level
) {
423 r
.in
.req
.req5
.destination_dsa_guid
= ctx
->new_dc
.invocation_id
;
424 r
.in
.req
.req5
.source_dsa_invocation_id
= null_guid
;
425 r
.in
.req
.req5
.naming_context
= &nc
;
426 r
.in
.req
.req5
.highwatermark
.tmp_highest_usn
= highest_usn
;
427 r
.in
.req
.req5
.highwatermark
.reserved_usn
= 0;
428 r
.in
.req
.req5
.highwatermark
.highest_usn
= highest_usn
;
429 r
.in
.req
.req5
.uptodateness_vector
= NULL
;
430 r
.in
.req
.req5
.replica_flags
= 0;
431 if (lp_parm_bool(-1,"dssync","compression",False
)) {
432 r
.in
.req
.req5
.replica_flags
|= DRSUAPI_DS_REPLICA_NEIGHBOUR_COMPRESS_CHANGES
;
434 if (lp_parm_bool(-1,"dssync","neighbour_writeable",True
)) {
435 r
.in
.req
.req5
.replica_flags
|= DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE
;
437 r
.in
.req
.req5
.replica_flags
|= DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP
438 | DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS
439 | DRSUAPI_DS_REPLICA_NEIGHBOUR_RETURN_OBJECT_PARENTS
440 | DRSUAPI_DS_REPLICA_NEIGHBOUR_NEVER_SYNCED
442 r
.in
.req
.req5
.max_object_count
= 133;
443 r
.in
.req
.req5
.max_ndr_size
= 1336770;
444 r
.in
.req
.req5
.unknown4
= 0;
445 r
.in
.req
.req5
.h1
= 0;
452 /* nc.dn can be set to any other ad partition */
454 r
.in
.req
.req8
.destination_dsa_guid
= ctx
->new_dc
.invocation_id
;
455 r
.in
.req
.req8
.source_dsa_invocation_id
= null_guid
;
456 r
.in
.req
.req8
.naming_context
= &nc
;
457 r
.in
.req
.req8
.highwatermark
.tmp_highest_usn
= highest_usn
;
458 r
.in
.req
.req8
.highwatermark
.reserved_usn
= 0;
459 r
.in
.req
.req8
.highwatermark
.highest_usn
= highest_usn
;
460 r
.in
.req
.req8
.uptodateness_vector
= NULL
;
461 r
.in
.req
.req8
.replica_flags
= 0;
462 if (lp_parm_bool(-1,"dssync","compression",False
)) {
463 r
.in
.req
.req8
.replica_flags
|= DRSUAPI_DS_REPLICA_NEIGHBOUR_COMPRESS_CHANGES
;
465 if (lp_parm_bool(-1,"dssync","neighbour_writeable",True
)) {
466 r
.in
.req
.req8
.replica_flags
|= DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE
;
468 r
.in
.req
.req8
.replica_flags
|= DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP
469 | DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS
470 | DRSUAPI_DS_REPLICA_NEIGHBOUR_RETURN_OBJECT_PARENTS
471 | DRSUAPI_DS_REPLICA_NEIGHBOUR_NEVER_SYNCED
473 r
.in
.req
.req8
.max_object_count
= 402;
474 r
.in
.req
.req8
.max_ndr_size
= 402116;
476 r
.in
.req
.req8
.unknown4
= 0;
477 r
.in
.req
.req8
.h1
= 0;
478 r
.in
.req
.req8
.unique_ptr1
= 0;
479 r
.in
.req
.req8
.unique_ptr2
= 0;
480 r
.in
.req
.req8
.mapping_ctr
.num_mappings
= 0;
481 r
.in
.req
.req8
.mapping_ctr
.mappings
= NULL
;
486 printf("Dumping AD partition: %s\n", nc
.dn
);
490 if (*r
.in
.level
== 5) {
491 DEBUG(0,("start[%d] tmp_higest_usn: %llu , highest_usn: %llu\n",y
,
492 (long long)r
.in
.req
.req5
.highwatermark
.tmp_highest_usn
,
493 (long long)r
.in
.req
.req5
.highwatermark
.highest_usn
));
496 if (*r
.in
.level
== 8) {
497 DEBUG(0,("start[%d] tmp_higest_usn: %llu , highest_usn: %llu\n",y
,
498 (long long)r
.in
.req
.req8
.highwatermark
.tmp_highest_usn
,
499 (long long)r
.in
.req
.req8
.highwatermark
.highest_usn
));
502 status
= dcerpc_drsuapi_DsGetNCChanges(ctx
->new_dc
.drsuapi
.pipe
, ctx
, &r
);
503 if (!NT_STATUS_IS_OK(status
)) {
504 const char *errstr
= nt_errstr(status
);
505 if (NT_STATUS_EQUAL(status
, NT_STATUS_NET_WRITE_FAULT
)) {
506 errstr
= dcerpc_errstr(ctx
, ctx
->new_dc
.drsuapi
.pipe
->last_fault_code
);
508 printf("dcerpc_drsuapi_DsGetNCChanges failed - %s\n", errstr
);
510 } else if (!W_ERROR_IS_OK(r
.out
.result
)) {
511 printf("DsGetNCChanges failed - %s\n", win_errstr(r
.out
.result
));
515 if (ret
== True
&& *r
.out
.level
== 1) {
517 ctr1
= &r
.out
.ctr
.ctr1
;
518 } else if (ret
== True
&& *r
.out
.level
== 2) {
520 ctr1
= r
.out
.ctr
.ctr2
.ctr
.mszip1
.ctr1
;
523 if (out_level
== 1) {
524 DEBUG(0,("end[%d] tmp_highest_usn: %llu , highest_usn: %llu\n",y
,
525 (long long)ctr1
->new_highwatermark
.tmp_highest_usn
,
526 (long long)ctr1
->new_highwatermark
.highest_usn
));
528 test_analyse_objects(ctx
, ctr1
->first_object
);
530 if (ctr1
->new_highwatermark
.tmp_highest_usn
> ctr1
->new_highwatermark
.highest_usn
) {
531 r
.in
.req
.req5
.highwatermark
= ctr1
->new_highwatermark
;
536 if (ret
== True
&& *r
.out
.level
== 6) {
538 ctr6
= &r
.out
.ctr
.ctr6
;
539 } else if (ret
== True
&& *r
.out
.level
== 7
540 && r
.out
.ctr
.ctr7
.level
== 6
541 && r
.out
.ctr
.ctr7
.type
== DRSUAPI_COMPRESSION_TYPE_MSZIP
) {
543 ctr6
= r
.out
.ctr
.ctr7
.ctr
.mszip6
.ctr6
;
546 if (out_level
== 6) {
547 DEBUG(0,("end[%d] tmp_highest_usn: %llu , highest_usn: %llu\n",y
,
548 (long long)ctr6
->new_highwatermark
.tmp_highest_usn
,
549 (long long)ctr6
->new_highwatermark
.highest_usn
));
551 test_analyse_objects(ctx
, ctr6
->first_object
);
553 if (ctr6
->new_highwatermark
.tmp_highest_usn
> ctr6
->new_highwatermark
.highest_usn
) {
554 r
.in
.req
.req8
.highwatermark
= ctr6
->new_highwatermark
;
566 static BOOL
test_FetchNT4Data(struct DsSyncTest
*ctx
)
571 uint64_t highest_usn
= 0;
572 const char *partition
= NULL
;
573 struct drsuapi_DsGetNT4ChangeLog r
;
574 int32_t out_level
= 0;
575 struct GUID null_guid
;
576 struct dom_sid null_sid
;
579 ZERO_STRUCT(null_guid
);
580 ZERO_STRUCT(null_sid
);
584 r
.in
.bind_handle
= &ctx
->new_dc
.drsuapi
.bind_handle
;
587 r
.in
.req
.req1
.unknown1
= lp_parm_int(-1, "dssync", "nt4-1", 3);
588 r
.in
.req
.req1
.unknown2
= lp_parm_int(-1, "dssync", "nt4-2", 0x00004000);
591 r
.in
.req
.req1
.length
= cookie
.length
;
592 r
.in
.req
.req1
.data
= cookie
.data
;
594 status
= dcerpc_drsuapi_DsGetNT4ChangeLog(ctx
->new_dc
.drsuapi
.pipe
, ctx
, &r
);
595 if (!NT_STATUS_IS_OK(status
)) {
596 const char *errstr
= nt_errstr(status
);
597 if (NT_STATUS_EQUAL(status
, NT_STATUS_NET_WRITE_FAULT
)) {
598 errstr
= dcerpc_errstr(ctx
, ctx
->new_dc
.drsuapi
.pipe
->last_fault_code
);
600 printf("dcerpc_drsuapi_DsGetNT4ChangeLog failed - %s\n", errstr
);
602 } else if (!W_ERROR_IS_OK(r
.out
.result
)) {
603 printf("DsGetNT4ChangeLog failed - %s\n", win_errstr(r
.out
.result
));
605 } else if (r
.out
.level
!= 1) {
606 printf("DsGetNT4ChangeLog unknown level - %u\n", r
.out
.level
);
608 } else if (NT_STATUS_IS_OK(r
.out
.info
.info1
.status
)) {
609 } else if (NT_STATUS_EQUAL(r
.out
.info
.info1
.status
, STATUS_MORE_ENTRIES
)) {
610 cookie
.length
= r
.out
.info
.info1
.length1
;
611 cookie
.data
= r
.out
.info
.info1
.data1
;
614 printf("DsGetNT4ChangeLog failed - %s\n", nt_errstr(r
.out
.info
.info1
.status
));
624 BOOL
torture_rpc_dssync(struct torture_context
*torture
)
628 struct DsSyncTest
*ctx
;
630 mem_ctx
= talloc_init("torture_rpc_dssync");
631 ctx
= test_create_context(mem_ctx
);
633 ret
&= _test_DsBind(ctx
, ctx
->admin
.credentials
, &ctx
->admin
.drsuapi
);
634 ret
&= test_LDAPBind(ctx
, ctx
->admin
.credentials
, &ctx
->admin
.ldap
);
635 ret
&= test_GetInfo(ctx
);
636 ret
&= _test_DsBind(ctx
, ctx
->admin
.credentials
, &ctx
->new_dc
.drsuapi
);
637 ret
&= test_FetchData(ctx
);
638 ret
&= test_FetchNT4Data(ctx
);