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_c.h"
28 #include "torture/rpc/rpc.h"
30 BOOL test_DsBind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
31 struct DsPrivate *priv)
34 struct drsuapi_DsBind r;
37 GUID_from_string(DRSUAPI_DS_BIND_GUID, &priv->bind_guid);
39 r.in.bind_guid = &priv->bind_guid;
40 r.in.bind_info = NULL;
41 r.out.bind_handle = &priv->bind_handle;
43 printf("testing DsBind\n");
45 status = dcerpc_drsuapi_DsBind(p, mem_ctx, &r);
46 if (!NT_STATUS_IS_OK(status)) {
47 const char *errstr = nt_errstr(status);
48 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
49 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
51 printf("dcerpc_drsuapi_DsBind failed - %s\n", errstr);
53 } else if (!W_ERROR_IS_OK(r.out.result)) {
54 printf("DsBind failed - %s\n", win_errstr(r.out.result));
61 static BOOL test_DsGetDCInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
62 struct DsPrivate *priv)
65 struct drsuapi_DsGetDomainControllerInfo r;
68 r.in.bind_handle = &priv->bind_handle;
71 r.in.req.req1.domain_name = talloc_strdup(mem_ctx, lp_realm());
72 r.in.req.req1.level = 1;
74 printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
75 r.in.req.req1.level, r.in.req.req1.domain_name);
77 status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
78 if (!NT_STATUS_IS_OK(status)) {
79 const char *errstr = nt_errstr(status);
80 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
81 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
83 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
84 " with dns domain failed - %s\n",
85 r.in.req.req1.level, errstr);
87 } else if (!W_ERROR_IS_OK(r.out.result)) {
88 printf("DsGetDomainControllerInfo level %d\n"
89 " with dns domain failed - %s\n",
90 r.in.req.req1.level, win_errstr(r.out.result));
94 r.in.req.req1.level = 2;
96 printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
97 r.in.req.req1.level, r.in.req.req1.domain_name);
99 status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
100 if (!NT_STATUS_IS_OK(status)) {
101 const char *errstr = nt_errstr(status);
102 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
103 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
105 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
106 " with dns domain failed - %s\n",
107 r.in.req.req1.level, errstr);
109 } else if (!W_ERROR_IS_OK(r.out.result)) {
110 printf("DsGetDomainControllerInfo level %d\n"
111 " with dns domain failed - %s\n",
112 r.in.req.req1.level, win_errstr(r.out.result));
115 if (r.out.ctr.ctr2.count > 0) {
116 priv->dcinfo = r.out.ctr.ctr2.array[0];
120 r.in.req.req1.level = -1;
122 printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
123 r.in.req.req1.level, r.in.req.req1.domain_name);
125 status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
126 if (!NT_STATUS_IS_OK(status)) {
127 const char *errstr = nt_errstr(status);
128 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
129 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
131 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
132 " with dns domain failed - %s\n",
133 r.in.req.req1.level, errstr);
135 } else if (!W_ERROR_IS_OK(r.out.result)) {
136 printf("DsGetDomainControllerInfo level %d\n"
137 " with dns domain failed - %s\n",
138 r.in.req.req1.level, win_errstr(r.out.result));
142 r.in.req.req1.domain_name = talloc_strdup(mem_ctx, lp_workgroup());
143 r.in.req.req1.level = 2;
145 printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
146 r.in.req.req1.level, r.in.req.req1.domain_name);
148 status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
149 if (!NT_STATUS_IS_OK(status)) {
150 const char *errstr = nt_errstr(status);
151 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
152 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
154 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
155 " with netbios domain failed - %s\n",
156 r.in.req.req1.level, errstr);
158 } else if (!W_ERROR_IS_OK(r.out.result)) {
159 printf("DsGetDomainControllerInfo level %d\n"
160 " with netbios domain failed - %s\n",
161 r.in.req.req1.level, win_errstr(r.out.result));
165 r.in.req.req1.domain_name = "__UNKNOWN_DOMAIN__";
166 r.in.req.req1.level = 2;
168 printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
169 r.in.req.req1.level, r.in.req.req1.domain_name);
171 status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
172 if (!NT_STATUS_IS_OK(status)) {
173 const char *errstr = nt_errstr(status);
174 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
175 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
177 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
178 " with invalid domain failed - %s\n",
179 r.in.req.req1.level, errstr);
181 } else if (!W_ERROR_EQUAL(r.out.result, WERR_DS_OBJ_NOT_FOUND)) {
182 printf("DsGetDomainControllerInfo level %d\n"
183 " with invalid domain not expected error (WERR_DS_OBJ_NOT_FOUND) - %s\n",
184 r.in.req.req1.level, win_errstr(r.out.result));
191 static BOOL test_DsWriteAccountSpn(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
192 struct DsPrivate *priv)
195 struct drsuapi_DsWriteAccountSpn r;
196 struct drsuapi_DsNameString names[2];
199 r.in.bind_handle = &priv->bind_handle;
202 printf("testing DsWriteAccountSpn\n");
204 r.in.req.req1.operation = DRSUAPI_DS_SPN_OPERATION_ADD;
205 r.in.req.req1.unknown1 = 0;
206 r.in.req.req1.object_dn = priv->dcinfo.computer_dn;
207 r.in.req.req1.count = 2;
208 r.in.req.req1.spn_names = names;
209 names[0].str = talloc_asprintf(mem_ctx, "smbtortureSPN/%s",priv->dcinfo.netbios_name);
210 names[1].str = talloc_asprintf(mem_ctx, "smbtortureSPN/%s",priv->dcinfo.dns_name);
212 status = dcerpc_drsuapi_DsWriteAccountSpn(p, mem_ctx, &r);
213 if (!NT_STATUS_IS_OK(status)) {
214 const char *errstr = nt_errstr(status);
215 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
216 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
218 printf("dcerpc_drsuapi_DsWriteAccountSpn failed - %s\n", errstr);
220 } else if (!W_ERROR_IS_OK(r.out.result)) {
221 printf("DsWriteAccountSpn failed - %s\n", win_errstr(r.out.result));
225 r.in.req.req1.operation = DRSUAPI_DS_SPN_OPERATION_DELETE;
226 r.in.req.req1.unknown1 = 0;
228 status = dcerpc_drsuapi_DsWriteAccountSpn(p, mem_ctx, &r);
229 if (!NT_STATUS_IS_OK(status)) {
230 const char *errstr = nt_errstr(status);
231 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
232 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
234 printf("dcerpc_drsuapi_DsWriteAccountSpn failed - %s\n", errstr);
236 } else if (!W_ERROR_IS_OK(r.out.result)) {
237 printf("DsWriteAccountSpn failed - %s\n", win_errstr(r.out.result));
244 static BOOL test_DsReplicaGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
245 struct DsPrivate *priv)
248 struct drsuapi_DsReplicaGetInfo r;
257 DRSUAPI_DS_REPLICA_GET_INFO,
258 DRSUAPI_DS_REPLICA_INFO_NEIGHBORS,
261 DRSUAPI_DS_REPLICA_GET_INFO,
262 DRSUAPI_DS_REPLICA_INFO_CURSORS,
265 DRSUAPI_DS_REPLICA_GET_INFO,
266 DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA,
269 DRSUAPI_DS_REPLICA_GET_INFO,
270 DRSUAPI_DS_REPLICA_INFO_KCC_DSA_CONNECT_FAILURES,
273 DRSUAPI_DS_REPLICA_GET_INFO,
274 DRSUAPI_DS_REPLICA_INFO_KCC_DSA_LINK_FAILURES,
277 DRSUAPI_DS_REPLICA_GET_INFO,
278 DRSUAPI_DS_REPLICA_INFO_PENDING_OPS,
281 DRSUAPI_DS_REPLICA_GET_INFO2,
282 DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA,
285 DRSUAPI_DS_REPLICA_GET_INFO2,
286 DRSUAPI_DS_REPLICA_INFO_CURSORS2,
289 DRSUAPI_DS_REPLICA_GET_INFO2,
290 DRSUAPI_DS_REPLICA_INFO_CURSORS3,
293 DRSUAPI_DS_REPLICA_GET_INFO2,
294 DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA2,
297 DRSUAPI_DS_REPLICA_GET_INFO2,
298 DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA2,
301 DRSUAPI_DS_REPLICA_GET_INFO2,
302 DRSUAPI_DS_REPLICA_INFO_NEIGHBORS02,
305 DRSUAPI_DS_REPLICA_GET_INFO2,
306 DRSUAPI_DS_REPLICA_INFO_CONNECTIONS04,
309 DRSUAPI_DS_REPLICA_GET_INFO2,
310 DRSUAPI_DS_REPLICA_INFO_CURSURS05,
313 DRSUAPI_DS_REPLICA_GET_INFO2,
314 DRSUAPI_DS_REPLICA_INFO_06,
319 r.in.bind_handle = &priv->bind_handle;
321 for (i=0; i < ARRAY_SIZE(array); i++) {
322 const char *object_dn;
324 printf("testing DsReplicaGetInfo level %d infotype %d\n",
325 array[i].level, array[i].infotype);
327 object_dn = (array[i].obj_dn ? array[i].obj_dn : priv->domain_obj_dn);
329 r.in.level = array[i].level;
331 case DRSUAPI_DS_REPLICA_GET_INFO:
332 r.in.req.req1.info_type = array[i].infotype;
333 r.in.req.req1.object_dn = object_dn;
334 ZERO_STRUCT(r.in.req.req1.guid1);
336 case DRSUAPI_DS_REPLICA_GET_INFO2:
337 r.in.req.req2.info_type = array[i].infotype;
338 r.in.req.req2.object_dn = object_dn;
339 ZERO_STRUCT(r.in.req.req1.guid1);
340 r.in.req.req2.unknown1 = 0;
341 r.in.req.req2.string1 = NULL;
342 r.in.req.req2.string2 = NULL;
343 r.in.req.req2.unknown2 = 0;
347 status = dcerpc_drsuapi_DsReplicaGetInfo(p, mem_ctx, &r);
348 if (!NT_STATUS_IS_OK(status)) {
349 const char *errstr = nt_errstr(status);
350 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
351 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
353 if (p->last_fault_code != DCERPC_FAULT_INVALID_TAG) {
354 printf("dcerpc_drsuapi_DsReplicaGetInfo failed - %s\n", errstr);
357 printf("DsReplicaGetInfo level %d and/or infotype %d not supported by server\n",
358 array[i].level, array[i].infotype);
360 } else if (!W_ERROR_IS_OK(r.out.result)) {
361 printf("DsReplicaGetInfo failed - %s\n", win_errstr(r.out.result));
369 static BOOL test_DsReplicaSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
370 struct DsPrivate *priv)
375 struct drsuapi_DsReplicaSync r;
376 struct drsuapi_DsReplicaObjectIdentifier nc;
377 struct GUID null_guid;
378 struct dom_sid null_sid;
387 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
388 printf("DsReplicaSync disabled - enable dangerous tests to use\n");
392 ZERO_STRUCT(null_guid);
393 ZERO_STRUCT(null_sid);
395 r.in.bind_handle = &priv->bind_handle;
397 for (i=0; i < ARRAY_SIZE(array); i++) {
398 printf("testing DsReplicaSync level %d\n",
401 r.in.level = array[i].level;
406 nc.dn = priv->domain_obj_dn?priv->domain_obj_dn:"";
408 r.in.req.req1.naming_context = &nc;
409 r.in.req.req1.guid1 = priv->dcinfo.ntds_guid;
410 r.in.req.req1.string1 = NULL;
411 r.in.req.req1.options = 16;
415 status = dcerpc_drsuapi_DsReplicaSync(p, mem_ctx, &r);
416 if (!NT_STATUS_IS_OK(status)) {
417 const char *errstr = nt_errstr(status);
418 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
419 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
421 printf("dcerpc_drsuapi_DsReplicaSync failed - %s\n", errstr);
423 } else if (!W_ERROR_IS_OK(r.out.result)) {
424 printf("DsReplicaSync failed - %s\n", win_errstr(r.out.result));
432 static BOOL test_DsReplicaUpdateRefs(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
433 struct DsPrivate *priv)
438 struct drsuapi_DsReplicaUpdateRefs r;
439 struct drsuapi_DsReplicaObjectIdentifier nc;
440 struct GUID null_guid;
441 struct dom_sid null_sid;
450 ZERO_STRUCT(null_guid);
451 ZERO_STRUCT(null_sid);
453 r.in.bind_handle = &priv->bind_handle;
455 for (i=0; i < ARRAY_SIZE(array); i++) {
456 printf("testing DsReplicaUpdateRefs level %d\n",
459 r.in.level = array[i].level;
464 nc.dn = priv->domain_obj_dn?priv->domain_obj_dn:"";
466 r.in.req.req1.naming_context = &nc;
467 r.in.req.req1.dest_dsa_dns_name = talloc_asprintf(mem_ctx, "__some_dest_dsa_guid_string._msdn.%s",
468 priv->domain_dns_name);
469 r.in.req.req1.dest_dsa_guid = null_guid;
470 r.in.req.req1.options = 0;
474 status = dcerpc_drsuapi_DsReplicaUpdateRefs(p, mem_ctx, &r);
475 if (!NT_STATUS_IS_OK(status)) {
476 const char *errstr = nt_errstr(status);
477 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
478 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
480 printf("dcerpc_drsuapi_DsReplicaUpdateRefs failed - %s\n", errstr);
482 } else if (!W_ERROR_IS_OK(r.out.result)) {
483 printf("DsReplicaUpdateRefs failed - %s\n", win_errstr(r.out.result));
491 static BOOL test_DsGetNCChanges(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
492 struct DsPrivate *priv)
497 struct drsuapi_DsGetNCChanges r;
498 struct drsuapi_DsReplicaObjectIdentifier nc;
499 struct GUID null_guid;
500 struct dom_sid null_sid;
512 ZERO_STRUCT(null_guid);
513 ZERO_STRUCT(null_sid);
515 for (i=0; i < ARRAY_SIZE(array); i++) {
516 printf("testing DsGetNCChanges level %d\n",
519 r.in.bind_handle = &priv->bind_handle;
520 r.in.level = array[i].level;
522 switch (r.in.level) {
526 nc.dn = priv->domain_obj_dn?priv->domain_obj_dn:"";
528 r.in.req.req5.destination_dsa_guid = GUID_random();
529 r.in.req.req5.source_dsa_guid = null_guid;
530 r.in.req.req5.naming_context = &nc;
531 r.in.req.req5.highwatermark.tmp_highest_usn = 0;
532 r.in.req.req5.highwatermark.reserved_usn = 0;
533 r.in.req.req5.highwatermark.highest_usn = 0;
534 r.in.req.req5.uptodateness_vector = NULL;
535 r.in.req.req5.replica_flags = 0;
536 if (lp_parm_bool(-1, "drsuapi","compression", False)) {
537 r.in.req.req5.replica_flags |= DRSUAPI_DS_REPLICA_NEIGHBOUR_COMPRESS_CHANGES;
539 r.in.req.req5.unknown2 = 0;
540 r.in.req.req5.unknown3 = 0;
541 r.in.req.req5.unknown4 = 0;
542 r.in.req.req5.h1 = 0;
548 nc.dn = priv->domain_obj_dn?priv->domain_obj_dn:"";
550 r.in.req.req8.destination_dsa_guid = GUID_random();
551 r.in.req.req8.source_dsa_guid = null_guid;
552 r.in.req.req8.naming_context = &nc;
553 r.in.req.req8.highwatermark.tmp_highest_usn = 0;
554 r.in.req.req8.highwatermark.reserved_usn = 0;
555 r.in.req.req8.highwatermark.highest_usn = 0;
556 r.in.req.req8.uptodateness_vector = NULL;
557 r.in.req.req8.replica_flags = 0;
558 if (lp_parm_bool(-1,"drsuapi","compression",False)) {
559 r.in.req.req8.replica_flags |= DRSUAPI_DS_REPLICA_NEIGHBOUR_COMPRESS_CHANGES;
561 if (lp_parm_bool(-1,"drsuapi","neighbour_writeable",True)) {
562 r.in.req.req8.replica_flags |= DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE;
564 r.in.req.req8.replica_flags |= DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP
565 | DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS
566 | DRSUAPI_DS_REPLICA_NEIGHBOUR_RETURN_OBJECT_PARENTS
567 | DRSUAPI_DS_REPLICA_NEIGHBOUR_NEVER_SYNCED
569 r.in.req.req8.unknown2 = 402;
570 r.in.req.req8.unknown3 = 402116;
571 r.in.req.req8.unknown4 = 0;
572 r.in.req.req8.h1 = 0;
573 r.in.req.req8.unique_ptr1 = 0;
574 r.in.req.req8.unique_ptr2 = 0;
575 r.in.req.req8.ctr12.count = 0;
576 r.in.req.req8.ctr12.array = NULL;
581 status = dcerpc_drsuapi_DsGetNCChanges(p, mem_ctx, &r);
582 if (!NT_STATUS_IS_OK(status)) {
583 const char *errstr = nt_errstr(status);
584 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
585 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
587 printf("dcerpc_drsuapi_DsGetNCChanges failed - %s\n", errstr);
589 } else if (!W_ERROR_IS_OK(r.out.result)) {
590 printf("DsGetNCChanges failed - %s\n", win_errstr(r.out.result));
598 BOOL test_DsUnbind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
599 struct DsPrivate *priv)
602 struct drsuapi_DsUnbind r;
605 r.in.bind_handle = &priv->bind_handle;
606 r.out.bind_handle = &priv->bind_handle;
608 printf("testing DsUnbind\n");
610 status = dcerpc_drsuapi_DsUnbind(p, mem_ctx, &r);
611 if (!NT_STATUS_IS_OK(status)) {
612 const char *errstr = nt_errstr(status);
613 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
614 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
616 printf("dcerpc_drsuapi_DsUnbind failed - %s\n", errstr);
618 } else if (!W_ERROR_IS_OK(r.out.result)) {
619 printf("DsBind failed - %s\n", win_errstr(r.out.result));
626 BOOL torture_rpc_drsuapi(void)
629 struct dcerpc_pipe *p;
632 struct DsPrivate priv;
634 mem_ctx = talloc_init("torture_rpc_drsuapi");
636 status = torture_rpc_connection(mem_ctx,
638 &dcerpc_table_drsuapi);
639 if (!NT_STATUS_IS_OK(status)) {
640 talloc_free(mem_ctx);
644 printf("Connected to DRAUAPI pipe\n");
648 ret &= test_DsBind(p, mem_ctx, &priv);
650 ret &= test_DsGetDCInfo(p, mem_ctx, &priv);
652 ret &= test_DsCrackNames(p, mem_ctx, &priv, priv.dcinfo.netbios_name);
654 ret &= test_DsWriteAccountSpn(p, mem_ctx, &priv);
656 ret &= test_DsReplicaGetInfo(p, mem_ctx, &priv);
658 ret &= test_DsReplicaSync(p, mem_ctx, &priv);
660 ret &= test_DsReplicaUpdateRefs(p, mem_ctx, &priv);
662 ret &= test_DsGetNCChanges(p, mem_ctx, &priv);
664 ret &= test_DsUnbind(p, mem_ctx, &priv);
666 talloc_free(mem_ctx);