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