2 Unix SMB/CIFS implementation.
6 Copyright (C) Andrew Tridgell 2003
7 Copyright (C) Stefan (metze) Metzmacher 2004
8 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include "torture/torture.h"
27 #include "librpc/gen_ndr/ndr_drsuapi.h"
28 #include "librpc/gen_ndr/ndr_drsuapi_c.h"
29 #include "torture/rpc/rpc.h"
31 BOOL test_DsBind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
32 struct DsPrivate *priv)
35 struct drsuapi_DsBind r;
38 GUID_from_string(DRSUAPI_DS_BIND_GUID, &priv->bind_guid);
40 r.in.bind_guid = &priv->bind_guid;
41 r.in.bind_info = NULL;
42 r.out.bind_handle = &priv->bind_handle;
44 printf("testing DsBind\n");
46 status = dcerpc_drsuapi_DsBind(p, mem_ctx, &r);
47 if (!NT_STATUS_IS_OK(status)) {
48 const char *errstr = nt_errstr(status);
49 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
50 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
52 printf("dcerpc_drsuapi_DsBind failed - %s\n", errstr);
54 } else if (!W_ERROR_IS_OK(r.out.result)) {
55 printf("DsBind failed - %s\n", win_errstr(r.out.result));
62 static BOOL test_DsGetDCInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
63 struct DsPrivate *priv)
66 struct drsuapi_DsGetDomainControllerInfo r;
69 r.in.bind_handle = &priv->bind_handle;
72 r.in.req.req1.domain_name = talloc_strdup(mem_ctx, lp_realm());
73 r.in.req.req1.level = 1;
75 printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
76 r.in.req.req1.level, r.in.req.req1.domain_name);
78 status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
79 if (!NT_STATUS_IS_OK(status)) {
80 const char *errstr = nt_errstr(status);
81 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
82 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
84 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
85 " with dns domain failed - %s\n",
86 r.in.req.req1.level, errstr);
88 } else if (!W_ERROR_IS_OK(r.out.result)) {
89 printf("DsGetDomainControllerInfo level %d\n"
90 " with dns domain failed - %s\n",
91 r.in.req.req1.level, win_errstr(r.out.result));
95 r.in.req.req1.level = 2;
97 printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
98 r.in.req.req1.level, r.in.req.req1.domain_name);
100 status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
101 if (!NT_STATUS_IS_OK(status)) {
102 const char *errstr = nt_errstr(status);
103 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
104 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
106 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
107 " with dns domain failed - %s\n",
108 r.in.req.req1.level, errstr);
110 } else if (!W_ERROR_IS_OK(r.out.result)) {
111 printf("DsGetDomainControllerInfo level %d\n"
112 " with dns domain failed - %s\n",
113 r.in.req.req1.level, win_errstr(r.out.result));
116 if (r.out.ctr.ctr2.count > 0) {
117 priv->dcinfo = r.out.ctr.ctr2.array[0];
121 r.in.req.req1.level = -1;
123 printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
124 r.in.req.req1.level, r.in.req.req1.domain_name);
126 status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
127 if (!NT_STATUS_IS_OK(status)) {
128 const char *errstr = nt_errstr(status);
129 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
130 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
132 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
133 " with dns domain failed - %s\n",
134 r.in.req.req1.level, errstr);
136 } else if (!W_ERROR_IS_OK(r.out.result)) {
137 printf("DsGetDomainControllerInfo level %d\n"
138 " with dns domain failed - %s\n",
139 r.in.req.req1.level, win_errstr(r.out.result));
143 r.in.req.req1.domain_name = talloc_strdup(mem_ctx, lp_workgroup());
144 r.in.req.req1.level = 2;
146 printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
147 r.in.req.req1.level, r.in.req.req1.domain_name);
149 status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
150 if (!NT_STATUS_IS_OK(status)) {
151 const char *errstr = nt_errstr(status);
152 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
153 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
155 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
156 " with netbios domain failed - %s\n",
157 r.in.req.req1.level, errstr);
159 } else if (!W_ERROR_IS_OK(r.out.result)) {
160 printf("DsGetDomainControllerInfo level %d\n"
161 " with netbios domain failed - %s\n",
162 r.in.req.req1.level, win_errstr(r.out.result));
166 r.in.req.req1.domain_name = "__UNKNOWN_DOMAIN__";
167 r.in.req.req1.level = 2;
169 printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
170 r.in.req.req1.level, r.in.req.req1.domain_name);
172 status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
173 if (!NT_STATUS_IS_OK(status)) {
174 const char *errstr = nt_errstr(status);
175 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
176 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
178 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
179 " with invalid domain failed - %s\n",
180 r.in.req.req1.level, errstr);
182 } else if (!W_ERROR_EQUAL(r.out.result, WERR_DS_OBJ_NOT_FOUND)) {
183 printf("DsGetDomainControllerInfo level %d\n"
184 " with invalid domain not expected error (WERR_DS_OBJ_NOT_FOUND) - %s\n",
185 r.in.req.req1.level, win_errstr(r.out.result));
192 static BOOL test_DsWriteAccountSpn(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
193 struct DsPrivate *priv)
196 struct drsuapi_DsWriteAccountSpn r;
197 struct drsuapi_DsNameString names[2];
200 r.in.bind_handle = &priv->bind_handle;
203 printf("testing DsWriteAccountSpn\n");
205 r.in.req.req1.operation = DRSUAPI_DS_SPN_OPERATION_ADD;
206 r.in.req.req1.unknown1 = 0;
207 r.in.req.req1.object_dn = priv->dcinfo.computer_dn;
208 r.in.req.req1.count = 2;
209 r.in.req.req1.spn_names = names;
210 names[0].str = talloc_asprintf(mem_ctx, "smbtortureSPN/%s",priv->dcinfo.netbios_name);
211 names[1].str = talloc_asprintf(mem_ctx, "smbtortureSPN/%s",priv->dcinfo.dns_name);
213 status = dcerpc_drsuapi_DsWriteAccountSpn(p, mem_ctx, &r);
214 if (!NT_STATUS_IS_OK(status)) {
215 const char *errstr = nt_errstr(status);
216 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
217 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
219 printf("dcerpc_drsuapi_DsWriteAccountSpn failed - %s\n", errstr);
221 } else if (!W_ERROR_IS_OK(r.out.result)) {
222 printf("DsWriteAccountSpn failed - %s\n", win_errstr(r.out.result));
226 r.in.req.req1.operation = DRSUAPI_DS_SPN_OPERATION_DELETE;
227 r.in.req.req1.unknown1 = 0;
229 status = dcerpc_drsuapi_DsWriteAccountSpn(p, mem_ctx, &r);
230 if (!NT_STATUS_IS_OK(status)) {
231 const char *errstr = nt_errstr(status);
232 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
233 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
235 printf("dcerpc_drsuapi_DsWriteAccountSpn failed - %s\n", errstr);
237 } else if (!W_ERROR_IS_OK(r.out.result)) {
238 printf("DsWriteAccountSpn failed - %s\n", win_errstr(r.out.result));
245 static BOOL test_DsReplicaGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
246 struct DsPrivate *priv)
249 struct drsuapi_DsReplicaGetInfo r;
258 DRSUAPI_DS_REPLICA_GET_INFO,
259 DRSUAPI_DS_REPLICA_INFO_NEIGHBORS,
262 DRSUAPI_DS_REPLICA_GET_INFO,
263 DRSUAPI_DS_REPLICA_INFO_CURSORS,
266 DRSUAPI_DS_REPLICA_GET_INFO,
267 DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA,
270 DRSUAPI_DS_REPLICA_GET_INFO,
271 DRSUAPI_DS_REPLICA_INFO_KCC_DSA_CONNECT_FAILURES,
274 DRSUAPI_DS_REPLICA_GET_INFO,
275 DRSUAPI_DS_REPLICA_INFO_KCC_DSA_LINK_FAILURES,
278 DRSUAPI_DS_REPLICA_GET_INFO,
279 DRSUAPI_DS_REPLICA_INFO_PENDING_OPS,
282 DRSUAPI_DS_REPLICA_GET_INFO2,
283 DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA,
286 DRSUAPI_DS_REPLICA_GET_INFO2,
287 DRSUAPI_DS_REPLICA_INFO_CURSORS2,
290 DRSUAPI_DS_REPLICA_GET_INFO2,
291 DRSUAPI_DS_REPLICA_INFO_CURSORS3,
294 DRSUAPI_DS_REPLICA_GET_INFO2,
295 DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA2,
298 DRSUAPI_DS_REPLICA_GET_INFO2,
299 DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA2,
302 DRSUAPI_DS_REPLICA_GET_INFO2,
303 DRSUAPI_DS_REPLICA_INFO_NEIGHBORS02,
306 DRSUAPI_DS_REPLICA_GET_INFO2,
307 DRSUAPI_DS_REPLICA_INFO_CONNECTIONS04,
310 DRSUAPI_DS_REPLICA_GET_INFO2,
311 DRSUAPI_DS_REPLICA_INFO_CURSURS05,
314 DRSUAPI_DS_REPLICA_GET_INFO2,
315 DRSUAPI_DS_REPLICA_INFO_06,
320 r.in.bind_handle = &priv->bind_handle;
322 for (i=0; i < ARRAY_SIZE(array); i++) {
323 const char *object_dn;
325 printf("testing DsReplicaGetInfo level %d infotype %d\n",
326 array[i].level, array[i].infotype);
328 object_dn = (array[i].obj_dn ? array[i].obj_dn : priv->domain_obj_dn);
330 r.in.level = array[i].level;
332 case DRSUAPI_DS_REPLICA_GET_INFO:
333 r.in.req.req1.info_type = array[i].infotype;
334 r.in.req.req1.object_dn = object_dn;
335 ZERO_STRUCT(r.in.req.req1.guid1);
337 case DRSUAPI_DS_REPLICA_GET_INFO2:
338 r.in.req.req2.info_type = array[i].infotype;
339 r.in.req.req2.object_dn = object_dn;
340 ZERO_STRUCT(r.in.req.req1.guid1);
341 r.in.req.req2.unknown1 = 0;
342 r.in.req.req2.string1 = NULL;
343 r.in.req.req2.string2 = NULL;
344 r.in.req.req2.unknown2 = 0;
348 status = dcerpc_drsuapi_DsReplicaGetInfo(p, mem_ctx, &r);
349 if (!NT_STATUS_IS_OK(status)) {
350 const char *errstr = nt_errstr(status);
351 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
352 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
354 if (p->last_fault_code != DCERPC_FAULT_INVALID_TAG) {
355 printf("dcerpc_drsuapi_DsReplicaGetInfo failed - %s\n", errstr);
358 printf("DsReplicaGetInfo level %d and/or infotype %d not supported by server\n",
359 array[i].level, array[i].infotype);
361 } else if (!W_ERROR_IS_OK(r.out.result)) {
362 printf("DsReplicaGetInfo failed - %s\n", win_errstr(r.out.result));
370 static BOOL test_DsReplicaSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
371 struct DsPrivate *priv)
376 struct drsuapi_DsReplicaSync r;
377 struct drsuapi_DsReplicaObjectIdentifier nc;
378 struct GUID null_guid;
379 struct dom_sid null_sid;
388 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
389 printf("DsReplicaSync disabled - enable dangerous tests to use\n");
393 ZERO_STRUCT(null_guid);
394 ZERO_STRUCT(null_sid);
396 r.in.bind_handle = &priv->bind_handle;
398 for (i=0; i < ARRAY_SIZE(array); i++) {
399 printf("testing DsReplicaSync level %d\n",
402 r.in.level = array[i].level;
407 nc.dn = priv->domain_obj_dn?priv->domain_obj_dn:"";
409 r.in.req.req1.naming_context = &nc;
410 r.in.req.req1.guid1 = priv->dcinfo.ntds_guid;
411 r.in.req.req1.string1 = NULL;
412 r.in.req.req1.options = 16;
416 status = dcerpc_drsuapi_DsReplicaSync(p, mem_ctx, &r);
417 if (!NT_STATUS_IS_OK(status)) {
418 const char *errstr = nt_errstr(status);
419 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
420 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
422 printf("dcerpc_drsuapi_DsReplicaSync failed - %s\n", errstr);
424 } else if (!W_ERROR_IS_OK(r.out.result)) {
425 printf("DsReplicaSync failed - %s\n", win_errstr(r.out.result));
433 static BOOL test_DsReplicaUpdateRefs(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
434 struct DsPrivate *priv)
439 struct drsuapi_DsReplicaUpdateRefs r;
440 struct drsuapi_DsReplicaObjectIdentifier nc;
441 struct GUID null_guid;
442 struct dom_sid null_sid;
451 ZERO_STRUCT(null_guid);
452 ZERO_STRUCT(null_sid);
454 r.in.bind_handle = &priv->bind_handle;
456 for (i=0; i < ARRAY_SIZE(array); i++) {
457 printf("testing DsReplicaUpdateRefs level %d\n",
460 r.in.level = array[i].level;
465 nc.dn = priv->domain_obj_dn?priv->domain_obj_dn:"";
467 r.in.req.req1.naming_context = &nc;
468 r.in.req.req1.dest_dsa_dns_name = talloc_asprintf(mem_ctx, "__some_dest_dsa_guid_string._msdn.%s",
469 priv->domain_dns_name);
470 r.in.req.req1.dest_dsa_guid = null_guid;
471 r.in.req.req1.options = 0;
475 status = dcerpc_drsuapi_DsReplicaUpdateRefs(p, mem_ctx, &r);
476 if (!NT_STATUS_IS_OK(status)) {
477 const char *errstr = nt_errstr(status);
478 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
479 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
481 printf("dcerpc_drsuapi_DsReplicaUpdateRefs failed - %s\n", errstr);
483 } else if (!W_ERROR_IS_OK(r.out.result)) {
484 printf("DsReplicaUpdateRefs failed - %s\n", win_errstr(r.out.result));
492 static BOOL test_DsGetNCChanges(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
493 struct DsPrivate *priv)
498 struct drsuapi_DsGetNCChanges r;
499 struct drsuapi_DsReplicaObjectIdentifier nc;
500 struct GUID null_guid;
501 struct dom_sid null_sid;
513 ZERO_STRUCT(null_guid);
514 ZERO_STRUCT(null_sid);
516 for (i=0; i < ARRAY_SIZE(array); i++) {
517 printf("testing DsGetNCChanges level %d\n",
520 r.in.bind_handle = &priv->bind_handle;
521 r.in.level = array[i].level;
523 switch (r.in.level) {
527 nc.dn = priv->domain_obj_dn?priv->domain_obj_dn:"";
529 r.in.req.req5.destination_dsa_guid = GUID_random();
530 r.in.req.req5.source_dsa_guid = null_guid;
531 r.in.req.req5.naming_context = &nc;
532 r.in.req.req5.highwatermark.tmp_highest_usn = 0;
533 r.in.req.req5.highwatermark.reserved_usn = 0;
534 r.in.req.req5.highwatermark.highest_usn = 0;
535 r.in.req.req5.uptodateness_vector = NULL;
536 r.in.req.req5.replica_flags = 0;
537 if (lp_parm_bool(-1, "drsuapi","compression", False)) {
538 r.in.req.req5.replica_flags |= DRSUAPI_DS_REPLICA_NEIGHBOUR_COMPRESS_CHANGES;
540 r.in.req.req5.unknown2 = 0;
541 r.in.req.req5.unknown3 = 0;
542 r.in.req.req5.unknown4 = 0;
543 r.in.req.req5.h1 = 0;
549 nc.dn = priv->domain_obj_dn?priv->domain_obj_dn:"";
551 r.in.req.req8.destination_dsa_guid = GUID_random();
552 r.in.req.req8.source_dsa_guid = null_guid;
553 r.in.req.req8.naming_context = &nc;
554 r.in.req.req8.highwatermark.tmp_highest_usn = 0;
555 r.in.req.req8.highwatermark.reserved_usn = 0;
556 r.in.req.req8.highwatermark.highest_usn = 0;
557 r.in.req.req8.uptodateness_vector = NULL;
558 r.in.req.req8.replica_flags = 0;
559 if (lp_parm_bool(-1,"drsuapi","compression",False)) {
560 r.in.req.req8.replica_flags |= DRSUAPI_DS_REPLICA_NEIGHBOUR_COMPRESS_CHANGES;
562 if (lp_parm_bool(-1,"drsuapi","neighbour_writeable",True)) {
563 r.in.req.req8.replica_flags |= DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE;
565 r.in.req.req8.replica_flags |= DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP
566 | DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS
567 | DRSUAPI_DS_REPLICA_NEIGHBOUR_RETURN_OBJECT_PARENTS
568 | DRSUAPI_DS_REPLICA_NEIGHBOUR_NEVER_SYNCED
570 r.in.req.req8.unknown2 = 402;
571 r.in.req.req8.unknown3 = 402116;
572 r.in.req.req8.unknown4 = 0;
573 r.in.req.req8.h1 = 0;
574 r.in.req.req8.unique_ptr1 = 0;
575 r.in.req.req8.unique_ptr2 = 0;
576 r.in.req.req8.ctr12.count = 0;
577 r.in.req.req8.ctr12.array = NULL;
582 status = dcerpc_drsuapi_DsGetNCChanges(p, mem_ctx, &r);
583 if (!NT_STATUS_IS_OK(status)) {
584 const char *errstr = nt_errstr(status);
585 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
586 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
588 printf("dcerpc_drsuapi_DsGetNCChanges failed - %s\n", errstr);
590 } else if (!W_ERROR_IS_OK(r.out.result)) {
591 printf("DsGetNCChanges failed - %s\n", win_errstr(r.out.result));
599 BOOL test_DsUnbind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
600 struct DsPrivate *priv)
603 struct drsuapi_DsUnbind r;
606 r.in.bind_handle = &priv->bind_handle;
607 r.out.bind_handle = &priv->bind_handle;
609 printf("testing DsUnbind\n");
611 status = dcerpc_drsuapi_DsUnbind(p, mem_ctx, &r);
612 if (!NT_STATUS_IS_OK(status)) {
613 const char *errstr = nt_errstr(status);
614 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
615 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
617 printf("dcerpc_drsuapi_DsUnbind failed - %s\n", errstr);
619 } else if (!W_ERROR_IS_OK(r.out.result)) {
620 printf("DsBind failed - %s\n", win_errstr(r.out.result));
627 BOOL torture_rpc_drsuapi(void)
630 struct dcerpc_pipe *p;
633 struct DsPrivate priv;
635 mem_ctx = talloc_init("torture_rpc_drsuapi");
637 status = torture_rpc_connection(mem_ctx,
639 &dcerpc_table_drsuapi);
640 if (!NT_STATUS_IS_OK(status)) {
641 talloc_free(mem_ctx);
645 printf("Connected to DRAUAPI pipe\n");
649 ret &= test_DsBind(p, mem_ctx, &priv);
651 ret &= test_DsGetDCInfo(p, mem_ctx, &priv);
653 ret &= test_DsCrackNames(p, mem_ctx, &priv, priv.dcinfo.netbios_name);
655 ret &= test_DsWriteAccountSpn(p, mem_ctx, &priv);
657 ret &= test_DsReplicaGetInfo(p, mem_ctx, &priv);
659 ret &= test_DsReplicaSync(p, mem_ctx, &priv);
661 ret &= test_DsReplicaUpdateRefs(p, mem_ctx, &priv);
663 ret &= test_DsGetNCChanges(p, mem_ctx, &priv);
665 ret &= test_DsUnbind(p, mem_ctx, &priv);
667 talloc_free(mem_ctx);