r5799: more DsGetNCChanges updates, I'm starting to understand it...
[bbaumbach/samba-autobuild/.git] / source4 / torture / rpc / drsuapi.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    DRSUapi tests
5
6    Copyright (C) Andrew Tridgell 2003
7    Copyright (C) Stefan (metze) Metzmacher 2004
8    
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.
13    
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.
18    
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.
22 */
23
24 #include "includes.h"
25 #include "librpc/gen_ndr/ndr_drsuapi.h"
26
27 struct DsPrivate {
28         struct policy_handle bind_handle;
29         struct GUID bind_guid;
30         const char *domain_obj_dn;
31         const char *domain_guid_str;
32         const char *domain_dns_name;
33         struct GUID domain_guid;
34         struct drsuapi_DsGetDCInfo2 dcinfo;
35 };
36
37 static BOOL test_DsBind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
38                       struct DsPrivate *priv)
39 {
40         NTSTATUS status;
41         struct drsuapi_DsBind r;
42         BOOL ret = True;
43
44         GUID_from_string(DRSUAPI_DS_BIND_GUID, &priv->bind_guid);
45
46         r.in.bind_guid = &priv->bind_guid;
47         r.in.bind_info = NULL;
48         r.out.bind_handle = &priv->bind_handle;
49
50         printf("testing DsBind\n");
51
52         status = dcerpc_drsuapi_DsBind(p, mem_ctx, &r);
53         if (!NT_STATUS_IS_OK(status)) {
54                 const char *errstr = nt_errstr(status);
55                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
56                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
57                 }
58                 printf("dcerpc_drsuapi_DsBind failed - %s\n", errstr);
59                 ret = False;
60         } else if (!W_ERROR_IS_OK(r.out.result)) {
61                 printf("DsBind failed - %s\n", win_errstr(r.out.result));
62                 ret = False;
63         }
64
65         return ret;
66 }
67
68 static BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
69                       struct DsPrivate *priv)
70 {
71         NTSTATUS status;
72         struct drsuapi_DsCrackNames r;
73         struct drsuapi_DsNameString names[1];
74         BOOL ret = True;
75         const char *dns_domain;
76         const char *nt4_domain;
77         const char *FQDN_1779_name;
78
79         ZERO_STRUCT(r);
80         r.in.bind_handle                = &priv->bind_handle;
81         r.in.level                      = 1;
82         r.in.req.req1.unknown1          = 0x000004e4;
83         r.in.req.req1.unknown2          = 0x00000407;
84         r.in.req.req1.count             = 1;
85         r.in.req.req1.names             = names;
86         r.in.req.req1.format_flags      = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
87
88         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_CANONICAL;
89         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
90         names[0].str = talloc_asprintf(mem_ctx, "%s/", lp_realm());
91
92         printf("testing DsCrackNames with name '%s' desired format:%d\n",
93                         names[0].str, r.in.req.req1.format_desired);
94
95         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
96         if (!NT_STATUS_IS_OK(status)) {
97                 const char *errstr = nt_errstr(status);
98                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
99                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
100                 }
101                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
102                 ret = False;
103         } else if (!W_ERROR_IS_OK(r.out.result)) {
104                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
105                 ret = False;
106         }
107
108         if (!ret) {
109                 return ret;
110         }
111
112         dns_domain = r.out.ctr.ctr1->array[0].dns_domain_name;
113         nt4_domain = r.out.ctr.ctr1->array[0].result_name;
114
115         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_GUID;
116
117         printf("testing DsCrackNames with name '%s' desired format:%d\n",
118                         names[0].str, r.in.req.req1.format_desired);
119
120         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
121         if (!NT_STATUS_IS_OK(status)) {
122                 const char *errstr = nt_errstr(status);
123                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
124                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
125                 }
126                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
127                 ret = False;
128         } else if (!W_ERROR_IS_OK(r.out.result)) {
129                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
130                 ret = False;
131         }
132
133         if (!ret) {
134                 return ret;
135         }
136
137         priv->domain_dns_name = r.out.ctr.ctr1->array[0].dns_domain_name;
138         priv->domain_guid_str = r.out.ctr.ctr1->array[0].result_name;
139         GUID_from_string(priv->domain_guid_str, &priv->domain_guid);
140
141
142         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_GUID;
143         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
144         names[0].str = priv->domain_guid_str;
145
146         printf("testing DsCrackNames with name '%s' desired format:%d\n",
147                         names[0].str, r.in.req.req1.format_desired);
148
149         status = dcerpc_drsuapi_DsCrackNames(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);
154                 }
155                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
156                 ret = False;
157         } else if (!W_ERROR_IS_OK(r.out.result)) {
158                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
159                 ret = False;
160         }
161
162         if (!ret) {
163                 return ret;
164         }
165
166         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
167         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
168         names[0].str = nt4_domain;
169
170         printf("testing DsCrackNames with name '%s' desired format:%d\n",
171                         names[0].str, r.in.req.req1.format_desired);
172
173         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
174         if (!NT_STATUS_IS_OK(status)) {
175                 const char *errstr = nt_errstr(status);
176                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
177                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
178                 }
179                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
180                 ret = False;
181         } else if (!W_ERROR_IS_OK(r.out.result)) {
182                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
183                 ret = False;
184         }
185
186         if (!ret) {
187                 return ret;
188         }
189
190         priv->domain_obj_dn = r.out.ctr.ctr1->array[0].result_name;
191
192         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
193         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
194         names[0].str = talloc_asprintf(mem_ctx, "%s%s$", nt4_domain, priv->dcinfo.netbios_name);
195
196         printf("testing DsCrackNames with name '%s' desired format:%d\n",
197                         names[0].str, r.in.req.req1.format_desired);
198
199         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
200         if (!NT_STATUS_IS_OK(status)) {
201                 const char *errstr = nt_errstr(status);
202                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
203                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
204                 }
205                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
206                 ret = False;
207         } else if (!W_ERROR_IS_OK(r.out.result)) {
208                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
209                 ret = False;
210         }
211
212         if (!ret) {
213                 return ret;
214         }
215
216         FQDN_1779_name = r.out.ctr.ctr1->array[0].result_name;
217
218         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
219         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_CANONICAL;
220         names[0].str = FQDN_1779_name;
221
222         printf("testing DsCrackNames with name '%s' desired format:%d\n",
223                         names[0].str, r.in.req.req1.format_desired);
224
225         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
226         if (!NT_STATUS_IS_OK(status)) {
227                 const char *errstr = nt_errstr(status);
228                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
229                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
230                 }
231                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
232                 ret = False;
233         } else if (!W_ERROR_IS_OK(r.out.result)) {
234                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
235                 ret = False;
236         }
237
238         if (!ret) {
239                 return ret;
240         }
241
242         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_DISPLAY;
243
244         printf("testing DsCrackNames with name '%s' desired format:%d\n",
245                         names[0].str, r.in.req.req1.format_desired);
246
247         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
248         if (!NT_STATUS_IS_OK(status)) {
249                 const char *errstr = nt_errstr(status);
250                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
251                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
252                 }
253                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
254                 ret = False;
255         } else if (!W_ERROR_IS_OK(r.out.result)) {
256                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
257                 ret = False;
258         }
259
260         if (!ret) {
261                 return ret;
262         }
263
264         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_GUID;
265
266         printf("testing DsCrackNames with name '%s' desired format:%d\n",
267                         names[0].str, r.in.req.req1.format_desired);
268
269         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
270         if (!NT_STATUS_IS_OK(status)) {
271                 const char *errstr = nt_errstr(status);
272                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
273                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
274                 }
275                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
276                 ret = False;
277         } else if (!W_ERROR_IS_OK(r.out.result)) {
278                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
279                 ret = False;
280         }
281
282         if (!ret) {
283                 return ret;
284         }
285
286         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL;
287
288         printf("testing DsCrackNames with name '%s' desired format:%d\n",
289                         names[0].str, r.in.req.req1.format_desired);
290
291         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
292         if (!NT_STATUS_IS_OK(status)) {
293                 const char *errstr = nt_errstr(status);
294                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
295                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
296                 }
297                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
298                 ret = False;
299         } else if (!W_ERROR_IS_OK(r.out.result)) {
300                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
301                 ret = False;
302         }
303
304         if (!ret) {
305                 return ret;
306         }
307
308         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL;
309
310         printf("testing DsCrackNames with name '%s' desired format:%d\n",
311                         names[0].str, r.in.req.req1.format_desired);
312
313         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
314         if (!NT_STATUS_IS_OK(status)) {
315                 const char *errstr = nt_errstr(status);
316                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
317                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
318                 }
319                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
320                 ret = False;
321         } else if (!W_ERROR_IS_OK(r.out.result)) {
322                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
323                 ret = False;
324         }
325
326         if (!ret) {
327                 return ret;
328         }
329
330         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_GUID;
331         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
332         names[0].str = GUID_string2(mem_ctx, &priv->dcinfo.site_guid);
333
334         printf("testing DsCrackNames with Site GUID '%s' desired format:%d\n",
335                         names[0].str, r.in.req.req1.format_desired);
336
337         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
338         if (!NT_STATUS_IS_OK(status)) {
339                 const char *errstr = nt_errstr(status);
340                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
341                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
342                 }
343                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
344                 ret = False;
345         } else if (!W_ERROR_IS_OK(r.out.result)) {
346                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
347                 ret = False;
348         }
349
350         if (!ret) {
351                 return ret;
352         }
353
354         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
355         names[0].str = GUID_string2(mem_ctx, &priv->dcinfo.computer_guid);
356
357         printf("testing DsCrackNames with Computer GUID '%s' desired format:%d\n",
358                         names[0].str, r.in.req.req1.format_desired);
359
360         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
361         if (!NT_STATUS_IS_OK(status)) {
362                 const char *errstr = nt_errstr(status);
363                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
364                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
365                 }
366                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
367                 ret = False;
368         } else if (!W_ERROR_IS_OK(r.out.result)) {
369                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
370                 ret = False;
371         }
372
373         if (!ret) {
374                 return ret;
375         }
376
377         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_GUID;
378         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
379         names[0].str = GUID_string2(mem_ctx, &priv->dcinfo.server_guid);
380
381         printf("testing DsCrackNames with Server GUID '%s' desired format:%d\n",
382                         names[0].str, r.in.req.req1.format_desired);
383
384         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
385         if (!NT_STATUS_IS_OK(status)) {
386                 const char *errstr = nt_errstr(status);
387                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
388                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
389                 }
390                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
391                 ret = False;
392         } else if (!W_ERROR_IS_OK(r.out.result)) {
393                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
394                 ret = False;
395         }
396
397         if (!ret) {
398                 return ret;
399         }
400
401         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_GUID;
402         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
403         names[0].str = GUID_string2(mem_ctx, &priv->dcinfo.ntds_guid);
404
405         printf("testing DsCrackNames with NTDS GUID '%s' desired format:%d\n",
406                         names[0].str, r.in.req.req1.format_desired);
407
408         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
409         if (!NT_STATUS_IS_OK(status)) {
410                 const char *errstr = nt_errstr(status);
411                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
412                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
413                 }
414                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
415                 ret = False;
416         } else if (!W_ERROR_IS_OK(r.out.result)) {
417                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
418                 ret = False;
419         }
420
421         if (!ret) {
422                 return ret;
423         }
424
425         r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_GUID;
426         r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
427         names[0].str = GUID_string2(mem_ctx, &priv->bind_guid);
428
429         printf("testing DsCrackNames with BIND GUID '%s' desired format:%d\n",
430                         names[0].str, r.in.req.req1.format_desired);
431
432         status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
433         if (!NT_STATUS_IS_OK(status)) {
434                 const char *errstr = nt_errstr(status);
435                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
436                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
437                 }
438                 printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
439                 ret = False;
440         } else if (!W_ERROR_IS_OK(r.out.result)) {
441                 printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
442                 ret = False;
443         }
444
445         if (!ret) {
446                 return ret;
447         }
448
449         return ret;
450 }
451
452 static BOOL test_DsGetDCInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
453                       struct DsPrivate *priv)
454 {
455         NTSTATUS status;
456         struct drsuapi_DsGetDomainControllerInfo r;
457         BOOL ret = True;
458
459         r.in.bind_handle = &priv->bind_handle;
460         r.in.level = 1;
461
462         r.in.req.req1.domain_name = talloc_strdup(mem_ctx, lp_realm());
463         r.in.req.req1.level = 1;
464
465         printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
466                         r.in.req.req1.level, r.in.req.req1.domain_name);
467
468         status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
469         if (!NT_STATUS_IS_OK(status)) {
470                 const char *errstr = nt_errstr(status);
471                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
472                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
473                 }
474                 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
475                         "    with dns domain failed - %s\n",
476                         r.in.req.req1.level, errstr);
477                 ret = False;
478         } else if (!W_ERROR_IS_OK(r.out.result)) {
479                 printf("DsGetDomainControllerInfo level %d\n"
480                         "    with dns domain failed - %s\n",
481                         r.in.req.req1.level, win_errstr(r.out.result));
482                 ret = False;
483         }
484
485         r.in.req.req1.level = 2;
486
487         printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
488                         r.in.req.req1.level, r.in.req.req1.domain_name);
489
490         status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
491         if (!NT_STATUS_IS_OK(status)) {
492                 const char *errstr = nt_errstr(status);
493                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
494                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
495                 }
496                 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
497                         "    with dns domain failed - %s\n",
498                         r.in.req.req1.level, errstr);
499                 ret = False;
500         } else if (!W_ERROR_IS_OK(r.out.result)) {
501                 printf("DsGetDomainControllerInfo level %d\n"
502                         "    with dns domain failed - %s\n",
503                         r.in.req.req1.level, win_errstr(r.out.result));
504                 ret = False;
505         } else {
506                 if (r.out.ctr.ctr2.count > 0) {
507                         priv->dcinfo    = r.out.ctr.ctr2.array[0];
508                 }
509         }
510
511         r.in.req.req1.level = -1;
512
513         printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
514                         r.in.req.req1.level, r.in.req.req1.domain_name);
515
516         status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
517         if (!NT_STATUS_IS_OK(status)) {
518                 const char *errstr = nt_errstr(status);
519                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
520                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
521                 }
522                 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
523                         "    with dns domain failed - %s\n",
524                         r.in.req.req1.level, errstr);
525                 ret = False;
526         } else if (!W_ERROR_IS_OK(r.out.result)) {
527                 printf("DsGetDomainControllerInfo level %d\n"
528                         "    with dns domain failed - %s\n",
529                         r.in.req.req1.level, win_errstr(r.out.result));
530                 ret = False;
531         }
532
533         r.in.req.req1.domain_name = talloc_strdup(mem_ctx, lp_workgroup());
534         r.in.req.req1.level = 2;
535
536         printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
537                         r.in.req.req1.level, r.in.req.req1.domain_name);
538
539         status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
540         if (!NT_STATUS_IS_OK(status)) {
541                 const char *errstr = nt_errstr(status);
542                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
543                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
544                 }
545                 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
546                         "    with netbios domain failed - %s\n",
547                         r.in.req.req1.level, errstr);
548                 ret = False;
549         } else if (!W_ERROR_IS_OK(r.out.result)) {
550                 printf("DsGetDomainControllerInfo level %d\n"
551                         "    with netbios domain failed - %s\n",
552                         r.in.req.req1.level, win_errstr(r.out.result));
553                 ret = False;
554         }
555
556         r.in.req.req1.domain_name = "__UNKNOWN_DOMAIN__";
557         r.in.req.req1.level = 2;
558
559         printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
560                         r.in.req.req1.level, r.in.req.req1.domain_name);
561
562         status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
563         if (!NT_STATUS_IS_OK(status)) {
564                 const char *errstr = nt_errstr(status);
565                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
566                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
567                 }
568                 printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
569                         "    with invalid domain failed - %s\n",
570                         r.in.req.req1.level, errstr);
571                 ret = False;
572         } else if (!W_ERROR_EQUAL(r.out.result, WERR_DS_OBJ_NOT_FOUND)) {
573                 printf("DsGetDomainControllerInfo level %d\n"
574                         "    with invalid domain not expected error (WERR_DS_OBJ_NOT_FOUND) - %s\n",
575                         r.in.req.req1.level, win_errstr(r.out.result));
576                 ret = False;
577         }
578
579         return ret;
580 }
581
582 static BOOL test_DsWriteAccountSpn(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
583                         struct DsPrivate *priv)
584 {
585         NTSTATUS status;
586         struct drsuapi_DsWriteAccountSpn r;
587         struct drsuapi_DsNameString names[2];
588         BOOL ret = True;
589
590         r.in.bind_handle                = &priv->bind_handle;
591         r.in.level                      = 1;
592
593         printf("testing DsWriteAccountSpn\n");
594
595         r.in.req.req1.operation = DRSUAPI_DS_SPN_OPERATION_ADD;
596         r.in.req.req1.unknown1  = 0;
597         r.in.req.req1.object_dn = priv->dcinfo.computer_dn;
598         r.in.req.req1.count     = 2;
599         r.in.req.req1.spn_names = names;
600         names[0].str = talloc_asprintf(mem_ctx, "smbtortureSPN/%s",priv->dcinfo.netbios_name);
601         names[1].str = talloc_asprintf(mem_ctx, "smbtortureSPN/%s",priv->dcinfo.dns_name);
602
603         status = dcerpc_drsuapi_DsWriteAccountSpn(p, mem_ctx, &r);
604         if (!NT_STATUS_IS_OK(status)) {
605                 const char *errstr = nt_errstr(status);
606                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
607                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
608                 }
609                 printf("dcerpc_drsuapi_DsWriteAccountSpn failed - %s\n", errstr);
610                 ret = False;
611         } else if (!W_ERROR_IS_OK(r.out.result)) {
612                 printf("DsWriteAccountSpn failed - %s\n", win_errstr(r.out.result));
613                 ret = False;
614         }
615
616         r.in.req.req1.operation = DRSUAPI_DS_SPN_OPERATION_DELETE;
617         r.in.req.req1.unknown1  = 0;
618
619         status = dcerpc_drsuapi_DsWriteAccountSpn(p, mem_ctx, &r);
620         if (!NT_STATUS_IS_OK(status)) {
621                 const char *errstr = nt_errstr(status);
622                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
623                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
624                 }
625                 printf("dcerpc_drsuapi_DsWriteAccountSpn failed - %s\n", errstr);
626                 ret = False;
627         } else if (!W_ERROR_IS_OK(r.out.result)) {
628                 printf("DsWriteAccountSpn failed - %s\n", win_errstr(r.out.result));
629                 ret = False;
630         }
631
632         return ret;
633 }
634
635 static BOOL test_DsReplicaGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
636                         struct DsPrivate *priv)
637 {
638         NTSTATUS status;
639         struct drsuapi_DsReplicaGetInfo r;
640         BOOL ret = True;
641         int i;
642         struct {
643                 int32_t level;
644                 int32_t infotype;
645                 const char *obj_dn;
646         } array[] = {
647                 {       
648                         DRSUAPI_DS_REPLICA_GET_INFO,
649                         DRSUAPI_DS_REPLICA_INFO_NEIGHBORS,
650                         NULL
651                 },{
652                         DRSUAPI_DS_REPLICA_GET_INFO,
653                         DRSUAPI_DS_REPLICA_INFO_CURSORS,
654                         NULL
655                 },{
656                         DRSUAPI_DS_REPLICA_GET_INFO,
657                         DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA,
658                         NULL
659                 },{
660                         DRSUAPI_DS_REPLICA_GET_INFO,
661                         DRSUAPI_DS_REPLICA_INFO_KCC_DSA_CONNECT_FAILURES,
662                         NULL
663                 },{
664                         DRSUAPI_DS_REPLICA_GET_INFO,
665                         DRSUAPI_DS_REPLICA_INFO_KCC_DSA_LINK_FAILURES,
666                         NULL
667                 },{
668                         DRSUAPI_DS_REPLICA_GET_INFO,
669                         DRSUAPI_DS_REPLICA_INFO_PENDING_OPS,
670                         NULL
671                 },{
672                         DRSUAPI_DS_REPLICA_GET_INFO2,
673                         DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA,
674                         NULL
675                 },{
676                         DRSUAPI_DS_REPLICA_GET_INFO2,
677                         DRSUAPI_DS_REPLICA_INFO_CURSORS2,
678                         NULL
679                 },{
680                         DRSUAPI_DS_REPLICA_GET_INFO2,
681                         DRSUAPI_DS_REPLICA_INFO_CURSORS3,
682                         NULL
683                 },{
684                         DRSUAPI_DS_REPLICA_GET_INFO2,
685                         DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA2,
686                         NULL
687                 },{
688                         DRSUAPI_DS_REPLICA_GET_INFO2,
689                         DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA2,
690                         NULL
691                 },{
692                         DRSUAPI_DS_REPLICA_GET_INFO2,
693                         DRSUAPI_DS_REPLICA_INFO_NEIGHBORS02,
694                         NULL
695                 },{
696                         DRSUAPI_DS_REPLICA_GET_INFO2,
697                         DRSUAPI_DS_REPLICA_INFO_CONNECTIONS04,
698                         "__IGNORED__"
699                 },{
700                         DRSUAPI_DS_REPLICA_GET_INFO2,
701                         DRSUAPI_DS_REPLICA_INFO_CURSURS05,
702                         NULL
703                 },{
704                         DRSUAPI_DS_REPLICA_GET_INFO2,
705                         DRSUAPI_DS_REPLICA_INFO_06,
706                         NULL
707                 }
708         };
709
710         r.in.bind_handle        = &priv->bind_handle;
711
712         for (i=0; i < ARRAY_SIZE(array); i++) {
713                 const char *object_dn;
714
715                 printf("testing DsReplicaGetInfo level %d infotype %d\n",
716                         array[i].level, array[i].infotype);
717
718                 object_dn = (array[i].obj_dn ? array[i].obj_dn : priv->domain_obj_dn);
719
720                 r.in.level = array[i].level;
721                 switch(r.in.level) {
722                 case DRSUAPI_DS_REPLICA_GET_INFO:
723                         r.in.req.req1.info_type = array[i].infotype;
724                         r.in.req.req1.object_dn = object_dn;
725                         ZERO_STRUCT(r.in.req.req1.guid1);
726                         break;
727                 case DRSUAPI_DS_REPLICA_GET_INFO2:
728                         r.in.req.req2.info_type = array[i].infotype;
729                         r.in.req.req2.object_dn = object_dn;
730                         ZERO_STRUCT(r.in.req.req1.guid1);
731                         r.in.req.req2.unknown1  = 0;
732                         r.in.req.req2.string1   = NULL;
733                         r.in.req.req2.string2   = NULL;
734                         r.in.req.req2.unknown2  = 0;
735                         break;
736                 }
737
738                 status = dcerpc_drsuapi_DsReplicaGetInfo(p, mem_ctx, &r);
739                 if (!NT_STATUS_IS_OK(status)) {
740                         const char *errstr = nt_errstr(status);
741                         if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
742                                 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
743                         }
744                         if (p->last_fault_code != DCERPC_FAULT_INVALID_TAG) {
745                                 printf("dcerpc_drsuapi_DsReplicaGetInfo failed - %s\n", errstr);
746                                 ret = False;
747                         } else {
748                                 printf("DsReplicaGetInfo level %d and/or infotype %d not supported by server\n",
749                                         array[i].level, array[i].infotype);
750                         }
751                 } else if (!W_ERROR_IS_OK(r.out.result)) {
752                         printf("DsReplicaGetInfo failed - %s\n", win_errstr(r.out.result));
753                         ret = False;
754                 }
755         }
756
757         return ret;
758 }
759
760 static BOOL test_DsReplicaSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
761                         struct DsPrivate *priv)
762 {
763         NTSTATUS status;
764         BOOL ret = True;
765         int i;
766         struct drsuapi_DsReplicaSync r;
767         struct drsuapi_DsReplicaObjectIdentifier nc;
768         struct GUID null_guid;
769         struct dom_sid null_sid;
770         struct {
771                 int32_t level;
772         } array[] = {
773                 {       
774                         1
775                 }
776         };
777
778         if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
779                 printf("DsReplicaSync disabled - enable dangerous tests to use\n");
780                 return True;
781         }
782
783         ZERO_STRUCT(null_guid);
784         ZERO_STRUCT(null_sid);
785
786         r.in.bind_handle        = &priv->bind_handle;
787
788         for (i=0; i < ARRAY_SIZE(array); i++) {
789                 printf("testing DsReplicaSync level %d\n",
790                         array[i].level);
791
792                 r.in.level = array[i].level;
793                 switch(r.in.level) {
794                 case 1:
795                         nc.guid                                 = null_guid;
796                         nc.sid                                  = null_sid;
797                         nc.dn                                   = priv->domain_obj_dn?priv->domain_obj_dn:"";
798
799                         r.in.req.req1.naming_context            = &nc;
800                         r.in.req.req1.guid1                     = priv->dcinfo.ntds_guid;
801                         r.in.req.req1.string1                   = NULL;
802                         r.in.req.req1.options                   = 16;
803                         break;
804                 }
805
806                 status = dcerpc_drsuapi_DsReplicaSync(p, mem_ctx, &r);
807                 if (!NT_STATUS_IS_OK(status)) {
808                         const char *errstr = nt_errstr(status);
809                         if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
810                                 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
811                         }
812                         printf("dcerpc_drsuapi_DsReplicaSync failed - %s\n", errstr);
813                         ret = False;
814                 } else if (!W_ERROR_IS_OK(r.out.result)) {
815                         printf("DsReplicaSync failed - %s\n", win_errstr(r.out.result));
816                         ret = False;
817                 }
818         }
819
820         return ret;
821 }
822
823 static BOOL test_DsReplicaUpdateRefs(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
824                         struct DsPrivate *priv)
825 {
826         NTSTATUS status;
827         BOOL ret = True;
828         int i;
829         struct drsuapi_DsReplicaUpdateRefs r;
830         struct drsuapi_DsReplicaObjectIdentifier nc;
831         struct GUID null_guid;
832         struct dom_sid null_sid;
833         struct {
834                 int32_t level;
835         } array[] = {
836                 {       
837                         1
838                 }
839         };
840
841         ZERO_STRUCT(null_guid);
842         ZERO_STRUCT(null_sid);
843
844         r.in.bind_handle        = &priv->bind_handle;
845
846         for (i=0; i < ARRAY_SIZE(array); i++) {
847                 printf("testing DsReplicaUpdateRefs level %d\n",
848                         array[i].level);
849
850                 r.in.level = array[i].level;
851                 switch(r.in.level) {
852                 case 1:
853                         nc.guid                         = null_guid;
854                         nc.sid                          = null_sid;
855                         nc.dn                           = priv->domain_obj_dn?priv->domain_obj_dn:"";
856
857                         r.in.req.req1.naming_context    = &nc;
858                         r.in.req.req1.dest_dsa_dns_name = talloc_asprintf(mem_ctx, "__some_dest_dsa_guid_string._msdn.%s",
859                                                                                 priv->domain_dns_name);
860                         r.in.req.req1.dest_dsa_guid     = null_guid;
861                         r.in.req.req1.options           = 0;
862                         break;
863                 }
864
865                 status = dcerpc_drsuapi_DsReplicaUpdateRefs(p, mem_ctx, &r);
866                 if (!NT_STATUS_IS_OK(status)) {
867                         const char *errstr = nt_errstr(status);
868                         if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
869                                 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
870                         }
871                         printf("dcerpc_drsuapi_DsReplicaUpdateRefs failed - %s\n", errstr);
872                         ret = False;
873                 } else if (!W_ERROR_IS_OK(r.out.result)) {
874                         printf("DsReplicaUpdateRefs failed - %s\n", win_errstr(r.out.result));
875                         ret = False;
876                 }
877         }
878
879         return ret;
880 }
881
882 static BOOL test_DsGetNCChanges(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
883                         struct DsPrivate *priv)
884 {
885         NTSTATUS status;
886         BOOL ret = True;
887         int i;
888         struct drsuapi_DsGetNCChanges r;
889         struct drsuapi_DsReplicaObjectIdentifier nc;
890         struct GUID null_guid;
891         struct dom_sid null_sid;
892         struct {
893                 int32_t level;
894         } array[] = {
895                 {       
896                         5
897                 },
898                 {       
899                         8
900                 }
901         };
902
903         ZERO_STRUCT(null_guid);
904         ZERO_STRUCT(null_sid);
905         
906         for (i=0; i < ARRAY_SIZE(array); i++) {
907                 printf("testing DsGetNCChanges level %d\n",
908                         array[i].level);
909
910                 ZERO_STRUCT(r.in);
911                 r.in.bind_handle        = &priv->bind_handle;
912                 r.in.level              = array[i].level;
913
914                 switch (r.in.level) {
915                 case 5:
916                         nc.guid                         = null_guid;
917                         nc.sid                          = null_sid;
918                         nc.dn                           = talloc_asprintf(mem_ctx, "CN=Schema,CN=Configuration,%s",
919                                                                           priv->domain_obj_dn?priv->domain_obj_dn:"");
920                         nc.dn                           = priv->domain_obj_dn?priv->domain_obj_dn:"";
921
922                         r.in.req.req5.naming_context    = &nc;
923                         r.in.req.req5.usn1.usn1         = 0;
924                         break;
925                 case 8:
926                         nc.guid                         = null_guid;
927                         nc.sid                          = null_sid;
928                         nc.dn                           = priv->domain_obj_dn?priv->domain_obj_dn:"";
929
930                         r.in.req.req8.naming_context    = &nc;
931                         r.in.req.req8.usn1.usn1         = 0;
932                         break;
933                 }
934
935                 status = dcerpc_drsuapi_DsGetNCChanges(p, mem_ctx, &r);
936                 if (!NT_STATUS_IS_OK(status)) {
937                         const char *errstr = nt_errstr(status);
938                         if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
939                                 errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
940                         }
941                         printf("dcerpc_drsuapi_DsGetNCChanges failed - %s\n", errstr);
942                         ret = False;
943                 } else if (!W_ERROR_IS_OK(r.out.result)) {
944                         printf("DsGetNCChanges failed - %s\n", win_errstr(r.out.result));
945                         ret = False;
946                 }
947         }
948
949         return ret;
950 }
951
952 static BOOL test_DsUnbind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
953                         struct DsPrivate *priv)
954 {
955         NTSTATUS status;
956         struct drsuapi_DsUnbind r;
957         BOOL ret = True;
958
959         r.in.bind_handle = &priv->bind_handle;
960         r.out.bind_handle = &priv->bind_handle;
961
962         printf("testing DsUnbind\n");
963
964         status = dcerpc_drsuapi_DsUnbind(p, mem_ctx, &r);
965         if (!NT_STATUS_IS_OK(status)) {
966                 const char *errstr = nt_errstr(status);
967                 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
968                         errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
969                 }
970                 printf("dcerpc_drsuapi_DsUnbind failed - %s\n", errstr);
971                 ret = False;
972         } else if (!W_ERROR_IS_OK(r.out.result)) {
973                 printf("DsBind failed - %s\n", win_errstr(r.out.result));
974                 ret = False;
975         }
976
977         return ret;
978 }
979
980 BOOL torture_rpc_drsuapi(void)
981 {
982         NTSTATUS status;
983         struct dcerpc_pipe *p;
984         TALLOC_CTX *mem_ctx;
985         BOOL ret = True;
986         struct DsPrivate priv;
987
988         status = torture_rpc_connection(&p, 
989                                         DCERPC_DRSUAPI_NAME,
990                                         DCERPC_DRSUAPI_UUID,
991                                         DCERPC_DRSUAPI_VERSION);
992         if (!NT_STATUS_IS_OK(status)) {
993                 return False;
994         }
995
996         printf("Connected to DRAUAPI pipe\n");
997
998         mem_ctx = talloc_init("torture_rpc_drsuapi");
999
1000         ZERO_STRUCT(priv);
1001
1002         ret &= test_DsBind(p, mem_ctx, &priv);
1003
1004         ret &= test_DsGetDCInfo(p, mem_ctx, &priv);
1005
1006         ret &= test_DsCrackNames(p, mem_ctx, &priv);
1007
1008         ret &= test_DsWriteAccountSpn(p, mem_ctx, &priv);
1009
1010         ret &= test_DsReplicaGetInfo(p, mem_ctx, &priv);
1011
1012         ret &= test_DsReplicaSync(p, mem_ctx, &priv);
1013
1014         ret &= test_DsReplicaUpdateRefs(p, mem_ctx, &priv);
1015
1016         ret &= test_DsGetNCChanges(p, mem_ctx, &priv);
1017
1018         ret &= test_DsUnbind(p, mem_ctx, &priv);
1019
1020         talloc_free(mem_ctx);
1021
1022         torture_rpc_close(p);
1023
1024         return ret;
1025 }