Initial import
[samba] / source / 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 NTSTATUS cmd_netlogon_getdcname(struct rpc_pipe_client *cli, 
49                                        TALLOC_CTX *mem_ctx, int argc, 
50                                        const char **argv)
51 {
52         fstring dcname;
53         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
54
55         if (argc != 2) {
56                 fprintf(stderr, "Usage: %s domainname\n", argv[0]);
57                 return NT_STATUS_OK;
58         }
59
60         result = rpccli_netlogon_getdcname(cli, mem_ctx, cli->cli->desthost, argv[1], dcname);
61
62         if (!NT_STATUS_IS_OK(result))
63                 goto done;
64
65         /* Display results */
66
67         printf("%s\n", dcname);
68
69  done:
70         return result;
71 }
72
73 static WERROR cmd_netlogon_dsr_getdcname(struct rpc_pipe_client *cli,
74                                          TALLOC_CTX *mem_ctx, int argc,
75                                          const char **argv)
76 {
77         WERROR result;
78         char *dcname, *dcaddress;
79
80         if (argc != 2) {
81                 fprintf(stderr, "Usage: %s domainname\n", argv[0]);
82                 return WERR_OK;
83         }
84
85         result = rpccli_netlogon_dsr_getdcname(
86                 cli, mem_ctx, cli->cli->desthost, argv[1], NULL, NULL,
87                 0x40000000, &dcname, &dcaddress, NULL, NULL, NULL, NULL,
88                 NULL, NULL, NULL);
89
90         if (W_ERROR_IS_OK(result)) {
91                 printf("Domain %s's DC is called %s at IP %s\n",
92                        argv[1], dcname, dcaddress);
93                 return WERR_OK;
94         }
95
96         printf("rpccli_netlogon_dsr_getdcname returned %s\n",
97                nt_errstr(werror_to_ntstatus(result)));
98
99         return result;
100 }
101
102 static WERROR cmd_netlogon_dsr_getsitename(struct rpc_pipe_client *cli,
103                                            TALLOC_CTX *mem_ctx, int argc,
104                                            const char **argv)
105 {
106         WERROR result;
107         char *sitename;
108
109         if (argc != 2) {
110                 fprintf(stderr, "Usage: %s computername\n", argv[0]);
111                 return WERR_OK;
112         }
113
114         result = rpccli_netlogon_dsr_getsitename(cli, mem_ctx, argv[1], &sitename);
115
116         if (!W_ERROR_IS_OK(result)) {
117                 printf("rpccli_netlogon_dsr_gesitename returned %s\n",
118                        nt_errstr(werror_to_ntstatus(result)));
119                 return result;
120         }
121
122         printf("Computer %s is on Site: %s\n", argv[1], sitename);
123
124         return WERR_OK;
125 }
126
127 static NTSTATUS cmd_netlogon_logon_ctrl(struct rpc_pipe_client *cli, 
128                                         TALLOC_CTX *mem_ctx, int argc, 
129                                         const char **argv)
130 {
131 #if 0
132         uint32 query_level = 1;
133 #endif
134         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
135
136         if (argc > 1) {
137                 fprintf(stderr, "Usage: %s\n", argv[0]);
138                 return NT_STATUS_OK;
139         }
140
141 #if 0
142         result = cli_netlogon_logon_ctrl(cli, mem_ctx, query_level);
143         if (!NT_STATUS_IS_OK(result)) {
144                 goto done;
145         }
146 #endif
147
148         /* Display results */
149
150         return result;
151 }
152
153 /* Display sam synchronisation information */
154
155 static void display_sam_sync(uint32 num_deltas, SAM_DELTA_HDR *hdr_deltas,
156                              SAM_DELTA_CTR *deltas)
157 {
158         fstring name;
159         uint32 i, j;
160
161         for (i = 0; i < num_deltas; i++) {
162                 switch (hdr_deltas[i].type) {
163                 case SAM_DELTA_DOMAIN_INFO:
164                         unistr2_to_ascii(name,
165                                          &deltas[i].domain_info.uni_dom_name,
166                                          sizeof(name) - 1);
167                         printf("Domain: %s\n", name);
168                         break;
169                 case SAM_DELTA_GROUP_INFO:
170                         unistr2_to_ascii(name,
171                                          &deltas[i].group_info.uni_grp_name,
172                                          sizeof(name) - 1);
173                         printf("Group: %s\n", name);
174                         break;
175                 case SAM_DELTA_ACCOUNT_INFO:
176                         unistr2_to_ascii(name, 
177                                          &deltas[i].account_info.uni_acct_name,
178                                          sizeof(name) - 1);
179                         printf("Account: %s\n", name);
180                         break;
181                 case SAM_DELTA_ALIAS_INFO:
182                         unistr2_to_ascii(name, 
183                                          &deltas[i].alias_info.uni_als_name,
184                                          sizeof(name) - 1);
185                         printf("Alias: %s\n", name);
186                         break;
187                 case SAM_DELTA_ALIAS_MEM: {
188                         SAM_ALIAS_MEM_INFO *alias = &deltas[i].als_mem_info;
189
190                         for (j = 0; j < alias->num_members; j++) {
191                                 fstring sid_str;
192
193                                 sid_to_string(sid_str, &alias->sids[j].sid);
194
195                                 printf("%s\n", sid_str);
196                         }
197                         break;
198                 }
199                 case SAM_DELTA_GROUP_MEM: {
200                         SAM_GROUP_MEM_INFO *group = &deltas[i].grp_mem_info;
201
202                         for (j = 0; j < group->num_members; j++)
203                                 printf("rid 0x%x, attrib 0x%08x\n", 
204                                           group->rids[j], group->attribs[j]);
205                         break;
206                 }
207                 case SAM_DELTA_MODIFIED_COUNT: {
208                         SAM_DELTA_MOD_COUNT *mc = &deltas[i].mod_count;
209
210                         printf("sam sequence update: 0x%04x\n", mc->seqnum);
211                         break;
212                 }                                  
213                 default:
214                         printf("unknown delta type 0x%02x\n", 
215                                   hdr_deltas[i].type);
216                         break;
217                 }
218         }
219 }
220
221 /* Perform sam synchronisation */
222
223 static NTSTATUS cmd_netlogon_sam_sync(struct rpc_pipe_client *cli, 
224                                       TALLOC_CTX *mem_ctx, int argc,
225                                       const char **argv)
226 {
227         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
228         uint32 database_id = 0, num_deltas;
229         SAM_DELTA_HDR *hdr_deltas;
230         SAM_DELTA_CTR *deltas;
231
232         if (argc > 2) {
233                 fprintf(stderr, "Usage: %s [database_id]\n", argv[0]);
234                 return NT_STATUS_OK;
235         }
236
237         if (argc == 2)
238                 database_id = atoi(argv[1]);
239
240         /* Synchronise sam database */
241
242         result = rpccli_netlogon_sam_sync(cli, mem_ctx, database_id,
243                                        0, &num_deltas, &hdr_deltas, &deltas);
244
245         if (!NT_STATUS_IS_OK(result))
246                 goto done;
247
248         /* Display results */
249
250         display_sam_sync(num_deltas, hdr_deltas, deltas);
251
252  done:
253         return result;
254 }
255
256 /* Perform sam delta synchronisation */
257
258 static NTSTATUS cmd_netlogon_sam_deltas(struct rpc_pipe_client *cli, 
259                                         TALLOC_CTX *mem_ctx, int argc,
260                                         const char **argv)
261 {
262         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
263         uint32 database_id, num_deltas, tmp;
264         SAM_DELTA_HDR *hdr_deltas;
265         SAM_DELTA_CTR *deltas;
266         UINT64_S seqnum;
267
268         if (argc != 3) {
269                 fprintf(stderr, "Usage: %s database_id seqnum\n", argv[0]);
270                 return NT_STATUS_OK;
271         }
272
273         database_id = atoi(argv[1]);
274         tmp = atoi(argv[2]);
275
276         seqnum.low = tmp & 0xffff;
277         seqnum.high = 0;
278
279         result = rpccli_netlogon_sam_deltas(cli, mem_ctx, database_id,
280                                          seqnum, &num_deltas, 
281                                          &hdr_deltas, &deltas);
282
283         if (!NT_STATUS_IS_OK(result))
284                 goto done;
285
286         /* Display results */
287
288         display_sam_sync(num_deltas, hdr_deltas, deltas);
289         
290  done:
291         return result;
292 }
293
294 /* Log on a domain user */
295
296 static NTSTATUS cmd_netlogon_sam_logon(struct rpc_pipe_client *cli, 
297                                        TALLOC_CTX *mem_ctx, int argc,
298                                        const char **argv)
299 {
300         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
301         int logon_type = NET_LOGON_TYPE;
302         const char *username, *password;
303         uint32 neg_flags = 0x000001ff;
304         int auth_level = 2;
305
306         /* Check arguments */
307
308         if (argc < 3 || argc > 6) {
309                 fprintf(stderr, "Usage: samlogon <username> <password> "
310                         "[logon_type] [neg flags] [auth level (2 or 3)]\n"
311                         "neg flags being 0x000001ff or 0x6007ffff\n");
312                 return NT_STATUS_OK;
313         }
314
315         username = argv[1];
316         password = argv[2];
317
318         if (argc >= 4)
319                 sscanf(argv[3], "%i", &logon_type);
320
321         if (argc >= 5)
322                 sscanf(argv[4], "%i", &neg_flags);
323
324         if (argc == 6)
325                 sscanf(argv[5], "%i", &auth_level);
326
327         /* Perform the sam logon */
328
329         result = rpccli_netlogon_sam_logon(cli, mem_ctx, 0, lp_workgroup(), username, password, logon_type);
330
331         if (!NT_STATUS_IS_OK(result))
332                 goto done;
333
334  done:
335         return result;
336 }
337
338 /* Change the trust account password */
339
340 static NTSTATUS cmd_netlogon_change_trust_pw(struct rpc_pipe_client *cli, 
341                                              TALLOC_CTX *mem_ctx, int argc,
342                                              const char **argv)
343 {
344         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
345
346         /* Check arguments */
347
348         if (argc > 1) {
349                 fprintf(stderr, "Usage: change_trust_pw");
350                 return NT_STATUS_OK;
351         }
352
353         /* Perform the sam logon */
354
355         result = trust_pw_find_change_and_store_it(cli, mem_ctx,
356                                                    lp_workgroup());
357
358         if (!NT_STATUS_IS_OK(result))
359                 goto done;
360
361  done:
362         return result;
363 }
364
365
366 /* List of commands exported by this module */
367
368 struct cmd_set netlogon_commands[] = {
369
370         { "NETLOGON" },
371
372         { "logonctrl2", RPC_RTYPE_NTSTATUS, cmd_netlogon_logon_ctrl2, NULL, PI_NETLOGON, NULL, "Logon Control 2",     "" },
373         { "getdcname", RPC_RTYPE_NTSTATUS, cmd_netlogon_getdcname, NULL, PI_NETLOGON, NULL, "Get trusted DC name",     "" },
374         { "dsr_getdcname", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getdcname, PI_NETLOGON, NULL, "Get trusted DC name",     "" },
375         { "dsr_getsitename", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getsitename, PI_NETLOGON, NULL, "Get sitename",     "" },
376         { "logonctrl",  RPC_RTYPE_NTSTATUS, cmd_netlogon_logon_ctrl,  NULL, PI_NETLOGON, NULL, "Logon Control",       "" },
377         { "samsync",    RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_sync,    NULL, PI_NETLOGON, NULL, "Sam Synchronisation", "" },
378         { "samdeltas",  RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_deltas,  NULL, PI_NETLOGON, NULL, "Query Sam Deltas",    "" },
379         { "samlogon",   RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_logon,   NULL, PI_NETLOGON, NULL, "Sam Logon",           "" },
380         { "change_trust_pw",   RPC_RTYPE_NTSTATUS, cmd_netlogon_change_trust_pw,   NULL, PI_NETLOGON, NULL, "Change Trust Account Password",           "" },
381
382         { NULL }
383 };