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