908245f5dcee90b3ccec46eaf6bc323945514479
[samba.git] / source3 / rpcclient / cmd_samr.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 2.2
4    RPC pipe client
5
6    Copyright (C) Andrew Tridgell              1992-2000,
7    Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
8    Copyright (C) Elrond                            2000
9    Copyright (C) Tim Potter 2000
10
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 2 of the License, or
14    (at your option) any later version.
15    
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20    
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26 #include "includes.h"
27
28 extern DOM_SID domain_sid;
29
30 /****************************************************************************
31  display sam_user_info_21 structure
32  ****************************************************************************/
33 static void display_sam_user_info_21(SAM_USER_INFO_21 *usr)
34 {
35         fstring temp;
36
37         unistr2_to_ascii(temp, &usr->uni_user_name, sizeof(temp)-1);
38         printf("\tUser Name   :\t%s\n", temp);
39         
40         unistr2_to_ascii(temp, &usr->uni_full_name, sizeof(temp)-1);
41         printf("\tFull Name   :\t%s\n", temp);
42         
43         unistr2_to_ascii(temp, &usr->uni_home_dir, sizeof(temp)-1);
44         printf("\tHome Drive  :\t%s\n", temp);
45         
46         unistr2_to_ascii(temp, &usr->uni_dir_drive, sizeof(temp)-1);
47         printf("\tDir Drive   :\t%s\n", temp);
48         
49         unistr2_to_ascii(temp, &usr->uni_profile_path, sizeof(temp)-1);
50         printf("\tProfile Path:\t%s\n", temp);
51         
52         unistr2_to_ascii(temp, &usr->uni_logon_script, sizeof(temp)-1);
53         printf("\tLogon Script:\t%s\n", temp);
54         
55         unistr2_to_ascii(temp, &usr->uni_acct_desc, sizeof(temp)-1);
56         printf("\tDescription :\t%s\n", temp);
57         
58         unistr2_to_ascii(temp, &usr->uni_workstations, sizeof(temp)-1);
59         printf("\tWorkstations:\t%s\n", temp);
60         
61         unistr2_to_ascii(temp, &usr->uni_unknown_str, sizeof(temp)-1);
62         printf("\tUnknown Str :\t%s\n", temp);
63         
64         unistr2_to_ascii(temp, &usr->uni_munged_dial, sizeof(temp)-1);
65         printf("\tRemote Dial :\t%s\n", temp);
66         
67         printf("\tLogon Time               :\t%s\n", 
68                http_timestring(nt_time_to_unix(&usr->logon_time)));
69         printf("\tLogoff Time              :\t%s\n", 
70                http_timestring(nt_time_to_unix(&usr->logoff_time)));
71         printf("\tKickoff Time             :\t%s\n", 
72                http_timestring(nt_time_to_unix(&usr->kickoff_time)));
73         printf("\tPassword last set Time   :\t%s\n", 
74                http_timestring(nt_time_to_unix(&usr->pass_last_set_time)));
75         printf("\tPassword can change Time :\t%s\n", 
76                http_timestring(nt_time_to_unix(&usr->pass_can_change_time)));
77         printf("\tPassword must change Time:\t%s\n", 
78                http_timestring(nt_time_to_unix(&usr->pass_must_change_time)));
79         
80         printf("\tunknown_2[0..31]...\n"); /* user passwords? */
81         
82         printf("\tuser_rid :\t%x\n"  , usr->user_rid ); /* User ID */
83         printf("\tgroup_rid:\t%x\n"  , usr->group_rid); /* Group ID */
84         printf("\tacb_info :\t%04x\n", usr->acb_info ); /* Account Control Info */
85         
86         printf("\tunknown_3:\t%08x\n", usr->unknown_3); /* 0x00ff ffff */
87         printf("\tlogon_divs:\t%d\n", usr->logon_divs); /* 0x0000 00a8 which is 168 which is num hrs in a week */
88         printf("\tunknown_5:\t%08x\n", usr->unknown_5); /* 0x0002 0000 */
89         
90         printf("\tpadding1[0..7]...\n");
91         
92         if (usr->ptr_logon_hrs) {
93                 printf("\tlogon_hrs[0..%d]...\n", usr->logon_hrs.len);
94         }
95 }
96
97 /**********************************************************************
98  * Query user information 
99  */
100 static uint32 cmd_samr_query_user(struct cli_state *cli, int argc, char **argv) 
101 {
102         POLICY_HND connect_pol, domain_pol, user_pol;
103         uint32  result = NT_STATUS_UNSUCCESSFUL, 
104                 info_level = 21;
105         BOOL    got_connect_pol = False, 
106                 got_domain_pol = False,
107                 got_user_pol = False;
108         SAM_USERINFO_CTR user_ctr;
109         SAM_USER_INFO_21 info_21;
110         fstring                 server;
111         
112         if (argc != 1) {
113                 printf("Usage: %s\n", argv[0]);
114                 return 0;
115         }
116
117         /* Initialise RPC connection */
118         if (!cli_nt_session_open (cli, PIPE_SAMR)) {
119                 fprintf (stderr, "Could not initialize samr pipe!\n");
120                 return NT_STATUS_UNSUCCESSFUL;
121         }
122         
123         slprintf (server, sizeof(fstring), "\\\\%s", cli->desthost);
124         strupper (server);
125         
126         if ((result = cli_samr_connect(cli, server, MAXIMUM_ALLOWED_ACCESS,
127                                        &connect_pol)) !=
128             NT_STATUS_NOPROBLEMO) {
129                 goto done;
130         }
131
132         got_connect_pol = True;
133         fetch_domain_sid(cli);
134
135         if ((result = cli_samr_open_domain(cli, &connect_pol,
136                                            MAXIMUM_ALLOWED_ACCESS,
137                                            &domain_sid, &domain_pol))
138              != NT_STATUS_NOPROBLEMO) {
139                 goto done;
140         }
141
142         got_domain_pol = True;
143
144         if ((result = cli_samr_open_user(cli, &domain_pol,
145                                          MAXIMUM_ALLOWED_ACCESS,
146                                          0x1f4, &user_pol))
147             != NT_STATUS_NOPROBLEMO) {
148                 goto done;
149         }
150
151         got_user_pol = True;
152
153         ZERO_STRUCT(user_ctr);
154         ZERO_STRUCT(info_21);
155
156         user_ctr.info.id21 = &info_21;
157
158         if ((result = cli_samr_query_userinfo(cli, &user_pol, info_level,
159                                               &user_ctr)) 
160             != NT_STATUS_NOPROBLEMO) {
161                 goto done;
162         }
163
164         display_sam_user_info_21(&info_21);
165
166 done:
167         if (got_user_pol) cli_samr_close(cli, &user_pol);
168         if (got_domain_pol) cli_samr_close(cli, &domain_pol);
169         if (got_connect_pol) cli_samr_close(cli, &connect_pol);
170
171         cli_nt_session_close(cli);
172
173         return result;
174 }
175
176 /****************************************************************************
177  display group info
178  ****************************************************************************/
179 static void display_group_info1(GROUP_INFO1 *info1)
180 {
181         fstring temp;
182
183         unistr2_to_ascii(temp, &info1->uni_acct_name, sizeof(temp)-1);
184         printf("\tGroup Name:\t%s\n", temp);
185         unistr2_to_ascii(temp, &info1->uni_acct_desc, sizeof(temp)-1);
186         printf("\tDescription:\t%s\n", temp);
187         printf("\tunk1:%d\n", info1->unknown_1);
188         printf("\tNum Members:%d\n", info1->num_members);
189 }
190
191 /****************************************************************************
192  display group info
193  ****************************************************************************/
194 static void display_group_info4(GROUP_INFO4 *info4)
195 {
196         fstring desc;
197
198         unistr2_to_ascii(desc, &info4->uni_acct_desc, sizeof(desc)-1);
199         printf("\tGroup Description:%s\n", desc);
200 }
201
202 /****************************************************************************
203  display sam sync structure
204  ****************************************************************************/
205 static void display_group_info_ctr(GROUP_INFO_CTR *ctr)
206 {
207         switch (ctr->switch_value1) {
208             case 1: {
209                     display_group_info1(&ctr->group.info1);
210                     break;
211             }
212             case 4: {
213                     display_group_info4(&ctr->group.info4);
214                     break;
215             }
216         }
217 }
218
219 /***********************************************************************
220  * Query group information 
221  */
222 static uint32 cmd_samr_query_group(struct cli_state *cli, int argc, char **argv) 
223 {
224         POLICY_HND connect_pol, domain_pol, group_pol;
225         uint32 result = NT_STATUS_UNSUCCESSFUL, info_level = 1;
226         BOOL got_connect_pol = False, got_domain_pol = False,
227                 got_group_pol = False;
228         GROUP_INFO_CTR group_ctr;
229         fstring                 server; 
230         
231         if (argc != 1) {
232                 printf("Usage: %s\n", argv[0]);
233                 return 0;
234         }
235
236         /* Initialise RPC connection */
237         if (!cli_nt_session_open (cli, PIPE_SAMR)) {
238                 fprintf (stderr, "Could not initialize samr pipe!\n");
239                 return NT_STATUS_UNSUCCESSFUL;
240         }
241         
242         slprintf (server, sizeof(fstring), "\\\\%s", cli->desthost);
243         strupper (server);
244
245         if ((result = cli_samr_connect(cli, server, MAXIMUM_ALLOWED_ACCESS,
246                                        &connect_pol)) !=
247             NT_STATUS_NOPROBLEMO) {
248                 goto done;
249         }
250
251         got_connect_pol = True;
252         fetch_domain_sid(cli);
253
254         if ((result = cli_samr_open_domain(cli, &connect_pol,
255                                            MAXIMUM_ALLOWED_ACCESS,
256                                            &domain_sid, &domain_pol))
257              != NT_STATUS_NOPROBLEMO) {
258                 goto done;
259         }
260
261         got_domain_pol = True;
262
263         if ((result = cli_samr_open_group(cli, &domain_pol,
264                                           MAXIMUM_ALLOWED_ACCESS,
265                                           0x202, &group_pol))
266             != NT_STATUS_NOPROBLEMO) {
267                 goto done;
268         }
269
270         got_group_pol = True;
271
272         ZERO_STRUCT(group_ctr);
273
274         if ((result = cli_samr_query_groupinfo(cli, &group_pol, info_level,
275                                                &group_ctr)) 
276             != NT_STATUS_NOPROBLEMO) {
277                 goto done;
278         }
279
280         display_group_info_ctr(&group_ctr);
281
282 done:
283         if (got_group_pol) cli_samr_close(cli, &group_pol);
284         if (got_domain_pol) cli_samr_close(cli, &domain_pol);
285         if (got_connect_pol) cli_samr_close(cli, &connect_pol);
286
287         cli_nt_session_close(cli);
288
289         return result;
290 }
291
292 /* Query groups a user is a member of */
293
294 static uint32 cmd_samr_query_usergroups(struct cli_state *cli, int argc, char **argv) 
295 {
296         POLICY_HND              connect_pol, 
297                                 domain_pol, 
298                                 user_pol;
299         uint32                  result = NT_STATUS_UNSUCCESSFUL;
300         BOOL                    got_connect_pol = False, 
301                                 got_domain_pol = False,
302                                 got_user_pol = False;
303         uint32                  num_groups, 
304                                 user_rid;
305         DOM_GID                 *user_gids;
306         int                     i;
307         fstring                 server;
308         
309         if (argc != 2) {
310                 printf("Usage: %s rid/name\n", argv[0]);
311                 return 0;
312         }
313
314         sscanf(argv[1], "%i", &user_rid);
315
316         /* Initialise RPC connection */
317         if (!cli_nt_session_open (cli, PIPE_SAMR)) {
318                 fprintf (stderr, "Could not initialize samr pipe!\n");
319                 return NT_STATUS_UNSUCCESSFUL;
320         }
321
322         slprintf (server, sizeof(fstring), "\\\\%s", cli->desthost);
323         strupper (server);
324                 
325         if ((result = cli_samr_connect(cli, server, MAXIMUM_ALLOWED_ACCESS,
326                                        &connect_pol)) !=
327             NT_STATUS_NOPROBLEMO) {
328                 goto done;
329         }
330
331         got_connect_pol = True;
332         fetch_domain_sid(cli);
333
334         if ((result = cli_samr_open_domain(cli, &connect_pol,
335                                            MAXIMUM_ALLOWED_ACCESS,
336                                            &domain_sid, &domain_pol))
337              != NT_STATUS_NOPROBLEMO) {
338                 goto done;
339         }
340
341         got_domain_pol = True;
342
343         if ((result = cli_samr_open_user(cli, &domain_pol,
344                                          MAXIMUM_ALLOWED_ACCESS,
345                                          user_rid, &user_pol))
346             != NT_STATUS_NOPROBLEMO) {
347                 goto done;
348         }
349
350         got_user_pol = True;
351
352         if ((result = cli_samr_query_usergroups(cli, &user_pol,
353                                                 &num_groups, &user_gids))
354             != NT_STATUS_NOPROBLEMO) {
355                 goto done;
356         }
357
358         for (i = 0; i < num_groups; i++) {
359                 printf("\tgroup rid:[0x%x] attr:[0x%x]\n", 
360                        user_gids[i].g_rid, user_gids[i].attr);
361         }
362
363  done:
364         if (got_user_pol) cli_samr_close(cli, &user_pol);
365         if (got_domain_pol) cli_samr_close(cli, &domain_pol);
366         if (got_connect_pol) cli_samr_close(cli, &connect_pol);
367
368         cli_nt_session_close(cli);
369
370         return result;
371 }
372
373 /* Query members of a group */
374
375 static uint32 cmd_samr_query_groupmem(struct cli_state *cli, int argc, char **argv) 
376 {
377         POLICY_HND connect_pol, domain_pol, group_pol;
378         uint32 result = NT_STATUS_UNSUCCESSFUL;
379         BOOL    got_connect_pol = False, 
380                 got_domain_pol = False,
381                 got_group_pol = False;
382         uint32 num_members, *group_rids, *group_attrs, group_rid;
383         int i;
384         fstring                 server;
385         
386         if (argc != 2) {
387                 printf("Usage: %s rid/name\n", argv[0]);
388                 return 0;
389         }
390
391         sscanf(argv[1], "%i", &group_rid);
392
393         /* Initialise RPC connection */
394         if (!cli_nt_session_open (cli, PIPE_SAMR)) {
395                 fprintf (stderr, "Could not initialize samr pipe!\n");
396                 return NT_STATUS_UNSUCCESSFUL;
397         }
398
399         slprintf (server, sizeof(fstring), "\\\\%s", cli->desthost);
400         strupper (server);
401
402         if ((result = cli_samr_connect(cli, server, MAXIMUM_ALLOWED_ACCESS,
403                                        &connect_pol)) !=
404             NT_STATUS_NOPROBLEMO) {
405                 goto done;
406         }
407
408         got_connect_pol = True;
409         fetch_domain_sid(cli);
410
411         if ((result = cli_samr_open_domain(cli, &connect_pol,
412                                            MAXIMUM_ALLOWED_ACCESS,
413                                            &domain_sid, &domain_pol))
414              != NT_STATUS_NOPROBLEMO) {
415                 goto done;
416         }
417
418         got_domain_pol = True;
419
420         if ((result = cli_samr_open_group(cli, &domain_pol,
421                                           MAXIMUM_ALLOWED_ACCESS,
422                                           group_rid, &group_pol))
423             != NT_STATUS_NOPROBLEMO) {
424                 goto done;
425         }
426
427         got_group_pol = True;
428
429         if ((result = cli_samr_query_groupmem(cli, &group_pol,
430                                               &num_members, &group_rids,
431                                               &group_attrs))
432             != NT_STATUS_NOPROBLEMO) {
433                 goto done;
434         }
435
436         for (i = 0; i < num_members; i++) {
437                 printf("\trid:[0x%x] attr:[0x%x]\n", group_rids[i],
438                        group_attrs[i]);
439         }
440
441  done:
442         if (got_group_pol) cli_samr_close(cli, &group_pol);
443         if (got_domain_pol) cli_samr_close(cli, &domain_pol);
444         if (got_connect_pol) cli_samr_close(cli, &connect_pol);
445
446         cli_nt_session_close(cli);
447
448         return result;
449 }
450
451 /* List of commands exported by this module */
452
453 struct cmd_set samr_commands[] = {
454         { "SAMR",               NULL,                           "" },
455         { "queryuser",          cmd_samr_query_user,            "Query user info" },
456         { "querygroup",         cmd_samr_query_group,           "Query group info" },
457         { "queryusergroups",    cmd_samr_query_usergroups,      "Query user groups" },
458         { "querygroupmem",      cmd_samr_query_groupmem,        "Query group membership" },
459         { NULL, NULL, NULL }
460 };
461