r21259: Fix coverity bug id #340. No way to process
[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
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23 #include "rpcclient.h"
24
25 static NTSTATUS cmd_netlogon_logon_ctrl2(struct rpc_pipe_client *cli, 
26                                          TALLOC_CTX *mem_ctx, int argc, 
27                                          const char **argv)
28 {
29         uint32 query_level = 1;
30         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
31
32         if (argc > 1) {
33                 fprintf(stderr, "Usage: %s\n", argv[0]);
34                 return NT_STATUS_OK;
35         }
36
37         result = rpccli_netlogon_logon_ctrl2(cli, mem_ctx, query_level);
38
39         if (!NT_STATUS_IS_OK(result))
40                 goto done;
41
42         /* Display results */
43
44  done:
45         return result;
46 }
47
48 static WERROR cmd_netlogon_getdcname(struct rpc_pipe_client *cli, 
49                                      TALLOC_CTX *mem_ctx, int argc, 
50                                      const char **argv)
51 {
52         fstring dcname;
53         WERROR result = WERR_GENERAL_FAILURE;
54         int old_timeout;
55
56         if (argc != 2) {
57                 fprintf(stderr, "Usage: %s domainname\n", argv[0]);
58                 return WERR_OK;
59         }
60
61         /* Make sure to wait for our DC's reply */
62         old_timeout = cli_set_timeout(cli->cli, MAX(cli->cli->timeout,30000)); /* 30 seconds. */
63
64         result = rpccli_netlogon_getdcname(cli, mem_ctx, cli->cli->desthost, argv[1], dcname);
65
66         cli_set_timeout(cli->cli, old_timeout);
67
68         if (!W_ERROR_IS_OK(result))
69                 goto done;
70
71         /* Display results */
72
73         printf("%s\n", dcname);
74
75  done:
76         return result;
77 }
78
79 static WERROR cmd_netlogon_getanydcname(struct rpc_pipe_client *cli, 
80                                         TALLOC_CTX *mem_ctx, int argc, 
81                                         const char **argv)
82 {
83         fstring dcname;
84         WERROR result = WERR_GENERAL_FAILURE;
85         int old_timeout;
86
87         if (argc != 2) {
88                 fprintf(stderr, "Usage: %s domainname\n", argv[0]);
89                 return WERR_OK;
90         }
91
92         /* Make sure to wait for our DC's reply */
93         old_timeout = cli_set_timeout(cli->cli, MAX(cli->cli->timeout,30000)); /* 30 seconds. */
94
95         result = rpccli_netlogon_getanydcname(cli, mem_ctx, cli->cli->desthost, argv[1], dcname);
96
97         cli_set_timeout(cli->cli, old_timeout);
98
99         if (!W_ERROR_IS_OK(result))
100                 goto done;
101
102         /* Display results */
103
104         printf("%s\n", dcname);
105
106  done:
107         return result;
108 }
109
110 static WERROR cmd_netlogon_dsr_getdcname(struct rpc_pipe_client *cli,
111                                          TALLOC_CTX *mem_ctx, int argc,
112                                          const char **argv)
113 {
114         WERROR result;
115         char *dcname, *dcaddress;
116
117         if (argc != 2) {
118                 fprintf(stderr, "Usage: %s domainname\n", argv[0]);
119                 return WERR_OK;
120         }
121
122         result = rpccli_netlogon_dsr_getdcname(
123                 cli, mem_ctx, cli->cli->desthost, argv[1], NULL, NULL,
124                 0x40000000, &dcname, &dcaddress, NULL, NULL, NULL, NULL,
125                 NULL, NULL, NULL);
126
127         if (W_ERROR_IS_OK(result)) {
128                 printf("Domain %s's DC is called %s at IP %s\n",
129                        argv[1], dcname, dcaddress);
130                 return WERR_OK;
131         }
132
133         printf("rpccli_netlogon_dsr_getdcname returned %s\n",
134                nt_errstr(werror_to_ntstatus(result)));
135
136         return result;
137 }
138
139 static WERROR cmd_netlogon_dsr_getsitename(struct rpc_pipe_client *cli,
140                                            TALLOC_CTX *mem_ctx, int argc,
141                                            const char **argv)
142 {
143         WERROR result;
144         char *sitename;
145
146         if (argc != 2) {
147                 fprintf(stderr, "Usage: %s computername\n", argv[0]);
148                 return WERR_OK;
149         }
150
151         result = rpccli_netlogon_dsr_getsitename(cli, mem_ctx, argv[1], &sitename);
152
153         if (!W_ERROR_IS_OK(result)) {
154                 printf("rpccli_netlogon_dsr_gesitename returned %s\n",
155                        nt_errstr(werror_to_ntstatus(result)));
156                 return result;
157         }
158
159         printf("Computer %s is on Site: %s\n", argv[1], sitename);
160
161         return WERR_OK;
162 }
163
164 static NTSTATUS cmd_netlogon_logon_ctrl(struct rpc_pipe_client *cli, 
165                                         TALLOC_CTX *mem_ctx, int argc, 
166                                         const char **argv)
167 {
168 #if 0
169         uint32 query_level = 1;
170 #endif
171         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
172
173         if (argc > 1) {
174                 fprintf(stderr, "Usage: %s\n", argv[0]);
175                 return NT_STATUS_OK;
176         }
177
178 #if 0
179         result = cli_netlogon_logon_ctrl(cli, mem_ctx, query_level);
180         if (!NT_STATUS_IS_OK(result)) {
181                 goto done;
182         }
183 #endif
184
185         /* Display results */
186
187         return result;
188 }
189
190 /* Display sam synchronisation information */
191
192 static void display_sam_sync(uint32 num_deltas, SAM_DELTA_HDR *hdr_deltas,
193                              SAM_DELTA_CTR *deltas)
194 {
195         fstring name;
196         uint32 i, j;
197
198         for (i = 0; i < num_deltas; i++) {
199                 switch (hdr_deltas[i].type) {
200                 case SAM_DELTA_DOMAIN_INFO:
201                         unistr2_to_ascii(name,
202                                          &deltas[i].domain_info.uni_dom_name,
203                                          sizeof(name) - 1);
204                         printf("Domain: %s\n", name);
205                         break;
206                 case SAM_DELTA_GROUP_INFO:
207                         unistr2_to_ascii(name,
208                                          &deltas[i].group_info.uni_grp_name,
209                                          sizeof(name) - 1);
210                         printf("Group: %s\n", name);
211                         break;
212                 case SAM_DELTA_ACCOUNT_INFO:
213                         unistr2_to_ascii(name, 
214                                          &deltas[i].account_info.uni_acct_name,
215                                          sizeof(name) - 1);
216                         printf("Account: %s\n", name);
217                         break;
218                 case SAM_DELTA_ALIAS_INFO:
219                         unistr2_to_ascii(name, 
220                                          &deltas[i].alias_info.uni_als_name,
221                                          sizeof(name) - 1);
222                         printf("Alias: %s\n", name);
223                         break;
224                 case SAM_DELTA_ALIAS_MEM: {
225                         SAM_ALIAS_MEM_INFO *alias = &deltas[i].als_mem_info;
226
227                         for (j = 0; j < alias->num_members; j++) {
228                                 fstring sid_str;
229
230                                 sid_to_string(sid_str, &alias->sids[j].sid);
231
232                                 printf("%s\n", sid_str);
233                         }
234                         break;
235                 }
236                 case SAM_DELTA_GROUP_MEM: {
237                         SAM_GROUP_MEM_INFO *group = &deltas[i].grp_mem_info;
238
239                         for (j = 0; j < group->num_members; j++)
240                                 printf("rid 0x%x, attrib 0x%08x\n", 
241                                           group->rids[j], group->attribs[j]);
242                         break;
243                 }
244                 case SAM_DELTA_MODIFIED_COUNT: {
245                         SAM_DELTA_MOD_COUNT *mc = &deltas[i].mod_count;
246
247                         printf("sam sequence update: 0x%04x\n", mc->seqnum);
248                         break;
249                 }                                  
250                 default:
251                         printf("unknown delta type 0x%02x\n", 
252                                   hdr_deltas[i].type);
253                         break;
254                 }
255         }
256 }
257
258 /* Perform sam synchronisation */
259
260 static NTSTATUS cmd_netlogon_sam_sync(struct rpc_pipe_client *cli, 
261                                       TALLOC_CTX *mem_ctx, int argc,
262                                       const char **argv)
263 {
264         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
265         uint32 database_id = 0, num_deltas;
266         SAM_DELTA_HDR *hdr_deltas;
267         SAM_DELTA_CTR *deltas;
268
269         if (argc > 2) {
270                 fprintf(stderr, "Usage: %s [database_id]\n", argv[0]);
271                 return NT_STATUS_OK;
272         }
273
274         if (argc == 2)
275                 database_id = atoi(argv[1]);
276
277         /* Synchronise sam database */
278
279         result = rpccli_netlogon_sam_sync(cli, mem_ctx, database_id,
280                                        0, &num_deltas, &hdr_deltas, &deltas);
281
282         if (!NT_STATUS_IS_OK(result))
283                 goto done;
284
285         /* Display results */
286
287         display_sam_sync(num_deltas, hdr_deltas, deltas);
288
289  done:
290         return result;
291 }
292
293 /* Perform sam delta synchronisation */
294
295 static NTSTATUS cmd_netlogon_sam_deltas(struct rpc_pipe_client *cli, 
296                                         TALLOC_CTX *mem_ctx, int argc,
297                                         const char **argv)
298 {
299         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
300         uint32 database_id, num_deltas, tmp;
301         SAM_DELTA_HDR *hdr_deltas;
302         SAM_DELTA_CTR *deltas;
303         uint64 seqnum;
304
305         if (argc != 3) {
306                 fprintf(stderr, "Usage: %s database_id seqnum\n", argv[0]);
307                 return NT_STATUS_OK;
308         }
309
310         database_id = atoi(argv[1]);
311         tmp = atoi(argv[2]);
312
313         seqnum = tmp & 0xffff;
314
315         result = rpccli_netlogon_sam_deltas(cli, mem_ctx, database_id,
316                                          seqnum, &num_deltas, 
317                                          &hdr_deltas, &deltas);
318
319         if (!NT_STATUS_IS_OK(result))
320                 goto done;
321
322         /* Display results */
323
324         display_sam_sync(num_deltas, hdr_deltas, deltas);
325         
326  done:
327         return result;
328 }
329
330 /* Log on a domain user */
331
332 static NTSTATUS cmd_netlogon_sam_logon(struct rpc_pipe_client *cli, 
333                                        TALLOC_CTX *mem_ctx, int argc,
334                                        const char **argv)
335 {
336         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
337         int logon_type = NET_LOGON_TYPE;
338         const char *username, *password;
339         int auth_level = 2;
340         uint32 logon_param = 0;
341         const char *workstation = NULL;
342
343         /* Check arguments */
344
345         if (argc < 3 || argc > 7) {
346                 fprintf(stderr, "Usage: samlogon <username> <password> [workstation]"
347                         "[logon_type (1 or 2)] [auth level (2 or 3)] [logon_parameter]\n");
348                 return NT_STATUS_OK;
349         }
350
351         username = argv[1];
352         password = argv[2];
353
354         if (argc >= 4) 
355                 workstation = argv[3];
356
357         if (argc >= 5)
358                 sscanf(argv[4], "%i", &logon_type);
359
360         if (argc >= 6)
361                 sscanf(argv[5], "%i", &auth_level);
362
363         if (argc == 7)
364                 sscanf(argv[6], "%x", &logon_param);
365
366         /* Perform the sam logon */
367
368         result = rpccli_netlogon_sam_logon(cli, mem_ctx, logon_param, lp_workgroup(), username, password, workstation, logon_type);
369
370         if (!NT_STATUS_IS_OK(result))
371                 goto done;
372
373  done:
374         return result;
375 }
376
377 /* Change the trust account password */
378
379 static NTSTATUS cmd_netlogon_change_trust_pw(struct rpc_pipe_client *cli, 
380                                              TALLOC_CTX *mem_ctx, int argc,
381                                              const char **argv)
382 {
383         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
384
385         /* Check arguments */
386
387         if (argc > 1) {
388                 fprintf(stderr, "Usage: change_trust_pw");
389                 return NT_STATUS_OK;
390         }
391
392         /* Perform the sam logon */
393
394         result = trust_pw_find_change_and_store_it(cli, mem_ctx,
395                                                    lp_workgroup());
396
397         if (!NT_STATUS_IS_OK(result))
398                 goto done;
399
400  done:
401         return result;
402 }
403
404
405 /* List of commands exported by this module */
406
407 struct cmd_set netlogon_commands[] = {
408
409         { "NETLOGON" },
410
411         { "logonctrl2", RPC_RTYPE_NTSTATUS, cmd_netlogon_logon_ctrl2, NULL, PI_NETLOGON, NULL, "Logon Control 2",     "" },
412         { "getdcname", RPC_RTYPE_WERROR, NULL, cmd_netlogon_getdcname, PI_NETLOGON, NULL, "Get trusted PDC name",     "" },
413         { "getanydcname", RPC_RTYPE_WERROR, NULL, cmd_netlogon_getanydcname, PI_NETLOGON, NULL, "Get trusted DC name",     "" },
414         { "dsr_getdcname", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getdcname, PI_NETLOGON, NULL, "Get trusted DC name",     "" },
415         { "dsr_getsitename", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getsitename, PI_NETLOGON, NULL, "Get sitename",     "" },
416         { "logonctrl",  RPC_RTYPE_NTSTATUS, cmd_netlogon_logon_ctrl,  NULL, PI_NETLOGON, NULL, "Logon Control",       "" },
417         { "samsync",    RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_sync,    NULL, PI_NETLOGON, NULL, "Sam Synchronisation", "" },
418         { "samdeltas",  RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_deltas,  NULL, PI_NETLOGON, NULL, "Query Sam Deltas",    "" },
419         { "samlogon",   RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_logon,   NULL, PI_NETLOGON, NULL, "Sam Logon",           "" },
420         { "change_trust_pw",   RPC_RTYPE_NTSTATUS, cmd_netlogon_change_trust_pw,   NULL, PI_NETLOGON, NULL, "Change Trust Account Password",           "" },
421
422         { NULL }
423 };