Add "desthost" to rpc_pipe_client
[kai/samba.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
25 static WERROR cmd_netlogon_logon_ctrl2(struct rpc_pipe_client *cli,
26                                        TALLOC_CTX *mem_ctx, int argc,
27                                        const char **argv)
28 {
29         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
30         WERROR werr;
31         const char *logon_server = cli->desthost;
32         enum netr_LogonControlCode function_code = NETLOGON_CONTROL_REDISCOVER;
33         uint32_t level = 1;
34         union netr_CONTROL_DATA_INFORMATION data;
35         union netr_CONTROL_QUERY_INFORMATION query;
36         const char *domain = lp_workgroup();
37
38         if (argc > 5) {
39                 fprintf(stderr, "Usage: %s <logon_server> <function_code> "
40                         "<level> <domain>\n", argv[0]);
41                 return WERR_OK;
42         }
43
44         if (argc >= 2) {
45                 logon_server = argv[1];
46         }
47
48         if (argc >= 3) {
49                 function_code = atoi(argv[2]);
50         }
51
52         if (argc >= 4) {
53                 level = atoi(argv[3]);
54         }
55
56         if (argc >= 5) {
57                 domain = argv[4];
58         }
59
60         switch (function_code) {
61                 case NETLOGON_CONTROL_REDISCOVER:
62                 case NETLOGON_CONTROL_TC_QUERY:
63                         data.domain = domain;
64                         break;
65                 default:
66                         break;
67         }
68
69         status = rpccli_netr_LogonControl2(cli, mem_ctx,
70                                           logon_server,
71                                           function_code,
72                                           level,
73                                           &data,
74                                           &query,
75                                           &werr);
76         if (!NT_STATUS_IS_OK(status)) {
77                 return ntstatus_to_werror(status);
78         }
79
80         if (!W_ERROR_IS_OK(werr)) {
81                 return werr;
82         }
83
84         /* Display results */
85
86         return werr;
87 }
88
89 static WERROR cmd_netlogon_getanydcname(struct rpc_pipe_client *cli, 
90                                         TALLOC_CTX *mem_ctx, int argc, 
91                                         const char **argv)
92 {
93         const char *dcname = NULL;
94         WERROR werr;
95         NTSTATUS status;
96         int old_timeout;
97
98         if (argc != 2) {
99                 fprintf(stderr, "Usage: %s domainname\n", argv[0]);
100                 return WERR_OK;
101         }
102
103         /* Make sure to wait for our DC's reply */
104         old_timeout = cli_set_timeout(cli->cli, MAX(cli->cli->timeout,30000)); /* 30 seconds. */
105
106         status = rpccli_netr_GetAnyDCName(cli, mem_ctx,
107                                           cli->desthost,
108                                           argv[1],
109                                           &dcname,
110                                           &werr);
111         cli_set_timeout(cli->cli, old_timeout);
112
113         if (!NT_STATUS_IS_OK(status)) {
114                 return ntstatus_to_werror(status);
115         }
116
117         if (!W_ERROR_IS_OK(werr)) {
118                 return werr;
119         }
120
121         /* Display results */
122
123         printf("%s\n", dcname);
124
125         return werr;
126 }
127
128 static WERROR cmd_netlogon_getdcname(struct rpc_pipe_client *cli,
129                                      TALLOC_CTX *mem_ctx, int argc,
130                                      const char **argv)
131 {
132         const char *dcname = NULL;
133         NTSTATUS status;
134         WERROR werr;
135         int old_timeout;
136
137         if (argc != 2) {
138                 fprintf(stderr, "Usage: %s domainname\n", argv[0]);
139                 return WERR_OK;
140         }
141
142         /* Make sure to wait for our DC's reply */
143         old_timeout = cli_set_timeout(cli->cli, MAX(cli->cli->timeout,30000)); /* 30 seconds. */
144
145         status = rpccli_netr_GetDcName(cli, mem_ctx,
146                                        cli->desthost,
147                                        argv[1],
148                                        &dcname,
149                                        &werr);
150         cli_set_timeout(cli->cli, old_timeout);
151
152         if (!NT_STATUS_IS_OK(status)) {
153                 return ntstatus_to_werror(status);
154         }
155
156         if (!W_ERROR_IS_OK(werr)) {
157                 return werr;
158         }
159
160         /* Display results */
161
162         printf("%s\n", dcname);
163
164         return werr;
165 }
166
167 static WERROR cmd_netlogon_dsr_getdcname(struct rpc_pipe_client *cli,
168                                          TALLOC_CTX *mem_ctx, int argc,
169                                          const char **argv)
170 {
171         NTSTATUS result;
172         WERROR werr = WERR_OK;
173         uint32 flags = DS_RETURN_DNS_NAME;
174         const char *server_name = cli->desthost;
175         const char *domain_name;
176         struct GUID domain_guid = GUID_zero();
177         struct GUID site_guid = GUID_zero();
178         struct netr_DsRGetDCNameInfo *info = NULL;
179
180         if (argc < 2) {
181                 fprintf(stderr, "Usage: %s [domain_name] [domain_guid] "
182                                 "[site_guid] [flags]\n", argv[0]);
183                 return WERR_OK;
184         }
185
186         if (argc >= 2)
187                 domain_name = argv[1];
188
189         if (argc >= 3) {
190                 if (!NT_STATUS_IS_OK(GUID_from_string(argv[2], &domain_guid))) {
191                         return WERR_NOMEM;
192                 }
193         }
194
195         if (argc >= 4) {
196                 if (!NT_STATUS_IS_OK(GUID_from_string(argv[3], &site_guid))) {
197                         return WERR_NOMEM;
198                 }
199         }
200
201         if (argc >= 5)
202                 sscanf(argv[4], "%x", &flags);
203
204         debug_dsdcinfo_flags(1,flags);
205
206         result = rpccli_netr_DsRGetDCName(cli, mem_ctx,
207                                           server_name,
208                                           domain_name,
209                                           &domain_guid,
210                                           &site_guid,
211                                           flags,
212                                           &info,
213                                           &werr);
214
215         if (W_ERROR_IS_OK(werr)) {
216                 d_printf("DsGetDcName gave: %s\n",
217                 NDR_PRINT_STRUCT_STRING(mem_ctx, netr_DsRGetDCNameInfo, info));
218                 return WERR_OK;
219         }
220
221         printf("rpccli_netlogon_dsr_getdcname returned %s\n",
222                dos_errstr(werr));
223
224         return werr;
225 }
226
227 static WERROR cmd_netlogon_dsr_getdcnameex(struct rpc_pipe_client *cli,
228                                            TALLOC_CTX *mem_ctx, int argc,
229                                            const char **argv)
230 {
231         WERROR result;
232         NTSTATUS status;
233         uint32_t flags = DS_RETURN_DNS_NAME;
234         const char *server_name = cli->desthost;
235         const char *domain_name;
236         const char *site_name = NULL;
237         struct GUID domain_guid = GUID_zero();
238         struct netr_DsRGetDCNameInfo *info = NULL;
239
240         if (argc < 2) {
241                 fprintf(stderr, "Usage: %s [domain_name] [domain_guid] "
242                                 "[site_name] [flags]\n", argv[0]);
243                 return WERR_OK;
244         }
245
246         domain_name = argv[1];
247
248         if (argc >= 3) {
249                 if (!NT_STATUS_IS_OK(GUID_from_string(argv[2], &domain_guid))) {
250                         return WERR_NOMEM;
251                 }
252         }
253
254         if (argc >= 4) {
255                 site_name = argv[3];
256         }
257
258         if (argc >= 5) {
259                 sscanf(argv[4], "%x", &flags);
260         }
261
262         debug_dsdcinfo_flags(1,flags);
263
264         status = rpccli_netr_DsRGetDCNameEx(cli, mem_ctx,
265                                             server_name,
266                                             domain_name,
267                                             &domain_guid,
268                                             site_name,
269                                             flags,
270                                             &info,
271                                             &result);
272         if (!NT_STATUS_IS_OK(status)) {
273                 return ntstatus_to_werror(status);
274         }
275
276         if (!W_ERROR_IS_OK(result)) {
277                 return result;
278         }
279
280         d_printf("DsRGetDCNameEx gave %s\n",
281                 NDR_PRINT_STRUCT_STRING(mem_ctx, netr_DsRGetDCNameInfo, info));
282
283         return result;
284 }
285
286 static WERROR cmd_netlogon_dsr_getdcnameex2(struct rpc_pipe_client *cli,
287                                             TALLOC_CTX *mem_ctx, int argc,
288                                             const char **argv)
289 {
290         WERROR result;
291         NTSTATUS status;
292         uint32_t flags = DS_RETURN_DNS_NAME;
293         const char *server_name = cli->desthost;
294         const char *domain_name = NULL;
295         const char *client_account = NULL;
296         uint32_t mask = 0;
297         const char *site_name = NULL;
298         struct GUID domain_guid = GUID_zero();
299         struct netr_DsRGetDCNameInfo *info = NULL;
300
301         if (argc < 2) {
302                 fprintf(stderr, "Usage: %s [client_account] [acb_mask] "
303                                 "[domain_name] [domain_guid] [site_name] "
304                                 "[flags]\n", argv[0]);
305                 return WERR_OK;
306         }
307
308         if (argc >= 2) {
309                 client_account = argv[1];
310         }
311
312         if (argc >= 3) {
313                 mask = atoi(argv[2]);
314         }
315
316         if (argc >= 4) {
317                 domain_name = argv[3];
318         }
319
320         if (argc >= 5) {
321                 if (!NT_STATUS_IS_OK(GUID_from_string(argv[4], &domain_guid))) {
322                         return WERR_NOMEM;
323                 }
324         }
325
326         if (argc >= 6) {
327                 site_name = argv[5];
328         }
329
330         if (argc >= 7) {
331                 sscanf(argv[6], "%x", &flags);
332         }
333
334         debug_dsdcinfo_flags(1,flags);
335
336         status = rpccli_netr_DsRGetDCNameEx2(cli, mem_ctx,
337                                              server_name,
338                                              client_account,
339                                              mask,
340                                              domain_name,
341                                              &domain_guid,
342                                              site_name,
343                                              flags,
344                                              &info,
345                                              &result);
346         if (!NT_STATUS_IS_OK(status)) {
347                 return ntstatus_to_werror(status);
348         }
349
350         if (!W_ERROR_IS_OK(result)) {
351                 return result;
352         }
353
354         d_printf("DsRGetDCNameEx2 gave %s\n",
355                 NDR_PRINT_STRUCT_STRING(mem_ctx, netr_DsRGetDCNameInfo, info));
356
357         return result;
358 }
359
360
361 static WERROR cmd_netlogon_dsr_getsitename(struct rpc_pipe_client *cli,
362                                            TALLOC_CTX *mem_ctx, int argc,
363                                            const char **argv)
364 {
365         WERROR werr;
366         NTSTATUS status;
367         const char *sitename = NULL;
368
369         if (argc != 2) {
370                 fprintf(stderr, "Usage: %s computername\n", argv[0]);
371                 return WERR_OK;
372         }
373
374         status = rpccli_netr_DsRGetSiteName(cli, mem_ctx,
375                                             argv[1],
376                                             &sitename,
377                                             &werr);
378         if (!NT_STATUS_IS_OK(status)) {
379                 return ntstatus_to_werror(status);
380         }
381
382         if (!W_ERROR_IS_OK(werr)) {
383                 printf("rpccli_netlogon_dsr_gesitename returned %s\n",
384                        nt_errstr(werror_to_ntstatus(werr)));
385                 return werr;
386         }
387
388         printf("Computer %s is on Site: %s\n", argv[1], sitename);
389
390         return WERR_OK;
391 }
392
393 static WERROR cmd_netlogon_logon_ctrl(struct rpc_pipe_client *cli,
394                                       TALLOC_CTX *mem_ctx, int argc,
395                                       const char **argv)
396 {
397         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
398         WERROR werr;
399         const char *logon_server = cli->desthost;
400         enum netr_LogonControlCode function_code = 1;
401         uint32_t level = 1;
402         union netr_CONTROL_QUERY_INFORMATION info;
403
404         if (argc > 4) {
405                 fprintf(stderr, "Usage: %s <logon_server> <function_code> "
406                         "<level>\n", argv[0]);
407                 return WERR_OK;
408         }
409
410         if (argc >= 2) {
411                 logon_server = argv[1];
412         }
413
414         if (argc >= 3) {
415                 function_code = atoi(argv[2]);
416         }
417
418         if (argc >= 4) {
419                 level = atoi(argv[3]);
420         }
421
422         status = rpccli_netr_LogonControl(cli, mem_ctx,
423                                           logon_server,
424                                           function_code,
425                                           level,
426                                           &info,
427                                           &werr);
428         if (!NT_STATUS_IS_OK(status)) {
429                 return ntstatus_to_werror(status);
430         }
431
432         if (!W_ERROR_IS_OK(werr)) {
433                 return werr;
434         }
435
436         /* Display results */
437
438         return werr;
439 }
440
441 /* Display sam synchronisation information */
442
443 static void display_sam_sync(struct netr_DELTA_ENUM_ARRAY *r)
444 {
445         uint32_t i, j;
446
447         for (i=0; i < r->num_deltas; i++) {
448
449                 union netr_DELTA_UNION u = r->delta_enum[i].delta_union;
450                 union netr_DELTA_ID_UNION id = r->delta_enum[i].delta_id_union;
451
452                 switch (r->delta_enum[i].delta_type) {
453                 case NETR_DELTA_DOMAIN:
454                         printf("Domain: %s\n",
455                                 u.domain->domain_name.string);
456                         break;
457                 case NETR_DELTA_GROUP:
458                         printf("Group: %s\n",
459                                 u.group->group_name.string);
460                         break;
461                 case NETR_DELTA_DELETE_GROUP:
462                         printf("Delete Group: %d\n",
463                                 u.delete_account.unknown);
464                         break;
465                 case NETR_DELTA_RENAME_GROUP:
466                         printf("Rename Group: %s -> %s\n",
467                                 u.rename_group->OldName.string,
468                                 u.rename_group->NewName.string);
469                         break;
470                 case NETR_DELTA_USER:
471                         printf("Account: %s\n",
472                                 u.user->account_name.string);
473                         break;
474                 case NETR_DELTA_DELETE_USER:
475                         printf("Delete User: %d\n",
476                                 id.rid);
477                         break;
478                 case NETR_DELTA_RENAME_USER:
479                         printf("Rename user: %s -> %s\n",
480                                 u.rename_user->OldName.string,
481                                 u.rename_user->NewName.string);
482                         break;
483                 case NETR_DELTA_GROUP_MEMBER:
484                         for (j=0; j < u.group_member->num_rids; j++) {
485                                 printf("rid 0x%x, attrib 0x%08x\n",
486                                         u.group_member->rids[j],
487                                         u.group_member->attribs[j]);
488                         }
489                         break;
490                 case NETR_DELTA_ALIAS:
491                         printf("Alias: %s\n",
492                                 u.alias->alias_name.string);
493                         break;
494                 case NETR_DELTA_DELETE_ALIAS:
495                         printf("Delete Alias: %d\n",
496                                 r->delta_enum[i].delta_id_union.rid);
497                         break;
498                 case NETR_DELTA_RENAME_ALIAS:
499                         printf("Rename alias: %s -> %s\n",
500                                 u.rename_alias->OldName.string,
501                                 u.rename_alias->NewName.string);
502                         break;
503                 case NETR_DELTA_ALIAS_MEMBER:
504                         for (j=0; j < u.alias_member->sids.num_sids; j++) {
505                                 fstring sid_str;
506                                 sid_to_fstring(sid_str,
507                                         u.alias_member->sids.sids[j].sid);
508                                 printf("%s\n", sid_str);
509                         }
510                         break;
511                 case NETR_DELTA_POLICY:
512                         printf("Policy\n");
513                         break;
514                 case NETR_DELTA_TRUSTED_DOMAIN:
515                         printf("Trusted Domain: %s\n",
516                                 u.trusted_domain->domain_name.string);
517                         break;
518                 case NETR_DELTA_DELETE_TRUST:
519                         printf("Delete Trust: %d\n",
520                                 u.delete_trust.unknown);
521                         break;
522                 case NETR_DELTA_ACCOUNT:
523                         printf("Account\n");
524                         break;
525                 case NETR_DELTA_DELETE_ACCOUNT:
526                         printf("Delete Account: %d\n",
527                                 u.delete_account.unknown);
528                         break;
529                 case NETR_DELTA_SECRET:
530                         printf("Secret\n");
531                         break;
532                 case NETR_DELTA_DELETE_SECRET:
533                         printf("Delete Secret: %d\n",
534                                 u.delete_secret.unknown);
535                         break;
536                 case NETR_DELTA_DELETE_GROUP2:
537                         printf("Delete Group2: %s\n",
538                                 u.delete_group->account_name);
539                         break;
540                 case NETR_DELTA_DELETE_USER2:
541                         printf("Delete User2: %s\n",
542                                 u.delete_user->account_name);
543                         break;
544                 case NETR_DELTA_MODIFY_COUNT:
545                         printf("sam sequence update: 0x%016llx\n",
546                                 (unsigned long long) *u.modified_count);
547                         break;
548                 default:
549                         printf("unknown delta type 0x%02x\n",
550                                 r->delta_enum[i].delta_type);
551                         break;
552                 }
553         }
554 }
555
556 /* Perform sam synchronisation */
557
558 static NTSTATUS cmd_netlogon_sam_sync(struct rpc_pipe_client *cli,
559                                       TALLOC_CTX *mem_ctx, int argc,
560                                       const char **argv)
561 {
562         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
563         const char *logon_server = cli->desthost;
564         const char *computername = global_myname();
565         struct netr_Authenticator credential;
566         struct netr_Authenticator return_authenticator;
567         enum netr_SamDatabaseID database_id = SAM_DATABASE_DOMAIN;
568         uint16_t restart_state = 0;
569         uint32_t sync_context = 0;
570
571         if (argc > 2) {
572                 fprintf(stderr, "Usage: %s [database_id]\n", argv[0]);
573                 return NT_STATUS_OK;
574         }
575
576         if (argc == 2) {
577                 database_id = atoi(argv[1]);
578         }
579
580         /* Synchronise sam database */
581
582         do {
583                 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
584
585                 netlogon_creds_client_step(cli->dc, &credential);
586
587                 result = rpccli_netr_DatabaseSync2(cli, mem_ctx,
588                                                    logon_server,
589                                                    computername,
590                                                    &credential,
591                                                    &return_authenticator,
592                                                    database_id,
593                                                    restart_state,
594                                                    &sync_context,
595                                                    &delta_enum_array,
596                                                    0xffff);
597
598                 /* Check returned credentials. */
599                 if (!netlogon_creds_client_check(cli->dc,
600                                                  &return_authenticator.cred)) {
601                         DEBUG(0,("credentials chain check failed\n"));
602                         return NT_STATUS_ACCESS_DENIED;
603                 }
604
605                 if (NT_STATUS_IS_ERR(result)) {
606                         break;
607                 }
608
609                 /* Display results */
610
611                 display_sam_sync(delta_enum_array);
612
613                 TALLOC_FREE(delta_enum_array);
614
615         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
616
617         return result;
618 }
619
620 /* Perform sam delta synchronisation */
621
622 static NTSTATUS cmd_netlogon_sam_deltas(struct rpc_pipe_client *cli,
623                                         TALLOC_CTX *mem_ctx, int argc,
624                                         const char **argv)
625 {
626         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
627         uint32_t tmp;
628         const char *logon_server = cli->desthost;
629         const char *computername = global_myname();
630         struct netr_Authenticator credential;
631         struct netr_Authenticator return_authenticator;
632         enum netr_SamDatabaseID database_id = SAM_DATABASE_DOMAIN;
633         uint64_t sequence_num;
634
635         if (argc != 3) {
636                 fprintf(stderr, "Usage: %s database_id seqnum\n", argv[0]);
637                 return NT_STATUS_OK;
638         }
639
640         database_id = atoi(argv[1]);
641         tmp = atoi(argv[2]);
642
643         sequence_num = tmp & 0xffff;
644
645         do {
646                 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
647
648                 netlogon_creds_client_step(cli->dc, &credential);
649
650                 result = rpccli_netr_DatabaseDeltas(cli, mem_ctx,
651                                                     logon_server,
652                                                     computername,
653                                                     &credential,
654                                                     &return_authenticator,
655                                                     database_id,
656                                                     &sequence_num,
657                                                     &delta_enum_array,
658                                                     0xffff);
659
660                 /* Check returned credentials. */
661                 if (!netlogon_creds_client_check(cli->dc,
662                                                  &return_authenticator.cred)) {
663                         DEBUG(0,("credentials chain check failed\n"));
664                         return NT_STATUS_ACCESS_DENIED;
665                 }
666
667                 if (NT_STATUS_IS_ERR(result)) {
668                         break;
669                 }
670
671                 /* Display results */
672
673                 display_sam_sync(delta_enum_array);
674
675                 TALLOC_FREE(delta_enum_array);
676
677         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
678
679         return result;
680 }
681
682 /* Log on a domain user */
683
684 static NTSTATUS cmd_netlogon_sam_logon(struct rpc_pipe_client *cli, 
685                                        TALLOC_CTX *mem_ctx, int argc,
686                                        const char **argv)
687 {
688         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
689         int logon_type = NET_LOGON_TYPE;
690         const char *username, *password;
691         int auth_level = 2;
692         uint32 logon_param = 0;
693         const char *workstation = NULL;
694
695         /* Check arguments */
696
697         if (argc < 3 || argc > 7) {
698                 fprintf(stderr, "Usage: samlogon <username> <password> [workstation]"
699                         "[logon_type (1 or 2)] [auth level (2 or 3)] [logon_parameter]\n");
700                 return NT_STATUS_OK;
701         }
702
703         username = argv[1];
704         password = argv[2];
705
706         if (argc >= 4) 
707                 workstation = argv[3];
708
709         if (argc >= 5)
710                 sscanf(argv[4], "%i", &logon_type);
711
712         if (argc >= 6)
713                 sscanf(argv[5], "%i", &auth_level);
714
715         if (argc == 7)
716                 sscanf(argv[6], "%x", &logon_param);
717
718         /* Perform the sam logon */
719
720         result = rpccli_netlogon_sam_logon(cli, mem_ctx, logon_param, lp_workgroup(), username, password, workstation, logon_type);
721
722         if (!NT_STATUS_IS_OK(result))
723                 goto done;
724
725  done:
726         return result;
727 }
728
729 /* Change the trust account password */
730
731 static NTSTATUS cmd_netlogon_change_trust_pw(struct rpc_pipe_client *cli, 
732                                              TALLOC_CTX *mem_ctx, int argc,
733                                              const char **argv)
734 {
735         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
736
737         /* Check arguments */
738
739         if (argc > 1) {
740                 fprintf(stderr, "Usage: change_trust_pw");
741                 return NT_STATUS_OK;
742         }
743
744         /* Perform the sam logon */
745
746         result = trust_pw_find_change_and_store_it(cli, mem_ctx,
747                                                    lp_workgroup());
748
749         if (!NT_STATUS_IS_OK(result))
750                 goto done;
751
752  done:
753         return result;
754 }
755
756 static WERROR cmd_netlogon_gettrustrid(struct rpc_pipe_client *cli,
757                                        TALLOC_CTX *mem_ctx, int argc,
758                                        const char **argv)
759 {
760         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
761         WERROR werr = WERR_GENERAL_FAILURE;
762         const char *server_name = cli->desthost;
763         const char *domain_name = lp_workgroup();
764         uint32_t rid = 0;
765
766         if (argc < 1 || argc > 3) {
767                 fprintf(stderr, "Usage: %s <server_name> <domain_name>\n",
768                         argv[0]);
769                 return WERR_OK;
770         }
771
772         if (argc >= 2) {
773                 server_name = argv[1];
774         }
775
776         if (argc >= 3) {
777                 domain_name = argv[2];
778         }
779
780         status = rpccli_netr_LogonGetTrustRid(cli, mem_ctx,
781                                               server_name,
782                                               domain_name,
783                                               &rid,
784                                               &werr);
785         if (!NT_STATUS_IS_OK(status)) {
786                 goto done;
787         }
788
789         if (W_ERROR_IS_OK(werr)) {
790                 printf("Rid: %d\n", rid);
791         }
792  done:
793         return werr;
794 }
795
796 static WERROR cmd_netlogon_dsr_enumtrustdom(struct rpc_pipe_client *cli,
797                                             TALLOC_CTX *mem_ctx, int argc,
798                                             const char **argv)
799 {
800         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
801         WERROR werr = WERR_GENERAL_FAILURE;
802         const char *server_name = cli->desthost;
803         uint32_t trust_flags = NETR_TRUST_FLAG_IN_FOREST;
804         struct netr_DomainTrustList trusts;
805
806         if (argc < 1 || argc > 3) {
807                 fprintf(stderr, "Usage: %s <server_name> <trust_flags>\n",
808                         argv[0]);
809                 return WERR_OK;
810         }
811
812         if (argc >= 2) {
813                 server_name = argv[1];
814         }
815
816         if (argc >= 3) {
817                 sscanf(argv[2], "%x", &trust_flags);
818         }
819
820         status = rpccli_netr_DsrEnumerateDomainTrusts(cli, mem_ctx,
821                                                       server_name,
822                                                       trust_flags,
823                                                       &trusts,
824                                                       &werr);
825         if (!NT_STATUS_IS_OK(status)) {
826                 goto done;
827         }
828
829         if (W_ERROR_IS_OK(werr)) {
830                 int i;
831
832                 printf("%d domains returned\n", trusts.count);
833
834                 for (i=0; i<trusts.count; i++ ) {
835                         printf("%s (%s)\n",
836                                 trusts.array[i].dns_name,
837                                 trusts.array[i].netbios_name);
838                 }
839         }
840  done:
841         return werr;
842 }
843
844 static WERROR cmd_netlogon_deregisterdnsrecords(struct rpc_pipe_client *cli,
845                                                 TALLOC_CTX *mem_ctx, int argc,
846                                                 const char **argv)
847 {
848         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
849         WERROR werr = WERR_GENERAL_FAILURE;
850         const char *server_name = cli->desthost;
851         const char *domain = lp_workgroup();
852         const char *dns_host = NULL;
853
854         if (argc < 1 || argc > 4) {
855                 fprintf(stderr, "Usage: %s <server_name> <domain_name> "
856                         "<dns_host>\n", argv[0]);
857                 return WERR_OK;
858         }
859
860         if (argc >= 2) {
861                 server_name = argv[1];
862         }
863
864         if (argc >= 3) {
865                 domain = argv[2];
866         }
867
868         if (argc >= 4) {
869                 dns_host = argv[3];
870         }
871
872         status = rpccli_netr_DsrDeregisterDNSHostRecords(cli, mem_ctx,
873                                                          server_name,
874                                                          domain,
875                                                          NULL,
876                                                          NULL,
877                                                          dns_host,
878                                                          &werr);
879         if (!NT_STATUS_IS_OK(status)) {
880                 goto done;
881         }
882
883         if (W_ERROR_IS_OK(werr)) {
884                 printf("success\n");
885         }
886  done:
887         return werr;
888 }
889
890 static WERROR cmd_netlogon_dsr_getforesttrustinfo(struct rpc_pipe_client *cli,
891                                                   TALLOC_CTX *mem_ctx, int argc,
892                                                   const char **argv)
893 {
894         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
895         WERROR werr = WERR_GENERAL_FAILURE;
896         const char *server_name = cli->desthost;
897         const char *trusted_domain_name = NULL;
898         struct lsa_ForestTrustInformation *info = NULL;
899         uint32_t flags = 0;
900
901         if (argc < 1 || argc > 4) {
902                 fprintf(stderr, "Usage: %s <server_name> <trusted_domain_name> "
903                         "<flags>\n", argv[0]);
904                 return WERR_OK;
905         }
906
907         if (argc >= 2) {
908                 server_name = argv[1];
909         }
910
911         if (argc >= 3) {
912                 trusted_domain_name = argv[2];
913         }
914
915         if (argc >= 4) {
916                 sscanf(argv[3], "%x", &flags);
917         }
918
919         status = rpccli_netr_DsRGetForestTrustInformation(cli, mem_ctx,
920                                                          server_name,
921                                                          trusted_domain_name,
922                                                          flags,
923                                                          &info,
924                                                          &werr);
925         if (!NT_STATUS_IS_OK(status)) {
926                 goto done;
927         }
928
929         if (W_ERROR_IS_OK(werr)) {
930                 printf("success\n");
931         }
932  done:
933         return werr;
934 }
935
936 static WERROR cmd_netlogon_enumtrusteddomains(struct rpc_pipe_client *cli,
937                                               TALLOC_CTX *mem_ctx, int argc,
938                                               const char **argv)
939 {
940         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
941         WERROR werr = WERR_GENERAL_FAILURE;
942         const char *server_name = cli->desthost;
943         struct netr_Blob blob;
944
945
946         if (argc < 1 || argc > 3) {
947                 fprintf(stderr, "Usage: %s <server_name>\n", argv[0]);
948                 return WERR_OK;
949         }
950
951         if (argc >= 2) {
952                 server_name = argv[1];
953         }
954
955         status = rpccli_netr_NetrEnumerateTrustedDomains(cli, mem_ctx,
956                                                          server_name,
957                                                          &blob,
958                                                          &werr);
959         if (!NT_STATUS_IS_OK(status)) {
960                 goto done;
961         }
962
963         if (W_ERROR_IS_OK(werr)) {
964                 printf("success\n");
965                 dump_data(1, blob.data, blob.length);
966         }
967  done:
968         return werr;
969 }
970
971 static WERROR cmd_netlogon_enumtrusteddomainsex(struct rpc_pipe_client *cli,
972                                                 TALLOC_CTX *mem_ctx, int argc,
973                                                 const char **argv)
974 {
975         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
976         WERROR werr = WERR_GENERAL_FAILURE;
977         const char *server_name = cli->desthost;
978         struct netr_DomainTrustList list;
979
980         if (argc < 1 || argc > 3) {
981                 fprintf(stderr, "Usage: %s <server_name>\n", argv[0]);
982                 return WERR_OK;
983         }
984
985         if (argc >= 2) {
986                 server_name = argv[1];
987         }
988
989         status = rpccli_netr_NetrEnumerateTrustedDomainsEx(cli, mem_ctx,
990                                                            server_name,
991                                                            &list,
992                                                            &werr);
993         if (!NT_STATUS_IS_OK(status)) {
994                 goto done;
995         }
996
997         if (W_ERROR_IS_OK(werr)) {
998                 printf("success\n");
999         }
1000  done:
1001         return werr;
1002 }
1003
1004
1005 /* List of commands exported by this module */
1006
1007 struct cmd_set netlogon_commands[] = {
1008
1009         { "NETLOGON" },
1010
1011         { "logonctrl2", RPC_RTYPE_WERROR, NULL, cmd_netlogon_logon_ctrl2, PI_NETLOGON, NULL, "Logon Control 2",     "" },
1012         { "getanydcname", RPC_RTYPE_WERROR, NULL, cmd_netlogon_getanydcname, PI_NETLOGON, NULL, "Get trusted DC name",     "" },
1013         { "getdcname", RPC_RTYPE_WERROR, NULL, cmd_netlogon_getdcname, PI_NETLOGON, NULL, "Get trusted PDC name",     "" },
1014         { "dsr_getdcname", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getdcname, PI_NETLOGON, NULL, "Get trusted DC name",     "" },
1015         { "dsr_getdcnameex", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getdcnameex, PI_NETLOGON, NULL, "Get trusted DC name",     "" },
1016         { "dsr_getdcnameex2", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getdcnameex2, PI_NETLOGON, NULL, "Get trusted DC name",     "" },
1017         { "dsr_getsitename", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getsitename, PI_NETLOGON, NULL, "Get sitename",     "" },
1018         { "dsr_getforesttrustinfo", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getforesttrustinfo, PI_NETLOGON, NULL, "Get Forest Trust Info",     "" },
1019         { "logonctrl",  RPC_RTYPE_WERROR, NULL, cmd_netlogon_logon_ctrl, PI_NETLOGON, NULL, "Logon Control",       "" },
1020         { "samsync",    RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_sync,    NULL, PI_NETLOGON, NULL, "Sam Synchronisation", "" },
1021         { "samdeltas",  RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_deltas,  NULL, PI_NETLOGON, NULL, "Query Sam Deltas",    "" },
1022         { "samlogon",   RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_logon,   NULL, PI_NETLOGON, NULL, "Sam Logon",           "" },
1023         { "change_trust_pw",   RPC_RTYPE_NTSTATUS, cmd_netlogon_change_trust_pw,   NULL, PI_NETLOGON, NULL, "Change Trust Account Password",           "" },
1024         { "gettrustrid", RPC_RTYPE_WERROR, NULL, cmd_netlogon_gettrustrid, PI_NETLOGON, NULL, "Get trust rid",     "" },
1025         { "dsr_enumtrustdom", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_enumtrustdom, PI_NETLOGON, NULL, "Enumerate trusted domains",     "" },
1026         { "dsenumdomtrusts",  RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_enumtrustdom, PI_NETLOGON, NULL, "Enumerate all trusted domains in an AD forest",     "" },
1027         { "deregisterdnsrecords", RPC_RTYPE_WERROR, NULL, cmd_netlogon_deregisterdnsrecords, PI_NETLOGON, NULL, "Deregister DNS records",     "" },
1028         { "netrenumtrusteddomains", RPC_RTYPE_WERROR, NULL, cmd_netlogon_enumtrusteddomains, PI_NETLOGON, NULL, "Enumerate trusted domains",     "" },
1029         { "netrenumtrusteddomainsex", RPC_RTYPE_WERROR, NULL, cmd_netlogon_enumtrusteddomainsex, PI_NETLOGON, NULL, "Enumerate trusted domains",     "" },
1030
1031         { NULL }
1032 };