39bee441b73616e7dfb94e4cefa552b6e0f0c59d
[metze/samba/wip.git] / source3 / rpcclient / cmd_netlogon.c
1 /* 
2    Unix SMB/CIFS implementation.
3    RPC pipe client
4
5    Copyright (C) Tim Potter 2000
6    Copyright (C) Guenther Deschner 2008
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "rpcclient.h"
24 #include "../libcli/auth/libcli_auth.h"
25 #include "../librpc/gen_ndr/ndr_netlogon.h"
26 #include "../librpc/gen_ndr/ndr_netlogon_c.h"
27 #include "rpc_client/cli_netlogon.h"
28 #include "secrets.h"
29 #include "../libcli/auth/netlogon_creds_cli.h"
30 #include "rpc_client/util_netlogon.h"
31
32 static WERROR cmd_netlogon_logon_ctrl2(struct rpc_pipe_client *cli,
33                                        TALLOC_CTX *mem_ctx, int argc,
34                                        const char **argv)
35 {
36         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
37         WERROR werr;
38         const char *logon_server = cli->desthost;
39         enum netr_LogonControlCode function_code = NETLOGON_CONTROL_REDISCOVER;
40         uint32_t level = 1;
41         union netr_CONTROL_DATA_INFORMATION data;
42         union netr_CONTROL_QUERY_INFORMATION query;
43         const char *domain = lp_workgroup();
44         struct dcerpc_binding_handle *b = cli->binding_handle;
45         int i;
46 #define fn_code_level(x, item) { x, #x, #item }
47         struct {
48                 enum netr_LogonControlCode code;
49                 const char *name;
50                 const char *argument;
51         } supported_levels[] = {
52                 fn_code_level(NETLOGON_CONTROL_REDISCOVER, domain),
53                 fn_code_level(NETLOGON_CONTROL_TC_QUERY, domain),
54                 fn_code_level(NETLOGON_CONTROL_TRANSPORT_NOTIFY, domain),
55                 fn_code_level(NETLOGON_CONTROL_FIND_USER, user),
56                 fn_code_level(NETLOGON_CONTROL_CHANGE_PASSWORD, domain),
57                 fn_code_level(NETLOGON_CONTROL_TC_VERIFY, domain),
58                 fn_code_level(NETLOGON_CONTROL_SET_DBFLAG, debug_level),
59                 {0, 0, 0}
60         };
61 #undef fn_code_level
62         if ((argc > 5) || (argc < 2)) {
63                 fprintf(stderr, "Usage: %s <logon_server> <function_code> "
64                         "<level:1..4> <argument>\n", argv[0]);
65                 fprintf(stderr, "Supported combinations:\n");
66                 fprintf(stderr, "function_code\targument\n");
67                 for(i=0; supported_levels[i].code; i++) {
68                         fprintf(stderr, "%7d\t\t%s\t(%s)\n",
69                                 supported_levels[i].code,
70                                 supported_levels[i].argument,
71                                 supported_levels[i].name);
72                 }
73                 return WERR_OK;
74         }
75
76         if (argc >= 2) {
77                 logon_server = argv[1];
78         }
79
80         if (argc >= 3) {
81                 function_code = atoi(argv[2]);
82         }
83
84         if (argc >= 4) {
85                 level = atoi(argv[3]);
86         }
87
88         if (argc >= 5) {
89                 domain = argv[4];
90         }
91
92         switch (function_code) {
93                 case NETLOGON_CONTROL_REDISCOVER:
94                 case NETLOGON_CONTROL_TC_QUERY:
95                 case NETLOGON_CONTROL_CHANGE_PASSWORD:
96                 case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
97                 case NETLOGON_CONTROL_TC_VERIFY:
98                         data.domain = domain;
99                         break;
100                 case NETLOGON_CONTROL_FIND_USER:
101                         data.user = domain;
102                         break;
103                 case NETLOGON_CONTROL_SET_DBFLAG:
104                         data.debug_level = atoi(domain);
105                 default:
106                         break;
107         }
108
109         status = dcerpc_netr_LogonControl2(b, mem_ctx,
110                                           logon_server,
111                                           function_code,
112                                           level,
113                                           &data,
114                                           &query,
115                                           &werr);
116         if (!NT_STATUS_IS_OK(status)) {
117                 return ntstatus_to_werror(status);
118         }
119
120         if (!W_ERROR_IS_OK(werr)) {
121                 return werr;
122         }
123
124         /* Display results */
125
126         return werr;
127 }
128
129 static WERROR cmd_netlogon_getanydcname(struct rpc_pipe_client *cli, 
130                                         TALLOC_CTX *mem_ctx, int argc, 
131                                         const char **argv)
132 {
133         const char *dcname = NULL;
134         WERROR werr;
135         NTSTATUS status;
136         int old_timeout;
137         struct dcerpc_binding_handle *b = cli->binding_handle;
138
139         if (argc != 2) {
140                 fprintf(stderr, "Usage: %s domainname\n", argv[0]);
141                 return WERR_OK;
142         }
143
144         /* Make sure to wait for our DC's reply */
145         old_timeout = rpccli_set_timeout(cli, 30000); /* 30 seconds. */
146         rpccli_set_timeout(cli, MAX(old_timeout, 30000)); /* At least 30 sec */
147
148         status = dcerpc_netr_GetAnyDCName(b, mem_ctx,
149                                           cli->desthost,
150                                           argv[1],
151                                           &dcname,
152                                           &werr);
153         rpccli_set_timeout(cli, old_timeout);
154
155         if (!NT_STATUS_IS_OK(status)) {
156                 return ntstatus_to_werror(status);
157         }
158
159         if (!W_ERROR_IS_OK(werr)) {
160                 return werr;
161         }
162
163         /* Display results */
164
165         printf("%s\n", dcname);
166
167         return werr;
168 }
169
170 static WERROR cmd_netlogon_getdcname(struct rpc_pipe_client *cli,
171                                      TALLOC_CTX *mem_ctx, int argc,
172                                      const char **argv)
173 {
174         const char *dcname = NULL;
175         NTSTATUS status;
176         WERROR werr;
177         int old_timeout;
178         struct dcerpc_binding_handle *b = cli->binding_handle;
179
180         if (argc != 2) {
181                 fprintf(stderr, "Usage: %s domainname\n", argv[0]);
182                 return WERR_OK;
183         }
184
185         /* Make sure to wait for our DC's reply */
186         old_timeout = rpccli_set_timeout(cli, 30000); /* 30 seconds. */
187         rpccli_set_timeout(cli, MAX(30000, old_timeout)); /* At least 30 sec */
188
189         status = dcerpc_netr_GetDcName(b, mem_ctx,
190                                        cli->desthost,
191                                        argv[1],
192                                        &dcname,
193                                        &werr);
194         rpccli_set_timeout(cli, old_timeout);
195
196         if (!NT_STATUS_IS_OK(status)) {
197                 return ntstatus_to_werror(status);
198         }
199
200         if (!W_ERROR_IS_OK(werr)) {
201                 return werr;
202         }
203
204         /* Display results */
205
206         printf("%s\n", dcname);
207
208         return werr;
209 }
210
211 static WERROR cmd_netlogon_dsr_getdcname(struct rpc_pipe_client *cli,
212                                          TALLOC_CTX *mem_ctx, int argc,
213                                          const char **argv)
214 {
215         NTSTATUS result;
216         WERROR werr = WERR_OK;
217         uint32_t flags = DS_RETURN_DNS_NAME;
218         const char *server_name = cli->desthost;
219         const char *domain_name = NULL;
220         struct GUID domain_guid = GUID_zero();
221         struct GUID site_guid = GUID_zero();
222         struct netr_DsRGetDCNameInfo *info = NULL;
223         struct dcerpc_binding_handle *b = cli->binding_handle;
224
225         if (argc < 2) {
226                 fprintf(stderr, "Usage: %s [domain_name] [domain_guid] "
227                                 "[site_guid] [flags]\n", argv[0]);
228                 return WERR_OK;
229         }
230
231         if (argc >= 2)
232                 domain_name = argv[1];
233
234         if (argc >= 3) {
235                 if (!NT_STATUS_IS_OK(GUID_from_string(argv[2], &domain_guid))) {
236                         return WERR_NOT_ENOUGH_MEMORY;
237                 }
238         }
239
240         if (argc >= 4) {
241                 if (!NT_STATUS_IS_OK(GUID_from_string(argv[3], &site_guid))) {
242                         return WERR_NOT_ENOUGH_MEMORY;
243                 }
244         }
245
246         if (argc >= 5)
247                 sscanf(argv[4], "%x", &flags);
248
249         result = dcerpc_netr_DsRGetDCName(b, mem_ctx,
250                                           server_name,
251                                           domain_name,
252                                           &domain_guid,
253                                           &site_guid,
254                                           flags,
255                                           &info,
256                                           &werr);
257         if (!NT_STATUS_IS_OK(result)) {
258                 return ntstatus_to_werror(result);
259         }
260
261         if (W_ERROR_IS_OK(werr)) {
262                 d_printf("DsGetDcName gave: %s\n",
263                 NDR_PRINT_STRUCT_STRING(mem_ctx, netr_DsRGetDCNameInfo, info));
264                 return WERR_OK;
265         }
266
267         printf("rpccli_netlogon_dsr_getdcname returned %s\n",
268                win_errstr(werr));
269
270         return werr;
271 }
272
273 static WERROR cmd_netlogon_dsr_getdcnameex(struct rpc_pipe_client *cli,
274                                            TALLOC_CTX *mem_ctx, int argc,
275                                            const char **argv)
276 {
277         WERROR result;
278         NTSTATUS status;
279         uint32_t flags = DS_RETURN_DNS_NAME;
280         const char *server_name = cli->desthost;
281         const char *domain_name;
282         const char *site_name = NULL;
283         struct GUID domain_guid = GUID_zero();
284         struct netr_DsRGetDCNameInfo *info = NULL;
285         struct dcerpc_binding_handle *b = cli->binding_handle;
286
287         if (argc < 2) {
288                 fprintf(stderr, "Usage: %s [domain_name] [domain_guid] "
289                                 "[site_name] [flags]\n", argv[0]);
290                 return WERR_OK;
291         }
292
293         domain_name = argv[1];
294
295         if (argc >= 3) {
296                 if (!NT_STATUS_IS_OK(GUID_from_string(argv[2], &domain_guid))) {
297                         return WERR_NOT_ENOUGH_MEMORY;
298                 }
299         }
300
301         if (argc >= 4) {
302                 site_name = argv[3];
303         }
304
305         if (argc >= 5) {
306                 sscanf(argv[4], "%x", &flags);
307         }
308
309         status = dcerpc_netr_DsRGetDCNameEx(b, mem_ctx,
310                                             server_name,
311                                             domain_name,
312                                             &domain_guid,
313                                             site_name,
314                                             flags,
315                                             &info,
316                                             &result);
317         if (!NT_STATUS_IS_OK(status)) {
318                 return ntstatus_to_werror(status);
319         }
320
321         if (!W_ERROR_IS_OK(result)) {
322                 return result;
323         }
324
325         d_printf("DsRGetDCNameEx gave %s\n",
326                 NDR_PRINT_STRUCT_STRING(mem_ctx, netr_DsRGetDCNameInfo, info));
327
328         return result;
329 }
330
331 static WERROR cmd_netlogon_dsr_getdcnameex2(struct rpc_pipe_client *cli,
332                                             TALLOC_CTX *mem_ctx, int argc,
333                                             const char **argv)
334 {
335         WERROR result;
336         NTSTATUS status;
337         uint32_t flags = DS_RETURN_DNS_NAME;
338         const char *server_name = cli->desthost;
339         const char *domain_name = NULL;
340         const char *client_account = NULL;
341         uint32_t mask = 0;
342         const char *site_name = NULL;
343         struct GUID domain_guid = GUID_zero();
344         struct netr_DsRGetDCNameInfo *info = NULL;
345         struct dcerpc_binding_handle *b = cli->binding_handle;
346
347         if (argc < 2) {
348                 fprintf(stderr, "Usage: %s [client_account] [acb_mask] "
349                                 "[domain_name] [domain_guid] [site_name] "
350                                 "[flags]\n", argv[0]);
351                 return WERR_OK;
352         }
353
354         if (argc >= 2) {
355                 client_account = argv[1];
356         }
357
358         if (argc >= 3) {
359                 mask = atoi(argv[2]);
360         }
361
362         if (argc >= 4) {
363                 domain_name = argv[3];
364         }
365
366         if (argc >= 5) {
367                 if (!NT_STATUS_IS_OK(GUID_from_string(argv[4], &domain_guid))) {
368                         return WERR_NOT_ENOUGH_MEMORY;
369                 }
370         }
371
372         if (argc >= 6) {
373                 site_name = argv[5];
374         }
375
376         if (argc >= 7) {
377                 sscanf(argv[6], "%x", &flags);
378         }
379
380         status = dcerpc_netr_DsRGetDCNameEx2(b, mem_ctx,
381                                              server_name,
382                                              client_account,
383                                              mask,
384                                              domain_name,
385                                              &domain_guid,
386                                              site_name,
387                                              flags,
388                                              &info,
389                                              &result);
390         if (!NT_STATUS_IS_OK(status)) {
391                 return ntstatus_to_werror(status);
392         }
393
394         if (!W_ERROR_IS_OK(result)) {
395                 return result;
396         }
397
398         d_printf("DsRGetDCNameEx2 gave %s\n",
399                 NDR_PRINT_STRUCT_STRING(mem_ctx, netr_DsRGetDCNameInfo, info));
400
401         return result;
402 }
403
404
405 static WERROR cmd_netlogon_dsr_getsitename(struct rpc_pipe_client *cli,
406                                            TALLOC_CTX *mem_ctx, int argc,
407                                            const char **argv)
408 {
409         WERROR werr;
410         NTSTATUS status;
411         const char *sitename = NULL;
412         struct dcerpc_binding_handle *b = cli->binding_handle;
413
414         if (argc != 2) {
415                 fprintf(stderr, "Usage: %s computername\n", argv[0]);
416                 return WERR_OK;
417         }
418
419         status = dcerpc_netr_DsRGetSiteName(b, mem_ctx,
420                                             argv[1],
421                                             &sitename,
422                                             &werr);
423         if (!NT_STATUS_IS_OK(status)) {
424                 return ntstatus_to_werror(status);
425         }
426
427         if (!W_ERROR_IS_OK(werr)) {
428                 printf("rpccli_netlogon_dsr_gesitename returned %s\n",
429                        nt_errstr(werror_to_ntstatus(werr)));
430                 return werr;
431         }
432
433         printf("Computer %s is on Site: %s\n", argv[1], sitename);
434
435         return WERR_OK;
436 }
437
438 static WERROR cmd_netlogon_logon_ctrl(struct rpc_pipe_client *cli,
439                                       TALLOC_CTX *mem_ctx, int argc,
440                                       const char **argv)
441 {
442         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
443         WERROR werr;
444         const char *logon_server = cli->desthost;
445         enum netr_LogonControlCode function_code = 1;
446         uint32_t level = 1;
447         union netr_CONTROL_QUERY_INFORMATION info;
448         struct dcerpc_binding_handle *b = cli->binding_handle;
449
450         if (argc > 4) {
451                 fprintf(stderr, "Usage: %s <logon_server> <function_code> "
452                         "<level>\n", argv[0]);
453                 return WERR_OK;
454         }
455
456         if (argc >= 2) {
457                 logon_server = argv[1];
458         }
459
460         if (argc >= 3) {
461                 function_code = atoi(argv[2]);
462         }
463
464         if (argc >= 4) {
465                 level = atoi(argv[3]);
466         }
467
468         status = dcerpc_netr_LogonControl(b, mem_ctx,
469                                           logon_server,
470                                           function_code,
471                                           level,
472                                           &info,
473                                           &werr);
474         if (!NT_STATUS_IS_OK(status)) {
475                 return ntstatus_to_werror(status);
476         }
477
478         if (!W_ERROR_IS_OK(werr)) {
479                 return werr;
480         }
481
482         /* Display results */
483
484         return werr;
485 }
486
487 /* Log on a domain user */
488
489 static NTSTATUS cmd_netlogon_sam_logon(struct rpc_pipe_client *cli, 
490                                        TALLOC_CTX *mem_ctx, int argc,
491                                        const char **argv)
492 {
493         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
494         int logon_type = NetlogonNetworkInformation;
495         const char *username, *password;
496         uint32_t logon_param = 0;
497         const char *workstation = NULL;
498         struct netr_SamInfo3 *info3 = NULL;
499         uint8_t authoritative = 0;
500         uint32_t flags = 0;
501         uint16_t validation_level;
502         union netr_Validation *validation = NULL;
503
504         /* Check arguments */
505
506         if (argc < 3 || argc > 6) {
507                 fprintf(stderr, "Usage: samlogon <username> <password> [workstation]"
508                         "[logon_type (1 or 2)] [logon_parameter]\n");
509                 return NT_STATUS_OK;
510         }
511
512         username = argv[1];
513         password = argv[2];
514
515         if (argc >= 4) 
516                 workstation = argv[3];
517
518         if (argc >= 5)
519                 sscanf(argv[4], "%i", &logon_type);
520
521         if (argc == 6)
522                 sscanf(argv[5], "%x", &logon_param);
523
524         if (rpcclient_netlogon_creds == NULL) {
525                 result = NT_STATUS_UNSUCCESSFUL;
526                 goto done;
527         }
528
529         /* Perform the sam logon */
530
531         result = rpccli_netlogon_password_logon(rpcclient_netlogon_creds,
532                                                 cli->binding_handle,
533                                                 mem_ctx,
534                                                 logon_param,
535                                                 lp_workgroup(),
536                                                 username,
537                                                 password,
538                                                 workstation,
539                                                 logon_type,
540                                                 &authoritative,
541                                                 &flags,
542                                                 &validation_level,
543                                                 &validation);
544         if (!NT_STATUS_IS_OK(result))
545                 goto done;
546
547         result = map_validation_to_info3(mem_ctx,
548                                          validation_level,
549                                          validation,
550                                          &info3);
551         if (!NT_STATUS_IS_OK(result)) {
552                 return result;
553         }
554
555  done:
556         return result;
557 }
558
559 /* Change the trust account password */
560
561 static NTSTATUS cmd_netlogon_change_trust_pw(struct rpc_pipe_client *cli, 
562                                              TALLOC_CTX *mem_ctx, int argc,
563                                              const char **argv)
564 {
565         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
566         const char *dcname = cli->desthost;
567
568         /* Check arguments */
569
570         if (argc > 1) {
571                 fprintf(stderr, "Usage: change_trust_pw");
572                 return NT_STATUS_OK;
573         }
574
575         result = trust_pw_change(rpcclient_netlogon_creds,
576                                  rpcclient_msg_ctx,
577                                  cli->binding_handle,
578                                  lp_workgroup(),
579                                  dcname,
580                                  true); /* force */
581         if (!NT_STATUS_IS_OK(result))
582                 goto done;
583
584  done:
585         return result;
586 }
587
588 static WERROR cmd_netlogon_gettrustrid(struct rpc_pipe_client *cli,
589                                        TALLOC_CTX *mem_ctx, int argc,
590                                        const char **argv)
591 {
592         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
593         WERROR werr = WERR_GEN_FAILURE;
594         const char *server_name = cli->desthost;
595         const char *domain_name = lp_workgroup();
596         uint32_t rid = 0;
597         struct dcerpc_binding_handle *b = cli->binding_handle;
598
599         if (argc < 1 || argc > 3) {
600                 fprintf(stderr, "Usage: %s <server_name> <domain_name>\n",
601                         argv[0]);
602                 return WERR_OK;
603         }
604
605         if (argc >= 2) {
606                 server_name = argv[1];
607         }
608
609         if (argc >= 3) {
610                 domain_name = argv[2];
611         }
612
613         status = dcerpc_netr_LogonGetTrustRid(b, mem_ctx,
614                                               server_name,
615                                               domain_name,
616                                               &rid,
617                                               &werr);
618         if (!NT_STATUS_IS_OK(status)) {
619                 werr = ntstatus_to_werror(status);
620                 goto done;
621         }
622
623         if (W_ERROR_IS_OK(werr)) {
624                 printf("Rid: %d\n", rid);
625         }
626  done:
627         return werr;
628 }
629
630 static WERROR cmd_netlogon_dsr_enumtrustdom(struct rpc_pipe_client *cli,
631                                             TALLOC_CTX *mem_ctx, int argc,
632                                             const char **argv)
633 {
634         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
635         WERROR werr = WERR_GEN_FAILURE;
636         const char *server_name = cli->desthost;
637         uint32_t trust_flags = NETR_TRUST_FLAG_IN_FOREST;
638         struct netr_DomainTrustList trusts;
639         struct dcerpc_binding_handle *b = cli->binding_handle;
640
641         if (argc < 1 || argc > 3) {
642                 fprintf(stderr, "Usage: %s <server_name> <trust_flags>\n",
643                         argv[0]);
644                 return WERR_OK;
645         }
646
647         if (argc >= 2) {
648                 server_name = argv[1];
649         }
650
651         if (argc >= 3) {
652                 sscanf(argv[2], "%x", &trust_flags);
653         }
654
655         status = dcerpc_netr_DsrEnumerateDomainTrusts(b, mem_ctx,
656                                                       server_name,
657                                                       trust_flags,
658                                                       &trusts,
659                                                       &werr);
660         if (!NT_STATUS_IS_OK(status)) {
661                 werr = ntstatus_to_werror(status);
662                 goto done;
663         }
664
665         if (W_ERROR_IS_OK(werr)) {
666                 int i;
667
668                 printf("%d domains returned\n", trusts.count);
669
670                 for (i=0; i<trusts.count; i++ ) {
671                         printf("%s (%s)\n",
672                                 trusts.array[i].dns_name,
673                                 trusts.array[i].netbios_name);
674                 }
675         }
676  done:
677         return werr;
678 }
679
680 static WERROR cmd_netlogon_deregisterdnsrecords(struct rpc_pipe_client *cli,
681                                                 TALLOC_CTX *mem_ctx, int argc,
682                                                 const char **argv)
683 {
684         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
685         WERROR werr = WERR_GEN_FAILURE;
686         const char *server_name = cli->desthost;
687         const char *domain = lp_workgroup();
688         const char *dns_host = NULL;
689         struct dcerpc_binding_handle *b = cli->binding_handle;
690
691         if (argc < 1 || argc > 4) {
692                 fprintf(stderr, "Usage: %s <server_name> <domain_name> "
693                         "<dns_host>\n", argv[0]);
694                 return WERR_OK;
695         }
696
697         if (argc >= 2) {
698                 server_name = argv[1];
699         }
700
701         if (argc >= 3) {
702                 domain = argv[2];
703         }
704
705         if (argc >= 4) {
706                 dns_host = argv[3];
707         }
708
709         status = dcerpc_netr_DsrDeregisterDNSHostRecords(b, mem_ctx,
710                                                          server_name,
711                                                          domain,
712                                                          NULL,
713                                                          NULL,
714                                                          dns_host,
715                                                          &werr);
716         if (!NT_STATUS_IS_OK(status)) {
717                 werr = ntstatus_to_werror(status);
718                 goto done;
719         }
720
721         if (W_ERROR_IS_OK(werr)) {
722                 printf("success\n");
723         }
724  done:
725         return werr;
726 }
727
728 static WERROR cmd_netlogon_dsr_getforesttrustinfo(struct rpc_pipe_client *cli,
729                                                   TALLOC_CTX *mem_ctx, int argc,
730                                                   const char **argv)
731 {
732         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
733         WERROR werr = WERR_GEN_FAILURE;
734         const char *server_name = cli->desthost;
735         const char *trusted_domain_name = NULL;
736         struct lsa_ForestTrustInformation *info = NULL;
737         uint32_t flags = 0;
738         struct dcerpc_binding_handle *b = cli->binding_handle;
739
740         if (argc < 1 || argc > 4) {
741                 fprintf(stderr, "Usage: %s <server_name> <trusted_domain_name> "
742                         "<flags>\n", argv[0]);
743                 return WERR_OK;
744         }
745
746         if (argc >= 2) {
747                 server_name = argv[1];
748         }
749
750         if (argc >= 3) {
751                 trusted_domain_name = argv[2];
752         }
753
754         if (argc >= 4) {
755                 sscanf(argv[3], "%x", &flags);
756         }
757
758         status = dcerpc_netr_DsRGetForestTrustInformation(b, mem_ctx,
759                                                          server_name,
760                                                          trusted_domain_name,
761                                                          flags,
762                                                          &info,
763                                                          &werr);
764         if (!NT_STATUS_IS_OK(status)) {
765                 werr = ntstatus_to_werror(status);
766                 goto done;
767         }
768
769         if (W_ERROR_IS_OK(werr)) {
770                 printf("success\n");
771         }
772  done:
773         return werr;
774 }
775
776 static NTSTATUS cmd_netlogon_enumtrusteddomains(struct rpc_pipe_client *cli,
777                                                 TALLOC_CTX *mem_ctx, int argc,
778                                                 const char **argv)
779 {
780         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
781         NTSTATUS result;
782         const char *server_name = cli->desthost;
783         struct netr_Blob blob;
784         struct dcerpc_binding_handle *b = cli->binding_handle;
785
786
787         if (argc < 1 || argc > 3) {
788                 fprintf(stderr, "Usage: %s <server_name>\n", argv[0]);
789                 return NT_STATUS_OK;
790         }
791
792         if (argc >= 2) {
793                 server_name = argv[1];
794         }
795
796         status = dcerpc_netr_NetrEnumerateTrustedDomains(b, mem_ctx,
797                                                          server_name,
798                                                          &blob,
799                                                          &result);
800         if (!NT_STATUS_IS_OK(status)) {
801                 goto done;
802         }
803
804         if (!NT_STATUS_IS_OK(result)) {
805                 status = result;
806                 goto done;
807         }
808
809         printf("success\n");
810         dump_data(1, blob.data, blob.length);
811  done:
812         return status;
813 }
814
815 static WERROR cmd_netlogon_enumtrusteddomainsex(struct rpc_pipe_client *cli,
816                                                 TALLOC_CTX *mem_ctx, int argc,
817                                                 const char **argv)
818 {
819         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
820         WERROR werr = WERR_GEN_FAILURE;
821         const char *server_name = cli->desthost;
822         struct netr_DomainTrustList list;
823         struct dcerpc_binding_handle *b = cli->binding_handle;
824
825         if (argc < 1 || argc > 3) {
826                 fprintf(stderr, "Usage: %s <server_name>\n", argv[0]);
827                 return WERR_OK;
828         }
829
830         if (argc >= 2) {
831                 server_name = argv[1];
832         }
833
834         status = dcerpc_netr_NetrEnumerateTrustedDomainsEx(b, mem_ctx,
835                                                            server_name,
836                                                            &list,
837                                                            &werr);
838         if (!NT_STATUS_IS_OK(status)) {
839                 werr = ntstatus_to_werror(status);
840                 goto done;
841         }
842
843         if (W_ERROR_IS_OK(werr)) {
844                 printf("success\n");
845         }
846  done:
847         return werr;
848 }
849
850 static WERROR cmd_netlogon_getdcsitecoverage(struct rpc_pipe_client *cli,
851                                              TALLOC_CTX *mem_ctx, int argc,
852                                              const char **argv)
853 {
854         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
855         WERROR werr = WERR_GEN_FAILURE;
856         const char *server_name = cli->desthost;
857         struct DcSitesCtr *ctr = NULL;
858         struct dcerpc_binding_handle *b = cli->binding_handle;
859
860         if (argc < 1 || argc > 3) {
861                 fprintf(stderr, "Usage: %s <server_name>\n", argv[0]);
862                 return WERR_OK;
863         }
864
865         if (argc >= 2) {
866                 server_name = argv[1];
867         }
868
869         status = dcerpc_netr_DsrGetDcSiteCoverageW(b, mem_ctx,
870                                                    server_name,
871                                                    &ctr,
872                                                    &werr);
873         if (!NT_STATUS_IS_OK(status)) {
874                 werr = ntstatus_to_werror(status);
875                 goto done;
876         }
877
878         if (W_ERROR_IS_OK(werr) && ctr->num_sites) {
879                 int i;
880                 printf("sites covered by this DC: %d\n", ctr->num_sites);
881                 for (i=0; i<ctr->num_sites; i++) {
882                         printf("%s\n", ctr->sites[i].string);
883                 }
884         }
885  done:
886         return werr;
887 }
888
889 static NTSTATUS cmd_netlogon_capabilities(struct rpc_pipe_client *cli,
890                                           TALLOC_CTX *mem_ctx, int argc,
891                                           const char **argv)
892 {
893         struct netlogon_creds_cli_lck *lck;
894         union netr_Capabilities capabilities;
895         NTSTATUS status;
896
897         if (argc > 1) {
898                 fprintf(stderr, "Usage: %s\n", argv[0]);
899                 return NT_STATUS_OK;
900         }
901
902         status = netlogon_creds_cli_lck(rpcclient_netlogon_creds,
903                                         NETLOGON_CREDS_CLI_LCK_EXCLUSIVE,
904                                         mem_ctx, &lck);
905         if (!NT_STATUS_IS_OK(status)) {
906                 fprintf(stderr, "netlogon_creds_cli_lck failed: %s\n",
907                         nt_errstr(status));
908                 return status;
909         }
910
911         status = netlogon_creds_cli_check(rpcclient_netlogon_creds,
912                                           cli->binding_handle,
913                                           &capabilities);
914         if (!NT_STATUS_IS_OK(status)) {
915                 fprintf(stderr, "netlogon_creds_cli_check failed: %s\n",
916                         nt_errstr(status));
917                 return status;
918         }
919
920         TALLOC_FREE(lck);
921
922         printf("capabilities: 0x%08x\n", capabilities.server_capabilities);
923
924         return NT_STATUS_OK;
925 }
926
927 /* List of commands exported by this module */
928
929 struct cmd_set netlogon_commands[] = {
930
931         {
932                 .name = "NETLOGON",
933         },
934
935         {
936                 .name               = "logonctrl2",
937                 .returntype         = RPC_RTYPE_WERROR,
938                 .ntfn               = NULL,
939                 .wfn                = cmd_netlogon_logon_ctrl2,
940                 .table              = &ndr_table_netlogon,
941                 .rpc_pipe           = NULL,
942                 .description        = "Logon Control 2",
943                 .usage              = "",
944         },
945         {
946                 .name               = "getanydcname",
947                 .returntype         = RPC_RTYPE_WERROR,
948                 .ntfn               = NULL,
949                 .wfn                = cmd_netlogon_getanydcname,
950                 .table              = &ndr_table_netlogon,
951                 .rpc_pipe           = NULL,
952                 .description        = "Get trusted DC name",
953                 .usage              = "",
954         },
955         {
956                 .name               = "getdcname",
957                 .returntype         = RPC_RTYPE_WERROR,
958                 .ntfn               = NULL,
959                 .wfn                = cmd_netlogon_getdcname,
960                 .table              = &ndr_table_netlogon,
961                 .rpc_pipe           = NULL,
962                 .description        = "Get trusted PDC name",
963                 .usage              = "",
964         },
965         {
966                 .name               = "dsr_getdcname",
967                 .returntype         = RPC_RTYPE_WERROR,
968                 .ntfn               = NULL,
969                 .wfn                = cmd_netlogon_dsr_getdcname,
970                 .table              = &ndr_table_netlogon,
971                 .rpc_pipe           = NULL,
972                 .description        = "Get trusted DC name",
973                 .usage              = "",
974         },
975         {
976                 .name               = "dsr_getdcnameex",
977                 .returntype         = RPC_RTYPE_WERROR,
978                 .ntfn               = NULL,
979                 .wfn                = cmd_netlogon_dsr_getdcnameex,
980                 .table              = &ndr_table_netlogon,
981                 .rpc_pipe           = NULL,
982                 .description        = "Get trusted DC name",
983                 .usage              = "",
984         },
985         {
986                 .name               = "dsr_getdcnameex2",
987                 .returntype         = RPC_RTYPE_WERROR,
988                 .ntfn               = NULL,
989                 .wfn                = cmd_netlogon_dsr_getdcnameex2,
990                 .table              = &ndr_table_netlogon,
991                 .rpc_pipe           = NULL,
992                 .description        = "Get trusted DC name",
993                 .usage              = "",
994         },
995         {
996                 .name               = "dsr_getsitename",
997                 .returntype         = RPC_RTYPE_WERROR,
998                 .ntfn               = NULL,
999                 .wfn                = cmd_netlogon_dsr_getsitename,
1000                 .table              = &ndr_table_netlogon,
1001                 .rpc_pipe           = NULL,
1002                 .description        = "Get sitename",
1003                 .usage              = "",
1004         },
1005         {
1006                 .name               = "dsr_getforesttrustinfo",
1007                 .returntype         = RPC_RTYPE_WERROR,
1008                 .ntfn               = NULL,
1009                 .wfn                = cmd_netlogon_dsr_getforesttrustinfo,
1010                 .table              = &ndr_table_netlogon,
1011                 .rpc_pipe           = NULL,
1012                 .description        = "Get Forest Trust Info",
1013                 .usage              = "",
1014         },
1015         {
1016                 .name               = "logonctrl",
1017                 .returntype         =  RPC_RTYPE_WERROR,
1018                 .ntfn               = NULL,
1019                 .wfn                = cmd_netlogon_logon_ctrl,
1020                 .table              = &ndr_table_netlogon,
1021                 .rpc_pipe           = NULL,
1022                 .description        = "Logon Control",
1023                 .usage              = "",
1024         },
1025         {
1026                 .name               = "samlogon",
1027                 .returntype         = RPC_RTYPE_NTSTATUS,
1028                 .ntfn               = cmd_netlogon_sam_logon,
1029                 .wfn                = NULL,
1030                 .table              = &ndr_table_netlogon,
1031                 .rpc_pipe           = NULL,
1032                 .description        = "Sam Logon",
1033                 .usage              = "",
1034                 .use_netlogon_creds = true,
1035         },
1036         {
1037                 .name               = "change_trust_pw",
1038                 .returntype         = RPC_RTYPE_NTSTATUS,
1039                 .ntfn               = cmd_netlogon_change_trust_pw,
1040                 .wfn                = NULL,
1041                 .table              = &ndr_table_netlogon,
1042                 .rpc_pipe           = NULL,
1043                 .description        = "Change Trust Account Password",
1044                 .usage              = "",
1045                 .use_netlogon_creds = true,
1046         },
1047         {
1048                 .name               = "gettrustrid",
1049                 .returntype         = RPC_RTYPE_WERROR,
1050                 .ntfn               = NULL,
1051                 .wfn                = cmd_netlogon_gettrustrid,
1052                 .table              = &ndr_table_netlogon,
1053                 .rpc_pipe           = NULL,
1054                 .description        = "Get trust rid",
1055                 .usage              = "",
1056         },
1057         {
1058                 .name               = "dsr_enumtrustdom",
1059                 .returntype         = RPC_RTYPE_WERROR,
1060                 .ntfn               = NULL,
1061                 .wfn                = cmd_netlogon_dsr_enumtrustdom,
1062                 .table              = &ndr_table_netlogon,
1063                 .rpc_pipe           = NULL,
1064                 .description        = "Enumerate trusted domains",
1065                 .usage              = "",
1066         },
1067         {
1068                 .name               = "dsenumdomtrusts",
1069                 .returntype         = RPC_RTYPE_WERROR,
1070                 .ntfn               = NULL,
1071                 .wfn                = cmd_netlogon_dsr_enumtrustdom,
1072                 .table              = &ndr_table_netlogon,
1073                 .rpc_pipe           = NULL,
1074                 .description        = "Enumerate all trusted domains in an AD forest",
1075                 .usage              = "",
1076         },
1077         {
1078                 .name               = "deregisterdnsrecords",
1079                 .returntype         = RPC_RTYPE_WERROR,
1080                 .ntfn               = NULL,
1081                 .wfn                = cmd_netlogon_deregisterdnsrecords,
1082                 .table              = &ndr_table_netlogon,
1083                 .rpc_pipe           = NULL,
1084                 .description        = "Deregister DNS records",
1085                 .usage              = "",
1086         },
1087         {
1088                 .name               = "netrenumtrusteddomains",
1089                 .returntype         = RPC_RTYPE_NTSTATUS,
1090                 .ntfn               = cmd_netlogon_enumtrusteddomains,
1091                 .wfn                = NULL,
1092                 .table              = &ndr_table_netlogon,
1093                 .rpc_pipe           = NULL,
1094                 .description        = "Enumerate trusted domains",
1095                 .usage              = "",
1096         },
1097         {
1098                 .name               = "netrenumtrusteddomainsex",
1099                 .returntype         = RPC_RTYPE_WERROR,
1100                 .ntfn               = NULL,
1101                 .wfn                = cmd_netlogon_enumtrusteddomainsex,
1102                 .table              = &ndr_table_netlogon,
1103                 .rpc_pipe           = NULL,
1104                 .description        = "Enumerate trusted domains",
1105                 .usage              = "",
1106         },
1107         {
1108                 .name               = "getdcsitecoverage",
1109                 .returntype         = RPC_RTYPE_WERROR,
1110                 .ntfn               = NULL,
1111                 .wfn                = cmd_netlogon_getdcsitecoverage,
1112                 .table              = &ndr_table_netlogon,
1113                 .rpc_pipe           = NULL,
1114                 .description        = "Get the Site-Coverage from a DC",
1115                 .usage              = "",
1116         },
1117         {
1118                 .name               = "capabilities",
1119                 .returntype         = RPC_RTYPE_NTSTATUS,
1120                 .ntfn               = cmd_netlogon_capabilities,
1121                 .wfn                = NULL,
1122                 .table              = &ndr_table_netlogon,
1123                 .rpc_pipe           = NULL,
1124                 .description        = "Return Capabilities",
1125                 .usage              = "",
1126                 .use_netlogon_creds = true,
1127         },
1128
1129         {
1130                 .name = NULL,
1131         }
1132 };