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