Use rpccli_samr_QueryUserInfo() in rpcclient.
[ira/wip.git] / source3 / rpcclient / cmd_samr.c
1 /*
2    Unix SMB/CIFS implementation.
3    RPC pipe client
4
5    Copyright (C) Andrew Tridgell              1992-2000,
6    Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
7    Copyright (C) Elrond                            2000,
8    Copyright (C) Tim Potter                        2000
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25 #include "rpcclient.h"
26
27 extern DOM_SID domain_sid;
28
29 static void init_lsa_String(struct lsa_String *name, const char *s)
30 {
31         name->string = s;
32 }
33
34 /****************************************************************************
35  display samr_user_info_7 structure
36  ****************************************************************************/
37 static void display_samr_user_info_7(struct samr_UserInfo7 *r)
38 {
39         printf("\tUser Name   :\t%s\n", r->account_name.string);
40 }
41
42 /****************************************************************************
43  display samr_user_info_9 structure
44  ****************************************************************************/
45 static void display_samr_user_info_9(struct samr_UserInfo9 *r)
46 {
47         printf("\tPrimary group RID   :\tox%x\n", r->primary_gid);
48 }
49
50 /****************************************************************************
51  display samr_user_info_16 structure
52  ****************************************************************************/
53 static void display_samr_user_info_16(struct samr_UserInfo16 *r)
54 {
55         printf("\tAcct Flags   :\tox%x\n", r->acct_flags);
56 }
57
58 /****************************************************************************
59  display samr_user_info_21 structure
60  ****************************************************************************/
61 static void display_samr_user_info_21(struct samr_UserInfo21 *r)
62 {
63         printf("\tUser Name   :\t%s\n", r->account_name.string);
64         printf("\tFull Name   :\t%s\n", r->full_name.string);
65         printf("\tHome Drive  :\t%s\n", r->home_directory.string);
66         printf("\tDir Drive   :\t%s\n", r->home_drive.string);
67         printf("\tProfile Path:\t%s\n", r->profile_path.string);
68         printf("\tLogon Script:\t%s\n", r->logon_script.string);
69         printf("\tDescription :\t%s\n", r->description.string);
70         printf("\tWorkstations:\t%s\n", r->workstations.string);
71         printf("\tComment     :\t%s\n", r->comment.string);
72         printf("\tRemote Dial :\t%s\n", r->parameters.string);
73
74         printf("\tLogon Time               :\t%s\n",
75                http_timestring(nt_time_to_unix(r->last_logon)));
76         printf("\tLogoff Time              :\t%s\n",
77                http_timestring(nt_time_to_unix(r->last_logoff)));
78         printf("\tKickoff Time             :\t%s\n",
79                http_timestring(nt_time_to_unix(r->acct_expiry)));
80         printf("\tPassword last set Time   :\t%s\n",
81                http_timestring(nt_time_to_unix(r->last_password_change)));
82         printf("\tPassword can change Time :\t%s\n",
83                http_timestring(nt_time_to_unix(r->allow_password_change)));
84         printf("\tPassword must change Time:\t%s\n",
85                http_timestring(nt_time_to_unix(r->force_password_change)));
86
87         printf("\tunknown_2[0..31]...\n"); /* user passwords? */
88
89         printf("\tuser_rid :\t0x%x\n"  , r->rid); /* User ID */
90         printf("\tgroup_rid:\t0x%x\n"  , r->primary_gid); /* Group ID */
91         printf("\tacb_info :\t0x%08x\n", r->acct_flags); /* Account Control Info */
92
93         printf("\tfields_present:\t0x%08x\n", r->fields_present); /* 0x00ff ffff */
94         printf("\tlogon_divs:\t%d\n", r->logon_hours.units_per_week); /* 0x0000 00a8 which is 168 which is num hrs in a week */
95         printf("\tbad_password_count:\t0x%08x\n", r->bad_password_count);
96         printf("\tlogon_count:\t0x%08x\n", r->logon_count);
97
98         printf("\tpadding1[0..7]...\n");
99
100         if (r->logon_hours.bits) {
101                 printf("\tlogon_hrs[0..%d]...\n", r->logon_hours.units_per_week/8);
102         }
103 }
104
105
106 static void display_password_properties(uint32_t password_properties)
107 {
108         printf("password_properties: 0x%08x\n", password_properties);
109
110         if (password_properties & DOMAIN_PASSWORD_COMPLEX)
111                 printf("\tDOMAIN_PASSWORD_COMPLEX\n");
112
113         if (password_properties & DOMAIN_PASSWORD_NO_ANON_CHANGE)
114                 printf("\tDOMAIN_PASSWORD_NO_ANON_CHANGE\n");
115
116         if (password_properties & DOMAIN_PASSWORD_NO_CLEAR_CHANGE)
117                 printf("\tDOMAIN_PASSWORD_NO_CLEAR_CHANGE\n");
118
119         if (password_properties & DOMAIN_PASSWORD_LOCKOUT_ADMINS)
120                 printf("\tDOMAIN_PASSWORD_LOCKOUT_ADMINS\n");
121
122         if (password_properties & DOMAIN_PASSWORD_STORE_CLEARTEXT)
123                 printf("\tDOMAIN_PASSWORD_STORE_CLEARTEXT\n");
124
125         if (password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE)
126                 printf("\tDOMAIN_REFUSE_PASSWORD_CHANGE\n");
127 }
128
129 static void display_sam_dom_info_1(struct samr_DomInfo1 *info1)
130 {
131         printf("Minimum password length:\t\t\t%d\n",
132                 info1->min_password_length);
133         printf("Password uniqueness (remember x passwords):\t%d\n",
134                 info1->password_history_length);
135         display_password_properties(info1->password_properties);
136         printf("password expire in:\t\t\t\t%s\n",
137                 display_time(info1->max_password_age));
138         printf("Min password age (allow changing in x days):\t%s\n",
139                 display_time(info1->min_password_age));
140 }
141
142 static void display_sam_dom_info_2(struct samr_DomInfo2 *info2)
143 {
144         printf("Domain:\t\t%s\n", info2->domain_name.string);
145         printf("Server:\t\t%s\n", info2->primary.string);
146         printf("Comment:\t%s\n", info2->comment.string);
147
148         printf("Total Users:\t%d\n", info2->num_users);
149         printf("Total Groups:\t%d\n", info2->num_groups);
150         printf("Total Aliases:\t%d\n", info2->num_aliases);
151
152         printf("Sequence No:\t%llu\n", (unsigned long long)info2->sequence_num);
153
154         printf("Force Logoff:\t%d\n",
155                 (int)nt_time_to_unix_abs(&info2->force_logoff_time));
156
157         printf("Unknown 2:\t0x%x\n", info2->unknown2);
158         printf("Server Role:\t%s\n", server_role_str(info2->role));
159         printf("Unknown 3:\t0x%x\n", info2->unknown3);
160 }
161
162 static void display_sam_dom_info_3(struct samr_DomInfo3 *info3)
163 {
164         printf("Force Logoff:\t%d\n",
165                 (int)nt_time_to_unix_abs(&info3->force_logoff_time));
166 }
167
168 static void display_sam_dom_info_4(struct samr_DomInfo4 *info4)
169 {
170         printf("Comment:\t%s\n", info4->comment.string);
171 }
172
173 static void display_sam_dom_info_5(struct samr_DomInfo5 *info5)
174 {
175         printf("Domain:\t\t%s\n", info5->domain_name.string);
176 }
177
178 static void display_sam_dom_info_6(struct samr_DomInfo6 *info6)
179 {
180         printf("Server:\t\t%s\n", info6->primary.string);
181 }
182
183 static void display_sam_dom_info_7(struct samr_DomInfo7 *info7)
184 {
185         printf("Server Role:\t%s\n", server_role_str(info7->role));
186 }
187
188 static void display_sam_dom_info_8(struct samr_DomInfo8 *info8)
189 {
190         printf("Sequence No:\t%llu\n", (unsigned long long)info8->sequence_num);
191         printf("Domain Create Time:\t%s\n",
192                 http_timestring(nt_time_to_unix(info8->domain_create_time)));
193 }
194
195 static void display_sam_dom_info_9(struct samr_DomInfo9 *info9)
196 {
197         printf("unknown:\t%d (0x%08x)\n", info9->unknown, info9->unknown);
198 }
199
200 static void display_sam_dom_info_12(struct samr_DomInfo12 *info12)
201 {
202         printf("Bad password lockout duration:               %s\n",
203                 display_time(info12->lockout_duration));
204         printf("Reset Lockout after:                         %s\n",
205                 display_time(info12->lockout_window));
206         printf("Lockout after bad attempts:                  %d\n",
207                 info12->lockout_threshold);
208 }
209
210 static void display_sam_dom_info_13(struct samr_DomInfo13 *info13)
211 {
212         printf("Sequence No:\t%llu\n", (unsigned long long)info13->sequence_num);
213         printf("Domain Create Time:\t%s\n",
214                 http_timestring(nt_time_to_unix(info13->domain_create_time)));
215         printf("Unknown1:\t%d\n", info13->unknown1);
216         printf("Unknown2:\t%d\n", info13->unknown2);
217
218 }
219
220 static void display_sam_info_1(struct samr_DispEntryGeneral *r)
221 {
222         printf("index: 0x%x ", r->idx);
223         printf("RID: 0x%x ", r->rid);
224         printf("acb: 0x%08x ", r->acct_flags);
225         printf("Account: %s\t", r->account_name.string);
226         printf("Name: %s\t", r->full_name.string);
227         printf("Desc: %s\n", r->description.string);
228 }
229
230 static void display_sam_info_2(struct samr_DispEntryFull *r)
231 {
232         printf("index: 0x%x ", r->idx);
233         printf("RID: 0x%x ", r->rid);
234         printf("acb: 0x%08x ", r->acct_flags);
235         printf("Account: %s\t", r->account_name.string);
236         printf("Desc: %s\n", r->description.string);
237 }
238
239 static void display_sam_info_3(struct samr_DispEntryFullGroup *r)
240 {
241         printf("index: 0x%x ", r->idx);
242         printf("RID: 0x%x ", r->rid);
243         printf("acb: 0x%08x ", r->acct_flags);
244         printf("Account: %s\t", r->account_name.string);
245         printf("Desc: %s\n", r->description.string);
246 }
247
248 static void display_sam_info_4(struct samr_DispEntryAscii *r)
249 {
250         printf("index: 0x%x ", r->idx);
251         printf("Account: %s\n", r->account_name.string);
252 }
253
254 static void display_sam_info_5(struct samr_DispEntryAscii *r)
255 {
256         printf("index: 0x%x ", r->idx);
257         printf("Account: %s\n", r->account_name.string);
258 }
259
260 /****************************************************************************
261  Try samr_connect4 first, then samr_connect2 if it fails
262  ****************************************************************************/
263 static NTSTATUS try_samr_connects(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
264                                   uint32 access_mask, POLICY_HND *connect_pol)
265 {
266         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
267
268         result = rpccli_samr_Connect4(cli, mem_ctx,
269                                       cli->cli->desthost,
270                                       SAMR_CONNECT_W2K,
271                                       access_mask,
272                                       connect_pol);
273         if (!NT_STATUS_IS_OK(result)) {
274                 result = rpccli_samr_Connect2(cli, mem_ctx,
275                                               cli->cli->desthost,
276                                               access_mask,
277                                               connect_pol);
278         }
279         return result;
280 }
281
282 /**********************************************************************
283  * Query user information
284  */
285 static NTSTATUS cmd_samr_query_user(struct rpc_pipe_client *cli,
286                                     TALLOC_CTX *mem_ctx,
287                                     int argc, const char **argv)
288 {
289         POLICY_HND connect_pol, domain_pol, user_pol;
290         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
291         uint32 info_level = 21;
292         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
293         union samr_UserInfo *info = NULL;
294         fstring server;
295         uint32 user_rid = 0;
296
297         if ((argc < 2) || (argc > 4)) {
298                 printf("Usage: %s rid [info level] [access mask] \n", argv[0]);
299                 return NT_STATUS_OK;
300         }
301
302         sscanf(argv[1], "%i", &user_rid);
303
304         if (argc > 2)
305                 sscanf(argv[2], "%i", &info_level);
306
307         if (argc > 3)
308                 sscanf(argv[3], "%x", &access_mask);
309
310
311         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
312         strupper_m(server);
313
314         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
315                                    &connect_pol);
316
317         if (!NT_STATUS_IS_OK(result))
318                 goto done;
319
320         result = rpccli_samr_OpenDomain(cli, mem_ctx,
321                                         &connect_pol,
322                                         MAXIMUM_ALLOWED_ACCESS,
323                                         &domain_sid,
324                                         &domain_pol);
325         if (!NT_STATUS_IS_OK(result))
326                 goto done;
327
328         result = rpccli_samr_OpenUser(cli, mem_ctx,
329                                       &domain_pol,
330                                       access_mask,
331                                       user_rid,
332                                       &user_pol);
333
334         if (NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_USER) &&
335             (user_rid == 0)) {
336
337                 /* Probably this was a user name, try lookupnames */
338                 struct samr_Ids rids, types;
339                 struct lsa_String lsa_acct_name;
340
341                 init_lsa_String(&lsa_acct_name, argv[1]);
342
343                 result = rpccli_samr_LookupNames(cli, mem_ctx,
344                                                  &domain_pol,
345                                                  1,
346                                                  &lsa_acct_name,
347                                                  &rids,
348                                                  &types);
349
350                 if (NT_STATUS_IS_OK(result)) {
351                         result = rpccli_samr_OpenUser(cli, mem_ctx,
352                                                       &domain_pol,
353                                                       access_mask,
354                                                       rids.ids[0],
355                                                       &user_pol);
356                 }
357         }
358
359
360         if (!NT_STATUS_IS_OK(result))
361                 goto done;
362
363         result = rpccli_samr_QueryUserInfo(cli, mem_ctx,
364                                            &user_pol,
365                                            info_level,
366                                            &info);
367
368         if (!NT_STATUS_IS_OK(result))
369                 goto done;
370
371         switch (info_level) {
372         case 7:
373                 display_samr_user_info_7(&info->info7);
374                 break;
375         case 9:
376                 display_samr_user_info_9(&info->info9);
377                 break;
378         case 16:
379                 display_samr_user_info_16(&info->info16);
380                 break;
381         case 21:
382                 display_samr_user_info_21(&info->info21);
383                 break;
384         default:
385                 printf("Unsupported infolevel: %d\n", info_level);
386                 break;
387         }
388
389         rpccli_samr_Close(cli, mem_ctx, &user_pol);
390         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
391         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
392
393 done:
394         return result;
395 }
396
397 /****************************************************************************
398  display group info
399  ****************************************************************************/
400 static void display_group_info1(struct samr_GroupInfoAll *info1)
401 {
402         printf("\tGroup Name:\t%s\n", info1->name.string);
403         printf("\tDescription:\t%s\n", info1->description.string);
404         printf("\tGroup Attribute:%d\n", info1->attributes);
405         printf("\tNum Members:%d\n", info1->num_members);
406 }
407
408 /****************************************************************************
409  display group info
410  ****************************************************************************/
411 static void display_group_info2(struct lsa_String *info2)
412 {
413         printf("\tGroup Description:%s\n", info2->string);
414 }
415
416
417 /****************************************************************************
418  display group info
419  ****************************************************************************/
420 static void display_group_info3(struct samr_GroupInfoAttributes *info3)
421 {
422         printf("\tGroup Attribute:%d\n", info3->attributes);
423 }
424
425
426 /****************************************************************************
427  display group info
428  ****************************************************************************/
429 static void display_group_info4(struct lsa_String *info4)
430 {
431         printf("\tGroup Description:%s\n", info4->string);
432 }
433
434 /****************************************************************************
435  display group info
436  ****************************************************************************/
437 static void display_group_info5(struct samr_GroupInfoAll *info5)
438 {
439         printf("\tGroup Name:\t%s\n", info5->name.string);
440         printf("\tDescription:\t%s\n", info5->description.string);
441         printf("\tGroup Attribute:%d\n", info5->attributes);
442         printf("\tNum Members:%d\n", info5->num_members);
443 }
444
445 /****************************************************************************
446  display sam sync structure
447  ****************************************************************************/
448 static void display_group_info(union samr_GroupInfo *info,
449                                enum samr_GroupInfoEnum level)
450 {
451         switch (level) {
452                 case 1:
453                         display_group_info1(&info->all);
454                         break;
455                 case 2:
456                         display_group_info2(&info->name);
457                         break;
458                 case 3:
459                         display_group_info3(&info->attributes);
460                         break;
461                 case 4:
462                         display_group_info4(&info->description);
463                         break;
464                 case 5:
465                         display_group_info5(&info->all2);
466                         break;
467         }
468 }
469
470 /***********************************************************************
471  * Query group information
472  */
473 static NTSTATUS cmd_samr_query_group(struct rpc_pipe_client *cli,
474                                      TALLOC_CTX *mem_ctx,
475                                      int argc, const char **argv)
476 {
477         POLICY_HND connect_pol, domain_pol, group_pol;
478         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
479         enum samr_GroupInfoEnum info_level = GROUPINFOALL;
480         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
481         union samr_GroupInfo *group_info = NULL;
482         fstring                 server;
483         uint32 group_rid;
484
485         if ((argc < 2) || (argc > 4)) {
486                 printf("Usage: %s rid [info level] [access mask]\n", argv[0]);
487                 return NT_STATUS_OK;
488         }
489
490         sscanf(argv[1], "%i", &group_rid);
491
492         if (argc > 2)
493                 info_level = atoi(argv[2]);
494
495         if (argc > 3)
496                 sscanf(argv[3], "%x", &access_mask);
497
498         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
499         strupper_m(server);
500
501         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
502                                    &connect_pol);
503
504         if (!NT_STATUS_IS_OK(result))
505                 goto done;
506
507         result = rpccli_samr_OpenDomain(cli, mem_ctx,
508                                         &connect_pol,
509                                         MAXIMUM_ALLOWED_ACCESS,
510                                         &domain_sid,
511                                         &domain_pol);
512
513         if (!NT_STATUS_IS_OK(result))
514                 goto done;
515
516         result = rpccli_samr_OpenGroup(cli, mem_ctx,
517                                        &domain_pol,
518                                        access_mask,
519                                        group_rid,
520                                        &group_pol);
521
522         if (!NT_STATUS_IS_OK(result))
523                 goto done;
524
525         result = rpccli_samr_QueryGroupInfo(cli, mem_ctx,
526                                             &group_pol,
527                                             info_level,
528                                             &group_info);
529         if (!NT_STATUS_IS_OK(result)) {
530                 goto done;
531         }
532
533         display_group_info(group_info, info_level);
534
535         rpccli_samr_Close(cli, mem_ctx, &group_pol);
536         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
537         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
538 done:
539         return result;
540 }
541
542 /* Query groups a user is a member of */
543
544 static NTSTATUS cmd_samr_query_usergroups(struct rpc_pipe_client *cli,
545                                           TALLOC_CTX *mem_ctx,
546                                           int argc, const char **argv)
547 {
548         POLICY_HND              connect_pol,
549                                 domain_pol,
550                                 user_pol;
551         NTSTATUS                result = NT_STATUS_UNSUCCESSFUL;
552         uint32                  user_rid;
553         uint32                  access_mask = MAXIMUM_ALLOWED_ACCESS;
554         int                     i;
555         fstring                 server;
556         struct samr_RidWithAttributeArray *rid_array = NULL;
557
558         if ((argc < 2) || (argc > 3)) {
559                 printf("Usage: %s rid [access mask]\n", argv[0]);
560                 return NT_STATUS_OK;
561         }
562
563         sscanf(argv[1], "%i", &user_rid);
564
565         if (argc > 2)
566                 sscanf(argv[2], "%x", &access_mask);
567
568         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
569         strupper_m(server);
570
571         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
572                                    &connect_pol);
573
574         if (!NT_STATUS_IS_OK(result))
575                 goto done;
576
577         result = rpccli_samr_OpenDomain(cli, mem_ctx,
578                                         &connect_pol,
579                                         MAXIMUM_ALLOWED_ACCESS,
580                                         &domain_sid, &domain_pol);
581
582         if (!NT_STATUS_IS_OK(result))
583                 goto done;
584
585         result = rpccli_samr_OpenUser(cli, mem_ctx,
586                                       &domain_pol,
587                                       access_mask,
588                                       user_rid,
589                                       &user_pol);
590
591         if (!NT_STATUS_IS_OK(result))
592                 goto done;
593
594         result = rpccli_samr_GetGroupsForUser(cli, mem_ctx,
595                                               &user_pol,
596                                               &rid_array);
597
598         if (!NT_STATUS_IS_OK(result))
599                 goto done;
600
601         for (i = 0; i < rid_array->count; i++) {
602                 printf("\tgroup rid:[0x%x] attr:[0x%x]\n",
603                        rid_array->rids[i].rid,
604                        rid_array->rids[i].attributes);
605         }
606
607         rpccli_samr_Close(cli, mem_ctx, &user_pol);
608         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
609         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
610  done:
611         return result;
612 }
613
614 /* Query aliases a user is a member of */
615
616 static NTSTATUS cmd_samr_query_useraliases(struct rpc_pipe_client *cli,
617                                            TALLOC_CTX *mem_ctx,
618                                            int argc, const char **argv)
619 {
620         POLICY_HND              connect_pol, domain_pol;
621         NTSTATUS                result = NT_STATUS_UNSUCCESSFUL;
622         DOM_SID                *sids;
623         size_t                     num_sids;
624         uint32                  access_mask = MAXIMUM_ALLOWED_ACCESS;
625         int                     i;
626         fstring                 server;
627         struct lsa_SidArray sid_array;
628         struct samr_Ids alias_rids;
629
630         if (argc < 3) {
631                 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
632                 return NT_STATUS_INVALID_PARAMETER;
633         }
634
635         sids = NULL;
636         num_sids = 0;
637
638         for (i=2; i<argc; i++) {
639                 DOM_SID tmp_sid;
640                 if (!string_to_sid(&tmp_sid, argv[i])) {
641                         printf("%s is not a legal SID\n", argv[i]);
642                         return NT_STATUS_INVALID_PARAMETER;
643                 }
644                 result = add_sid_to_array(mem_ctx, &tmp_sid, &sids, &num_sids);
645                 if (!NT_STATUS_IS_OK(result)) {
646                         return result;
647                 }
648         }
649
650         if (num_sids) {
651                 sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_sids);
652                 if (sid_array.sids == NULL)
653                         return NT_STATUS_NO_MEMORY;
654         } else {
655                 sid_array.sids = NULL;
656         }
657
658         for (i=0; i<num_sids; i++) {
659                 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[i]);
660                 if (!sid_array.sids[i].sid) {
661                         return NT_STATUS_NO_MEMORY;
662                 }
663         }
664
665         sid_array.num_sids = num_sids;
666
667         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
668         strupper_m(server);
669
670         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
671                                    &connect_pol);
672
673         if (!NT_STATUS_IS_OK(result))
674                 goto done;
675
676         if (StrCaseCmp(argv[1], "domain")==0)
677                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
678                                                 &connect_pol,
679                                                 access_mask,
680                                                 &domain_sid, &domain_pol);
681         else if (StrCaseCmp(argv[1], "builtin")==0)
682                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
683                                                 &connect_pol,
684                                                 access_mask,
685                                                 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
686                                                 &domain_pol);
687         else {
688                 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
689                 return NT_STATUS_INVALID_PARAMETER;
690         }
691
692         if (!NT_STATUS_IS_OK(result))
693                 goto done;
694
695         result = rpccli_samr_GetAliasMembership(cli, mem_ctx,
696                                                 &domain_pol,
697                                                 &sid_array,
698                                                 &alias_rids);
699         if (!NT_STATUS_IS_OK(result))
700                 goto done;
701
702         for (i = 0; i < alias_rids.count; i++) {
703                 printf("\tgroup rid:[0x%x]\n", alias_rids.ids[i]);
704         }
705
706         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
707         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
708  done:
709         return result;
710 }
711
712 /* Query members of a group */
713
714 static NTSTATUS cmd_samr_query_groupmem(struct rpc_pipe_client *cli,
715                                         TALLOC_CTX *mem_ctx,
716                                         int argc, const char **argv)
717 {
718         POLICY_HND connect_pol, domain_pol, group_pol;
719         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
720         uint32 group_rid;
721         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
722         int i;
723         fstring                 server;
724         unsigned int old_timeout;
725         struct samr_RidTypeArray *rids = NULL;
726
727         if ((argc < 2) || (argc > 3)) {
728                 printf("Usage: %s rid [access mask]\n", argv[0]);
729                 return NT_STATUS_OK;
730         }
731
732         sscanf(argv[1], "%i", &group_rid);
733
734         if (argc > 2)
735                 sscanf(argv[2], "%x", &access_mask);
736
737         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
738         strupper_m(server);
739
740         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
741                                    &connect_pol);
742
743         if (!NT_STATUS_IS_OK(result))
744                 goto done;
745
746         result = rpccli_samr_OpenDomain(cli, mem_ctx,
747                                         &connect_pol,
748                                         MAXIMUM_ALLOWED_ACCESS,
749                                         &domain_sid,
750                                         &domain_pol);
751
752         if (!NT_STATUS_IS_OK(result))
753                 goto done;
754
755         result = rpccli_samr_OpenGroup(cli, mem_ctx,
756                                        &domain_pol,
757                                        access_mask,
758                                        group_rid,
759                                        &group_pol);
760
761         if (!NT_STATUS_IS_OK(result))
762                 goto done;
763
764         /* Make sure to wait for our DC's reply */
765         old_timeout = cli_set_timeout(cli->cli, MAX(cli->cli->timeout,30000)); /* 30 seconds. */
766
767         result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
768                                               &group_pol,
769                                               &rids);
770
771         cli_set_timeout(cli->cli, old_timeout);
772
773         if (!NT_STATUS_IS_OK(result))
774                 goto done;
775
776         for (i = 0; i < rids->count; i++) {
777                 printf("\trid:[0x%x] attr:[0x%x]\n", rids->rids[i],
778                        rids->types[i]);
779         }
780
781         rpccli_samr_Close(cli, mem_ctx, &group_pol);
782         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
783         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
784  done:
785         return result;
786 }
787
788 /* Enumerate domain users */
789
790 static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli,
791                                         TALLOC_CTX *mem_ctx,
792                                         int argc, const char **argv)
793 {
794         POLICY_HND connect_pol, domain_pol;
795         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
796         uint32 start_idx, size, num_dom_users, i;
797         struct samr_SamArray *dom_users = NULL;
798         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
799         uint32 acb_mask = ACB_NORMAL;
800         bool got_connect_pol = False, got_domain_pol = False;
801
802         if ((argc < 1) || (argc > 3)) {
803                 printf("Usage: %s [access_mask] [acb_mask]\n", argv[0]);
804                 return NT_STATUS_OK;
805         }
806
807         if (argc > 1)
808                 sscanf(argv[1], "%x", &access_mask);
809
810         if (argc > 2)
811                 sscanf(argv[2], "%x", &acb_mask);
812
813         /* Get sam policy handle */
814
815         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
816                                    &connect_pol);
817
818         if (!NT_STATUS_IS_OK(result))
819                 goto done;
820
821         got_connect_pol = True;
822
823         /* Get domain policy handle */
824
825         result = rpccli_samr_OpenDomain(cli, mem_ctx,
826                                         &connect_pol,
827                                         access_mask,
828                                         &domain_sid,
829                                         &domain_pol);
830
831         if (!NT_STATUS_IS_OK(result))
832                 goto done;
833
834         got_domain_pol = True;
835
836         /* Enumerate domain users */
837
838         start_idx = 0;
839         size = 0xffff;
840
841         do {
842                 result = rpccli_samr_EnumDomainUsers(cli, mem_ctx,
843                                                      &domain_pol,
844                                                      &start_idx,
845                                                      acb_mask,
846                                                      &dom_users,
847                                                      size,
848                                                      &num_dom_users);
849
850                 if (NT_STATUS_IS_OK(result) ||
851                     NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
852
853                         for (i = 0; i < num_dom_users; i++)
854                                printf("user:[%s] rid:[0x%x]\n",
855                                        dom_users->entries[i].name.string,
856                                        dom_users->entries[i].idx);
857                 }
858
859         } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
860
861  done:
862         if (got_domain_pol)
863                 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
864
865         if (got_connect_pol)
866                 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
867
868         return result;
869 }
870
871 /* Enumerate domain groups */
872
873 static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli,
874                                          TALLOC_CTX *mem_ctx,
875                                          int argc, const char **argv)
876 {
877         POLICY_HND connect_pol, domain_pol;
878         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
879         uint32 start_idx, size, num_dom_groups, i;
880         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
881         struct samr_SamArray *dom_groups = NULL;
882         bool got_connect_pol = False, got_domain_pol = False;
883
884         if ((argc < 1) || (argc > 2)) {
885                 printf("Usage: %s [access_mask]\n", argv[0]);
886                 return NT_STATUS_OK;
887         }
888
889         if (argc > 1)
890                 sscanf(argv[1], "%x", &access_mask);
891
892         /* Get sam policy handle */
893
894         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
895                                    &connect_pol);
896
897         if (!NT_STATUS_IS_OK(result))
898                 goto done;
899
900         got_connect_pol = True;
901
902         /* Get domain policy handle */
903
904         result = rpccli_samr_OpenDomain(cli, mem_ctx,
905                                         &connect_pol,
906                                         access_mask,
907                                         &domain_sid,
908                                         &domain_pol);
909
910         if (!NT_STATUS_IS_OK(result))
911                 goto done;
912
913         got_domain_pol = True;
914
915         /* Enumerate domain groups */
916
917         start_idx = 0;
918         size = 0xffff;
919
920         do {
921                 result = rpccli_samr_EnumDomainGroups(cli, mem_ctx,
922                                                       &domain_pol,
923                                                       &start_idx,
924                                                       &dom_groups,
925                                                       size,
926                                                       &num_dom_groups);
927                 if (NT_STATUS_IS_OK(result) ||
928                     NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
929
930                         for (i = 0; i < num_dom_groups; i++)
931                                 printf("group:[%s] rid:[0x%x]\n",
932                                        dom_groups->entries[i].name.string,
933                                        dom_groups->entries[i].idx);
934                 }
935
936         } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
937
938  done:
939         if (got_domain_pol)
940                 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
941
942         if (got_connect_pol)
943                 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
944
945         return result;
946 }
947
948 /* Enumerate alias groups */
949
950 static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli,
951                                          TALLOC_CTX *mem_ctx,
952                                          int argc, const char **argv)
953 {
954         POLICY_HND connect_pol, domain_pol;
955         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
956         uint32 start_idx, size, num_als_groups, i;
957         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
958         struct samr_SamArray *als_groups = NULL;
959         bool got_connect_pol = False, got_domain_pol = False;
960
961         if ((argc < 2) || (argc > 3)) {
962                 printf("Usage: %s builtin|domain [access mask]\n", argv[0]);
963                 return NT_STATUS_OK;
964         }
965
966         if (argc > 2)
967                 sscanf(argv[2], "%x", &access_mask);
968
969         /* Get sam policy handle */
970
971         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
972                                    &connect_pol);
973
974         if (!NT_STATUS_IS_OK(result))
975                 goto done;
976
977         got_connect_pol = True;
978
979         /* Get domain policy handle */
980
981         if (StrCaseCmp(argv[1], "domain")==0)
982                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
983                                                 &connect_pol,
984                                                 access_mask,
985                                                 &domain_sid,
986                                                 &domain_pol);
987         else if (StrCaseCmp(argv[1], "builtin")==0)
988                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
989                                                 &connect_pol,
990                                                 access_mask,
991                                                 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
992                                                 &domain_pol);
993         else
994                 return NT_STATUS_OK;
995
996         if (!NT_STATUS_IS_OK(result))
997                 goto done;
998
999         got_domain_pol = True;
1000
1001         /* Enumerate alias groups */
1002
1003         start_idx = 0;
1004         size = 0xffff;          /* Number of groups to retrieve */
1005
1006         do {
1007                 result = rpccli_samr_EnumDomainAliases(cli, mem_ctx,
1008                                                        &domain_pol,
1009                                                        &start_idx,
1010                                                        &als_groups,
1011                                                        size,
1012                                                        &num_als_groups);
1013
1014                 if (NT_STATUS_IS_OK(result) ||
1015                     NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1016
1017                         for (i = 0; i < num_als_groups; i++)
1018                                 printf("group:[%s] rid:[0x%x]\n",
1019                                        als_groups->entries[i].name.string,
1020                                        als_groups->entries[i].idx);
1021                 }
1022         } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1023
1024  done:
1025         if (got_domain_pol)
1026                 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1027
1028         if (got_connect_pol)
1029                 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1030
1031         return result;
1032 }
1033
1034 /* Enumerate domains */
1035
1036 static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli,
1037                                       TALLOC_CTX *mem_ctx,
1038                                       int argc, const char **argv)
1039 {
1040         POLICY_HND connect_pol;
1041         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1042         uint32 start_idx, size, num_entries, i;
1043         uint32 access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1044         bool got_connect_pol = false;
1045         struct samr_SamArray *sam = NULL;
1046
1047         if ((argc < 1) || (argc > 2)) {
1048                 printf("Usage: %s [access mask]\n", argv[0]);
1049                 return NT_STATUS_OK;
1050         }
1051
1052         if (argc > 2) {
1053                 sscanf(argv[2], "%x", &access_mask);
1054         }
1055
1056         /* Get sam policy handle */
1057
1058         result = try_samr_connects(cli, mem_ctx,
1059                                    access_mask,
1060                                    &connect_pol);
1061
1062         if (!NT_STATUS_IS_OK(result)) {
1063                 goto done;
1064         }
1065
1066         got_connect_pol = true;
1067
1068         /* Enumerate alias groups */
1069
1070         start_idx = 0;
1071         size = 0xffff;
1072
1073         do {
1074                 result = rpccli_samr_EnumDomains(cli, mem_ctx,
1075                                                  &connect_pol,
1076                                                  &start_idx,
1077                                                  &sam,
1078                                                  size,
1079                                                  &num_entries);
1080
1081                 if (NT_STATUS_IS_OK(result) ||
1082                     NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1083
1084                         for (i = 0; i < num_entries; i++)
1085                                 printf("name:[%s] idx:[0x%x]\n",
1086                                        sam->entries[i].name.string,
1087                                        sam->entries[i].idx);
1088                 }
1089         } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1090
1091  done:
1092         if (got_connect_pol) {
1093                 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1094         }
1095
1096         return result;
1097 }
1098
1099
1100 /* Query alias membership */
1101
1102 static NTSTATUS cmd_samr_query_aliasmem(struct rpc_pipe_client *cli,
1103                                         TALLOC_CTX *mem_ctx,
1104                                         int argc, const char **argv)
1105 {
1106         POLICY_HND connect_pol, domain_pol, alias_pol;
1107         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1108         uint32 alias_rid, i;
1109         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1110         struct lsa_SidArray sid_array;
1111
1112         if ((argc < 3) || (argc > 4)) {
1113                 printf("Usage: %s builtin|domain rid [access mask]\n", argv[0]);
1114                 return NT_STATUS_OK;
1115         }
1116
1117         sscanf(argv[2], "%i", &alias_rid);
1118
1119         if (argc > 3)
1120                 sscanf(argv[3], "%x", &access_mask);
1121
1122         /* Open SAMR handle */
1123
1124         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1125                                    &connect_pol);
1126
1127         if (!NT_STATUS_IS_OK(result))
1128                 goto done;
1129
1130         /* Open handle on domain */
1131
1132         if (StrCaseCmp(argv[1], "domain")==0)
1133                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1134                                                 &connect_pol,
1135                                                 MAXIMUM_ALLOWED_ACCESS,
1136                                                 &domain_sid,
1137                                                 &domain_pol);
1138         else if (StrCaseCmp(argv[1], "builtin")==0)
1139                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1140                                                 &connect_pol,
1141                                                 MAXIMUM_ALLOWED_ACCESS,
1142                                                 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1143                                                 &domain_pol);
1144         else
1145                 return NT_STATUS_OK;
1146
1147         if (!NT_STATUS_IS_OK(result))
1148                 goto done;
1149
1150         /* Open handle on alias */
1151
1152         result = rpccli_samr_OpenAlias(cli, mem_ctx,
1153                                        &domain_pol,
1154                                        access_mask,
1155                                        alias_rid,
1156                                        &alias_pol);
1157         if (!NT_STATUS_IS_OK(result))
1158                 goto done;
1159
1160         result = rpccli_samr_GetMembersInAlias(cli, mem_ctx,
1161                                                &alias_pol,
1162                                                &sid_array);
1163
1164         if (!NT_STATUS_IS_OK(result))
1165                 goto done;
1166
1167         for (i = 0; i < sid_array.num_sids; i++) {
1168                 fstring sid_str;
1169
1170                 sid_to_fstring(sid_str, sid_array.sids[i].sid);
1171                 printf("\tsid:[%s]\n", sid_str);
1172         }
1173
1174         rpccli_samr_Close(cli, mem_ctx, &alias_pol);
1175         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1176         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1177  done:
1178         return result;
1179 }
1180
1181 /* Query alias info */
1182
1183 static NTSTATUS cmd_samr_query_aliasinfo(struct rpc_pipe_client *cli,
1184                                          TALLOC_CTX *mem_ctx,
1185                                          int argc, const char **argv)
1186 {
1187         POLICY_HND connect_pol, domain_pol, alias_pol;
1188         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1189         uint32_t alias_rid;
1190         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1191         union samr_AliasInfo *info = NULL;
1192         enum samr_AliasInfoEnum level = ALIASINFOALL;
1193
1194         if ((argc < 3) || (argc > 4)) {
1195                 printf("Usage: %s builtin|domain rid [level] [access mask]\n",
1196                         argv[0]);
1197                 return NT_STATUS_OK;
1198         }
1199
1200         sscanf(argv[2], "%i", &alias_rid);
1201
1202         if (argc > 3) {
1203                 level = atoi(argv[3]);
1204         }
1205
1206         if (argc > 4) {
1207                 sscanf(argv[4], "%x", &access_mask);
1208         }
1209
1210         /* Open SAMR handle */
1211
1212         result = try_samr_connects(cli, mem_ctx,
1213                                    SEC_FLAG_MAXIMUM_ALLOWED,
1214                                    &connect_pol);
1215
1216         if (!NT_STATUS_IS_OK(result)) {
1217                 goto done;
1218         }
1219
1220         /* Open handle on domain */
1221
1222         if (strequal(argv[1], "domain")) {
1223
1224                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1225                                                 &connect_pol,
1226                                                 SEC_FLAG_MAXIMUM_ALLOWED,
1227                                                 &domain_sid,
1228                                                 &domain_pol);
1229
1230         } else if (strequal(argv[1], "builtin")) {
1231
1232                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1233                                                 &connect_pol,
1234                                                 SEC_FLAG_MAXIMUM_ALLOWED,
1235                                                 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1236                                                 &domain_pol);
1237
1238         } else {
1239                 return NT_STATUS_OK;
1240         }
1241
1242         if (!NT_STATUS_IS_OK(result)) {
1243                 goto done;
1244         }
1245
1246         /* Open handle on alias */
1247
1248         result = rpccli_samr_OpenAlias(cli, mem_ctx,
1249                                        &domain_pol,
1250                                        access_mask,
1251                                        alias_rid,
1252                                        &alias_pol);
1253         if (!NT_STATUS_IS_OK(result)) {
1254                 goto done;
1255         }
1256
1257         result = rpccli_samr_QueryAliasInfo(cli, mem_ctx,
1258                                             &alias_pol,
1259                                             level,
1260                                             &info);
1261
1262         if (!NT_STATUS_IS_OK(result)) {
1263                 goto done;
1264         }
1265
1266         switch (level) {
1267                 case ALIASINFOALL:
1268                         printf("Name: %s\n", info->all.name.string);
1269                         printf("Description: %s\n", info->all.description.string);
1270                         printf("Num Members: %d\n", info->all.num_members);
1271                         break;
1272                 case ALIASINFONAME:
1273                         printf("Name: %s\n", info->name.string);
1274                         break;
1275                 case ALIASINFODESCRIPTION:
1276                         printf("Description: %s\n", info->description.string);
1277                         break;
1278                 default:
1279                         break;
1280         }
1281
1282         rpccli_samr_Close(cli, mem_ctx, &alias_pol);
1283         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1284         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1285  done:
1286         return result;
1287 }
1288
1289
1290 /* Query delete an alias membership */
1291
1292 static NTSTATUS cmd_samr_delete_alias(struct rpc_pipe_client *cli,
1293                                       TALLOC_CTX *mem_ctx,
1294                                       int argc, const char **argv)
1295 {
1296         POLICY_HND connect_pol, domain_pol, alias_pol;
1297         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1298         uint32 alias_rid;
1299         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1300
1301         if (argc != 3) {
1302                 printf("Usage: %s builtin|domain [rid|name]\n", argv[0]);
1303                 return NT_STATUS_OK;
1304         }
1305
1306         alias_rid = strtoul(argv[2], NULL, 10);
1307
1308         /* Open SAMR handle */
1309
1310         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1311                                    &connect_pol);
1312
1313         if (!NT_STATUS_IS_OK(result))
1314                 goto done;
1315
1316         /* Open handle on domain */
1317
1318         if (StrCaseCmp(argv[1], "domain")==0)
1319                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1320                                                 &connect_pol,
1321                                                 MAXIMUM_ALLOWED_ACCESS,
1322                                                 &domain_sid,
1323                                                 &domain_pol);
1324         else if (StrCaseCmp(argv[1], "builtin")==0)
1325                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1326                                                 &connect_pol,
1327                                                 MAXIMUM_ALLOWED_ACCESS,
1328                                                 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1329                                                 &domain_pol);
1330         else
1331                 return NT_STATUS_INVALID_PARAMETER;
1332
1333         if (!NT_STATUS_IS_OK(result))
1334                 goto done;
1335
1336         /* Open handle on alias */
1337
1338         result = rpccli_samr_OpenAlias(cli, mem_ctx,
1339                                        &domain_pol,
1340                                        access_mask,
1341                                        alias_rid,
1342                                        &alias_pol);
1343         if (!NT_STATUS_IS_OK(result) && (alias_rid == 0)) {
1344                 /* Probably this was a user name, try lookupnames */
1345                 struct samr_Ids rids, types;
1346                 struct lsa_String lsa_acct_name;
1347
1348                 init_lsa_String(&lsa_acct_name, argv[2]);
1349
1350                 result = rpccli_samr_LookupNames(cli, mem_ctx,
1351                                                  &domain_pol,
1352                                                  1,
1353                                                  &lsa_acct_name,
1354                                                  &rids,
1355                                                  &types);
1356
1357                 if (NT_STATUS_IS_OK(result)) {
1358                         result = rpccli_samr_OpenAlias(cli, mem_ctx,
1359                                                        &domain_pol,
1360                                                        access_mask,
1361                                                        rids.ids[0],
1362                                                        &alias_pol);
1363                 }
1364         }
1365
1366         result = rpccli_samr_DeleteDomAlias(cli, mem_ctx,
1367                                             &alias_pol);
1368
1369         if (!NT_STATUS_IS_OK(result))
1370                 goto done;
1371
1372         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1373         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1374  done:
1375         return result;
1376 }
1377
1378 /* Query display info */
1379
1380 static NTSTATUS cmd_samr_query_dispinfo(struct rpc_pipe_client *cli,
1381                                         TALLOC_CTX *mem_ctx,
1382                                         int argc, const char **argv)
1383 {
1384         POLICY_HND connect_pol, domain_pol;
1385         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1386         uint32 start_idx=0, max_entries=250, max_size = 0xffff, num_entries = 0, i;
1387         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1388         uint32 info_level = 1;
1389         union samr_DispInfo info;
1390         int loop_count = 0;
1391         bool got_params = False; /* Use get_query_dispinfo_params() or not? */
1392         uint32_t total_size, returned_size;
1393
1394         if (argc > 6) {
1395                 printf("Usage: %s [info level] [start index] [max entries] [max size] [access mask]\n", argv[0]);
1396                 return NT_STATUS_OK;
1397         }
1398
1399         if (argc >= 2)
1400                 sscanf(argv[1], "%i", &info_level);
1401
1402         if (argc >= 3)
1403                 sscanf(argv[2], "%i", &start_idx);
1404
1405         if (argc >= 4) {
1406                 sscanf(argv[3], "%i", &max_entries);
1407                 got_params = True;
1408         }
1409
1410         if (argc >= 5) {
1411                 sscanf(argv[4], "%i", &max_size);
1412                 got_params = True;
1413         }
1414
1415         if (argc >= 6)
1416                 sscanf(argv[5], "%x", &access_mask);
1417
1418         /* Get sam policy handle */
1419
1420         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1421                                    &connect_pol);
1422
1423         if (!NT_STATUS_IS_OK(result))
1424                 goto done;
1425
1426         /* Get domain policy handle */
1427
1428         result = rpccli_samr_OpenDomain(cli, mem_ctx,
1429                                         &connect_pol,
1430                                         access_mask,
1431                                         &domain_sid,
1432                                         &domain_pol);
1433
1434         if (!NT_STATUS_IS_OK(result))
1435                 goto done;
1436
1437         /* Query display info */
1438
1439         do {
1440
1441                 if (!got_params)
1442                         get_query_dispinfo_params(
1443                                 loop_count, &max_entries, &max_size);
1444
1445                 result = rpccli_samr_QueryDisplayInfo(cli, mem_ctx,
1446                                                       &domain_pol,
1447                                                       info_level,
1448                                                       start_idx,
1449                                                       max_entries,
1450                                                       max_size,
1451                                                       &total_size,
1452                                                       &returned_size,
1453                                                       &info);
1454
1455                 loop_count++;
1456
1457                 switch (info_level) {
1458                         case 1:
1459                                 num_entries = info.info1.count;
1460                                 break;
1461                         case 2:
1462                                 num_entries = info.info2.count;
1463                                 break;
1464                         case 3:
1465                                 num_entries = info.info3.count;
1466                                 break;
1467                         case 4:
1468                                 num_entries = info.info4.count;
1469                                 break;
1470                         case 5:
1471                                 num_entries = info.info5.count;
1472                                 break;
1473                         default:
1474                                 break;
1475                 }
1476
1477                 start_idx += num_entries;
1478
1479                 if (NT_STATUS_IS_ERR(result))
1480                         break;
1481
1482                 if (num_entries == 0)
1483                         break;
1484
1485                 for (i = 0; i < num_entries; i++) {
1486                         switch (info_level) {
1487                         case 1:
1488                                 display_sam_info_1(&info.info1.entries[i]);
1489                                 break;
1490                         case 2:
1491                                 display_sam_info_2(&info.info2.entries[i]);
1492                                 break;
1493                         case 3:
1494                                 display_sam_info_3(&info.info3.entries[i]);
1495                                 break;
1496                         case 4:
1497                                 display_sam_info_4(&info.info4.entries[i]);
1498                                 break;
1499                         case 5:
1500                                 display_sam_info_5(&info.info5.entries[i]);
1501                                 break;
1502                         }
1503                 }
1504         } while ( NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1505
1506         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1507         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1508  done:
1509         return result;
1510 }
1511
1512 /* Query domain info */
1513
1514 static NTSTATUS cmd_samr_query_dominfo(struct rpc_pipe_client *cli,
1515                                        TALLOC_CTX *mem_ctx,
1516                                        int argc, const char **argv)
1517 {
1518         POLICY_HND connect_pol, domain_pol;
1519         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1520         uint32 switch_level = 2;
1521         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1522         union samr_DomainInfo *info = NULL;
1523
1524         if (argc > 3) {
1525                 printf("Usage: %s [info level] [access mask]\n", argv[0]);
1526                 return NT_STATUS_OK;
1527         }
1528
1529         if (argc > 1)
1530                 sscanf(argv[1], "%i", &switch_level);
1531
1532         if (argc > 2)
1533                 sscanf(argv[2], "%x", &access_mask);
1534
1535         /* Get sam policy handle */
1536
1537         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1538                                    &connect_pol);
1539
1540         if (!NT_STATUS_IS_OK(result))
1541                 goto done;
1542
1543         /* Get domain policy handle */
1544
1545         result = rpccli_samr_OpenDomain(cli, mem_ctx,
1546                                         &connect_pol,
1547                                         access_mask,
1548                                         &domain_sid,
1549                                         &domain_pol);
1550
1551         if (!NT_STATUS_IS_OK(result))
1552                 goto done;
1553
1554         /* Query domain info */
1555
1556         result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1557                                              &domain_pol,
1558                                              switch_level,
1559                                              &info);
1560
1561         if (!NT_STATUS_IS_OK(result))
1562                 goto done;
1563
1564         /* Display domain info */
1565
1566         switch (switch_level) {
1567         case 1:
1568                 display_sam_dom_info_1(&info->info1);
1569                 break;
1570         case 2:
1571                 display_sam_dom_info_2(&info->info2);
1572                 break;
1573         case 3:
1574                 display_sam_dom_info_3(&info->info3);
1575                 break;
1576         case 4:
1577                 display_sam_dom_info_4(&info->info4);
1578                 break;
1579         case 5:
1580                 display_sam_dom_info_5(&info->info5);
1581                 break;
1582         case 6:
1583                 display_sam_dom_info_6(&info->info6);
1584                 break;
1585         case 7:
1586                 display_sam_dom_info_7(&info->info7);
1587                 break;
1588         case 8:
1589                 display_sam_dom_info_8(&info->info8);
1590                 break;
1591         case 9:
1592                 display_sam_dom_info_9(&info->info9);
1593                 break;
1594         case 12:
1595                 display_sam_dom_info_12(&info->info12);
1596                 break;
1597         case 13:
1598                 display_sam_dom_info_13(&info->info13);
1599                 break;
1600
1601         default:
1602                 printf("cannot display domain info for switch value %d\n",
1603                        switch_level);
1604                 break;
1605         }
1606
1607  done:
1608
1609         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1610         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1611         return result;
1612 }
1613
1614 /* Create domain user */
1615
1616 static NTSTATUS cmd_samr_create_dom_user(struct rpc_pipe_client *cli,
1617                                          TALLOC_CTX *mem_ctx,
1618                                          int argc, const char **argv)
1619 {
1620         POLICY_HND connect_pol, domain_pol, user_pol;
1621         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1622         struct lsa_String acct_name;
1623         uint32 acb_info;
1624         uint32 acct_flags, user_rid;
1625         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1626         uint32_t access_granted = 0;
1627
1628         if ((argc < 2) || (argc > 3)) {
1629                 printf("Usage: %s username [access mask]\n", argv[0]);
1630                 return NT_STATUS_OK;
1631         }
1632
1633         init_lsa_String(&acct_name, argv[1]);
1634
1635         if (argc > 2)
1636                 sscanf(argv[2], "%x", &access_mask);
1637
1638         /* Get sam policy handle */
1639
1640         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1641                                    &connect_pol);
1642
1643         if (!NT_STATUS_IS_OK(result))
1644                 goto done;
1645
1646         /* Get domain policy handle */
1647
1648         result = rpccli_samr_OpenDomain(cli, mem_ctx,
1649                                         &connect_pol,
1650                                         access_mask,
1651                                         &domain_sid,
1652                                         &domain_pol);
1653
1654         if (!NT_STATUS_IS_OK(result))
1655                 goto done;
1656
1657         /* Create domain user */
1658
1659         acb_info = ACB_NORMAL;
1660         acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
1661                      SEC_STD_WRITE_DAC | SEC_STD_DELETE |
1662                      SAMR_USER_ACCESS_SET_PASSWORD |
1663                      SAMR_USER_ACCESS_GET_ATTRIBUTES |
1664                      SAMR_USER_ACCESS_SET_ATTRIBUTES;
1665
1666         result = rpccli_samr_CreateUser2(cli, mem_ctx,
1667                                          &domain_pol,
1668                                          &acct_name,
1669                                          acb_info,
1670                                          acct_flags,
1671                                          &user_pol,
1672                                          &access_granted,
1673                                          &user_rid);
1674
1675         if (!NT_STATUS_IS_OK(result))
1676                 goto done;
1677
1678         result = rpccli_samr_Close(cli, mem_ctx, &user_pol);
1679         if (!NT_STATUS_IS_OK(result)) goto done;
1680
1681         result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1682         if (!NT_STATUS_IS_OK(result)) goto done;
1683
1684         result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1685         if (!NT_STATUS_IS_OK(result)) goto done;
1686
1687  done:
1688         return result;
1689 }
1690
1691 /* Create domain group */
1692
1693 static NTSTATUS cmd_samr_create_dom_group(struct rpc_pipe_client *cli,
1694                                           TALLOC_CTX *mem_ctx,
1695                                           int argc, const char **argv)
1696 {
1697         POLICY_HND connect_pol, domain_pol, group_pol;
1698         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1699         struct lsa_String grp_name;
1700         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1701         uint32_t rid = 0;
1702
1703         if ((argc < 2) || (argc > 3)) {
1704                 printf("Usage: %s groupname [access mask]\n", argv[0]);
1705                 return NT_STATUS_OK;
1706         }
1707
1708         init_lsa_String(&grp_name, argv[1]);
1709
1710         if (argc > 2)
1711                 sscanf(argv[2], "%x", &access_mask);
1712
1713         /* Get sam policy handle */
1714
1715         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1716                                    &connect_pol);
1717
1718         if (!NT_STATUS_IS_OK(result))
1719                 goto done;
1720
1721         /* Get domain policy handle */
1722
1723         result = rpccli_samr_OpenDomain(cli, mem_ctx,
1724                                         &connect_pol,
1725                                         access_mask,
1726                                         &domain_sid,
1727                                         &domain_pol);
1728
1729         if (!NT_STATUS_IS_OK(result))
1730                 goto done;
1731
1732         /* Create domain user */
1733         result = rpccli_samr_CreateDomainGroup(cli, mem_ctx,
1734                                                &domain_pol,
1735                                                &grp_name,
1736                                                MAXIMUM_ALLOWED_ACCESS,
1737                                                &group_pol,
1738                                                &rid);
1739
1740         if (!NT_STATUS_IS_OK(result))
1741                 goto done;
1742
1743         result = rpccli_samr_Close(cli, mem_ctx, &group_pol);
1744         if (!NT_STATUS_IS_OK(result)) goto done;
1745
1746         result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1747         if (!NT_STATUS_IS_OK(result)) goto done;
1748
1749         result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1750         if (!NT_STATUS_IS_OK(result)) goto done;
1751
1752  done:
1753         return result;
1754 }
1755
1756 /* Create domain alias */
1757
1758 static NTSTATUS cmd_samr_create_dom_alias(struct rpc_pipe_client *cli,
1759                                           TALLOC_CTX *mem_ctx,
1760                                           int argc, const char **argv)
1761 {
1762         POLICY_HND connect_pol, domain_pol, alias_pol;
1763         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1764         struct lsa_String alias_name;
1765         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1766         uint32_t rid = 0;
1767
1768         if ((argc < 2) || (argc > 3)) {
1769                 printf("Usage: %s aliasname [access mask]\n", argv[0]);
1770                 return NT_STATUS_OK;
1771         }
1772
1773         init_lsa_String(&alias_name, argv[1]);
1774
1775         if (argc > 2)
1776                 sscanf(argv[2], "%x", &access_mask);
1777
1778         /* Get sam policy handle */
1779
1780         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1781                                    &connect_pol);
1782
1783         if (!NT_STATUS_IS_OK(result))
1784                 goto done;
1785
1786         /* Get domain policy handle */
1787
1788         result = rpccli_samr_OpenDomain(cli, mem_ctx,
1789                                         &connect_pol,
1790                                         access_mask,
1791                                         &domain_sid,
1792                                         &domain_pol);
1793
1794         if (!NT_STATUS_IS_OK(result))
1795                 goto done;
1796
1797         /* Create domain user */
1798
1799         result = rpccli_samr_CreateDomAlias(cli, mem_ctx,
1800                                             &domain_pol,
1801                                             &alias_name,
1802                                             MAXIMUM_ALLOWED_ACCESS,
1803                                             &alias_pol,
1804                                             &rid);
1805
1806         if (!NT_STATUS_IS_OK(result))
1807                 goto done;
1808
1809         result = rpccli_samr_Close(cli, mem_ctx, &alias_pol);
1810         if (!NT_STATUS_IS_OK(result)) goto done;
1811
1812         result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1813         if (!NT_STATUS_IS_OK(result)) goto done;
1814
1815         result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1816         if (!NT_STATUS_IS_OK(result)) goto done;
1817
1818  done:
1819         return result;
1820 }
1821
1822 /* Lookup sam names */
1823
1824 static NTSTATUS cmd_samr_lookup_names(struct rpc_pipe_client *cli,
1825                                       TALLOC_CTX *mem_ctx,
1826                                       int argc, const char **argv)
1827 {
1828         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1829         POLICY_HND connect_pol, domain_pol;
1830         uint32 num_names;
1831         struct samr_Ids rids, name_types;
1832         int i;
1833         struct lsa_String *names = NULL;;
1834
1835         if (argc < 3) {
1836                 printf("Usage: %s  domain|builtin name1 [name2 [name3] [...]]\n", argv[0]);
1837                 printf("check on the domain SID: S-1-5-21-x-y-z\n");
1838                 printf("or check on the builtin SID: S-1-5-32\n");
1839                 return NT_STATUS_OK;
1840         }
1841
1842         /* Get sam policy and domain handles */
1843
1844         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1845                                    &connect_pol);
1846
1847         if (!NT_STATUS_IS_OK(result))
1848                 goto done;
1849
1850         if (StrCaseCmp(argv[1], "domain")==0)
1851                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1852                                                 &connect_pol,
1853                                                 MAXIMUM_ALLOWED_ACCESS,
1854                                                 &domain_sid,
1855                                                 &domain_pol);
1856         else if (StrCaseCmp(argv[1], "builtin")==0)
1857                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1858                                                 &connect_pol,
1859                                                 MAXIMUM_ALLOWED_ACCESS,
1860                                                 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1861                                                 &domain_pol);
1862         else
1863                 return NT_STATUS_OK;
1864
1865         if (!NT_STATUS_IS_OK(result))
1866                 goto done;
1867
1868         /* Look up names */
1869
1870         num_names = argc - 2;
1871
1872         if ((names = TALLOC_ARRAY(mem_ctx, struct lsa_String, num_names)) == NULL) {
1873                 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1874                 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1875                 result = NT_STATUS_NO_MEMORY;
1876                 goto done;
1877         }
1878
1879         for (i = 0; i < num_names; i++) {
1880                 init_lsa_String(&names[i], argv[i + 2]);
1881         }
1882
1883         result = rpccli_samr_LookupNames(cli, mem_ctx,
1884                                          &domain_pol,
1885                                          num_names,
1886                                          names,
1887                                          &rids,
1888                                          &name_types);
1889
1890         if (!NT_STATUS_IS_OK(result))
1891                 goto done;
1892
1893         /* Display results */
1894
1895         for (i = 0; i < num_names; i++)
1896                 printf("name %s: 0x%x (%d)\n", names[i].string, rids.ids[i],
1897                        name_types.ids[i]);
1898
1899         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1900         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1901  done:
1902         return result;
1903 }
1904
1905 /* Lookup sam rids */
1906
1907 static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli,
1908                                      TALLOC_CTX *mem_ctx,
1909                                      int argc, const char **argv)
1910 {
1911         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1912         POLICY_HND connect_pol, domain_pol;
1913         uint32_t num_rids, *rids;
1914         struct lsa_Strings names;
1915         struct samr_Ids types;
1916
1917         int i;
1918
1919         if (argc < 3) {
1920                 printf("Usage: %s domain|builtin rid1 [rid2 [rid3] [...]]\n", argv[0]);
1921                 return NT_STATUS_OK;
1922         }
1923
1924         /* Get sam policy and domain handles */
1925
1926         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1927                                    &connect_pol);
1928
1929         if (!NT_STATUS_IS_OK(result))
1930                 goto done;
1931
1932         if (StrCaseCmp(argv[1], "domain")==0)
1933                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1934                                                 &connect_pol,
1935                                                 MAXIMUM_ALLOWED_ACCESS,
1936                                                 &domain_sid,
1937                                                 &domain_pol);
1938         else if (StrCaseCmp(argv[1], "builtin")==0)
1939                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
1940                                                 &connect_pol,
1941                                                 MAXIMUM_ALLOWED_ACCESS,
1942                                                 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
1943                                                 &domain_pol);
1944         else
1945                 return NT_STATUS_OK;
1946
1947         if (!NT_STATUS_IS_OK(result))
1948                 goto done;
1949
1950         /* Look up rids */
1951
1952         num_rids = argc - 2;
1953
1954         if ((rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids)) == NULL) {
1955                 rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1956                 rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1957                 result = NT_STATUS_NO_MEMORY;
1958                 goto done;
1959         }
1960
1961         for (i = 0; i < argc - 2; i++)
1962                 sscanf(argv[i + 2], "%i", &rids[i]);
1963
1964         result = rpccli_samr_LookupRids(cli, mem_ctx,
1965                                         &domain_pol,
1966                                         num_rids,
1967                                         rids,
1968                                         &names,
1969                                         &types);
1970
1971         if (!NT_STATUS_IS_OK(result) &&
1972             !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
1973                 goto done;
1974
1975         /* Display results */
1976
1977         for (i = 0; i < num_rids; i++) {
1978                 printf("rid 0x%x: %s (%d)\n",
1979                         rids[i], names.names[i].string, types.ids[i]);
1980         }
1981
1982         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
1983         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
1984  done:
1985         return result;
1986 }
1987
1988 /* Delete domain group */
1989
1990 static NTSTATUS cmd_samr_delete_dom_group(struct rpc_pipe_client *cli,
1991                                          TALLOC_CTX *mem_ctx,
1992                                          int argc, const char **argv)
1993 {
1994         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1995         POLICY_HND connect_pol, domain_pol, group_pol;
1996         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1997
1998         if ((argc < 2) || (argc > 3)) {
1999                 printf("Usage: %s groupname\n", argv[0]);
2000                 return NT_STATUS_OK;
2001         }
2002
2003         if (argc > 2)
2004                 sscanf(argv[2], "%x", &access_mask);
2005
2006         /* Get sam policy and domain handles */
2007
2008         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2009                                    &connect_pol);
2010
2011         if (!NT_STATUS_IS_OK(result))
2012                 goto done;
2013
2014         result = rpccli_samr_OpenDomain(cli, mem_ctx,
2015                                         &connect_pol,
2016                                         MAXIMUM_ALLOWED_ACCESS,
2017                                         &domain_sid,
2018                                         &domain_pol);
2019
2020         if (!NT_STATUS_IS_OK(result))
2021                 goto done;
2022
2023         /* Get handle on group */
2024
2025         {
2026                 struct samr_Ids group_rids, name_types;
2027                 struct lsa_String lsa_acct_name;
2028
2029                 init_lsa_String(&lsa_acct_name, argv[1]);
2030
2031                 result = rpccli_samr_LookupNames(cli, mem_ctx,
2032                                                  &domain_pol,
2033                                                  1,
2034                                                  &lsa_acct_name,
2035                                                  &group_rids,
2036                                                  &name_types);
2037                 if (!NT_STATUS_IS_OK(result))
2038                         goto done;
2039
2040                 result = rpccli_samr_OpenGroup(cli, mem_ctx,
2041                                                &domain_pol,
2042                                                access_mask,
2043                                                group_rids.ids[0],
2044                                                &group_pol);
2045
2046                 if (!NT_STATUS_IS_OK(result))
2047                         goto done;
2048         }
2049
2050         /* Delete group */
2051
2052         result = rpccli_samr_DeleteDomainGroup(cli, mem_ctx,
2053                                                &group_pol);
2054
2055         if (!NT_STATUS_IS_OK(result))
2056                 goto done;
2057
2058         /* Display results */
2059
2060         rpccli_samr_Close(cli, mem_ctx, &group_pol);
2061         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2062         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2063
2064  done:
2065         return result;
2066 }
2067
2068 /* Delete domain user */
2069
2070 static NTSTATUS cmd_samr_delete_dom_user(struct rpc_pipe_client *cli,
2071                                          TALLOC_CTX *mem_ctx,
2072                                          int argc, const char **argv)
2073 {
2074         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2075         POLICY_HND connect_pol, domain_pol, user_pol;
2076         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2077
2078         if ((argc < 2) || (argc > 3)) {
2079                 printf("Usage: %s username\n", argv[0]);
2080                 return NT_STATUS_OK;
2081         }
2082
2083         if (argc > 2)
2084                 sscanf(argv[2], "%x", &access_mask);
2085
2086         /* Get sam policy and domain handles */
2087
2088         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2089                                    &connect_pol);
2090
2091         if (!NT_STATUS_IS_OK(result))
2092                 goto done;
2093
2094         result = rpccli_samr_OpenDomain(cli, mem_ctx,
2095                                         &connect_pol,
2096                                         MAXIMUM_ALLOWED_ACCESS,
2097                                         &domain_sid,
2098                                         &domain_pol);
2099
2100         if (!NT_STATUS_IS_OK(result))
2101                 goto done;
2102
2103         /* Get handle on user */
2104
2105         {
2106                 struct samr_Ids user_rids, name_types;
2107                 struct lsa_String lsa_acct_name;
2108
2109                 init_lsa_String(&lsa_acct_name, argv[1]);
2110
2111                 result = rpccli_samr_LookupNames(cli, mem_ctx,
2112                                                  &domain_pol,
2113                                                  1,
2114                                                  &lsa_acct_name,
2115                                                  &user_rids,
2116                                                  &name_types);
2117
2118                 if (!NT_STATUS_IS_OK(result))
2119                         goto done;
2120
2121                 result = rpccli_samr_OpenUser(cli, mem_ctx,
2122                                               &domain_pol,
2123                                               access_mask,
2124                                               user_rids.ids[0],
2125                                               &user_pol);
2126
2127                 if (!NT_STATUS_IS_OK(result))
2128                         goto done;
2129         }
2130
2131         /* Delete user */
2132
2133         result = rpccli_samr_DeleteUser(cli, mem_ctx,
2134                                         &user_pol);
2135
2136         if (!NT_STATUS_IS_OK(result))
2137                 goto done;
2138
2139         /* Display results */
2140
2141         rpccli_samr_Close(cli, mem_ctx, &user_pol);
2142         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2143         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2144
2145  done:
2146         return result;
2147 }
2148
2149 /**********************************************************************
2150  * Query user security object
2151  */
2152 static NTSTATUS cmd_samr_query_sec_obj(struct rpc_pipe_client *cli,
2153                                     TALLOC_CTX *mem_ctx,
2154                                     int argc, const char **argv)
2155 {
2156         POLICY_HND connect_pol, domain_pol, user_pol, *pol;
2157         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2158         uint32 sec_info = DACL_SECURITY_INFORMATION;
2159         fstring server;
2160         uint32 user_rid = 0;
2161         TALLOC_CTX *ctx = NULL;
2162         SEC_DESC_BUF *sec_desc_buf=NULL;
2163         bool domain = False;
2164
2165         ctx=talloc_init("cmd_samr_query_sec_obj");
2166
2167         if ((argc < 1) || (argc > 3)) {
2168                 printf("Usage: %s [rid|-d] [sec_info]\n", argv[0]);
2169                 printf("\tSpecify rid for security on user, -d for security on domain\n");
2170                 talloc_destroy(ctx);
2171                 return NT_STATUS_OK;
2172         }
2173
2174         if (argc > 1) {
2175                 if (strcmp(argv[1], "-d") == 0)
2176                         domain = True;
2177                 else
2178                         sscanf(argv[1], "%i", &user_rid);
2179         }
2180
2181         if (argc == 3) {
2182                 sec_info = atoi(argv[2]);
2183         }
2184
2185         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
2186         strupper_m(server);
2187         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2188                                    &connect_pol);
2189
2190         if (!NT_STATUS_IS_OK(result))
2191                 goto done;
2192
2193         if (domain || user_rid)
2194                 result = rpccli_samr_OpenDomain(cli, mem_ctx,
2195                                                 &connect_pol,
2196                                                 MAXIMUM_ALLOWED_ACCESS,
2197                                                 &domain_sid,
2198                                                 &domain_pol);
2199
2200         if (!NT_STATUS_IS_OK(result))
2201                 goto done;
2202
2203         if (user_rid)
2204                 result = rpccli_samr_OpenUser(cli, mem_ctx,
2205                                               &domain_pol,
2206                                               MAXIMUM_ALLOWED_ACCESS,
2207                                               user_rid,
2208                                               &user_pol);
2209
2210         if (!NT_STATUS_IS_OK(result))
2211                 goto done;
2212
2213         /* Pick which query pol to use */
2214
2215         pol = &connect_pol;
2216
2217         if (domain)
2218                 pol = &domain_pol;
2219
2220         if (user_rid)
2221                 pol = &user_pol;
2222
2223         /* Query SAM security object */
2224
2225         result = rpccli_samr_QuerySecurity(cli, mem_ctx,
2226                                            pol,
2227                                            sec_info,
2228                                            &sec_desc_buf);
2229
2230         if (!NT_STATUS_IS_OK(result))
2231                 goto done;
2232
2233         display_sec_desc(sec_desc_buf->sd);
2234
2235         rpccli_samr_Close(cli, mem_ctx, &user_pol);
2236         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2237         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2238 done:
2239         talloc_destroy(ctx);
2240         return result;
2241 }
2242
2243 static NTSTATUS cmd_samr_get_usrdom_pwinfo(struct rpc_pipe_client *cli,
2244                                            TALLOC_CTX *mem_ctx,
2245                                            int argc, const char **argv)
2246 {
2247         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2248         POLICY_HND connect_pol, domain_pol, user_pol;
2249         struct samr_PwInfo info;
2250         uint32_t rid;
2251
2252         if (argc != 2) {
2253                 printf("Usage: %s rid\n", argv[0]);
2254                 return NT_STATUS_OK;
2255         }
2256
2257         sscanf(argv[1], "%i", &rid);
2258
2259         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2260                                    &connect_pol);
2261
2262         if (!NT_STATUS_IS_OK(result)) {
2263                 goto done;
2264         }
2265
2266         result = rpccli_samr_OpenDomain(cli, mem_ctx,
2267                                         &connect_pol,
2268                                         MAXIMUM_ALLOWED_ACCESS,
2269                                         &domain_sid,
2270                                         &domain_pol);
2271
2272         if (!NT_STATUS_IS_OK(result)) {
2273                 goto done;
2274         }
2275
2276         result = rpccli_samr_OpenUser(cli, mem_ctx,
2277                                       &domain_pol,
2278                                       MAXIMUM_ALLOWED_ACCESS,
2279                                       rid,
2280                                       &user_pol);
2281
2282         if (!NT_STATUS_IS_OK(result)) {
2283                 goto done;
2284         }
2285
2286         result = rpccli_samr_GetUserPwInfo(cli, mem_ctx, &user_pol, &info);
2287         if (NT_STATUS_IS_OK(result)) {
2288                 printf("min_password_length: %d\n", info.min_password_length);
2289                 printf("%s\n",
2290                         NDR_PRINT_STRUCT_STRING(mem_ctx,
2291                                 samr_PasswordProperties, &info.password_properties));
2292         }
2293
2294  done:
2295         rpccli_samr_Close(cli, mem_ctx, &user_pol);
2296         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2297         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2298
2299         return result;
2300 }
2301
2302 static NTSTATUS cmd_samr_get_dom_pwinfo(struct rpc_pipe_client *cli,
2303                                         TALLOC_CTX *mem_ctx,
2304                                         int argc, const char **argv)
2305 {
2306         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2307         struct lsa_String domain_name;
2308         struct samr_PwInfo info;
2309
2310         if (argc < 1 || argc > 3) {
2311                 printf("Usage: %s <domain>\n", argv[0]);
2312                 return NT_STATUS_OK;
2313         }
2314
2315         init_lsa_String(&domain_name, argv[1]);
2316
2317         result = rpccli_samr_GetDomPwInfo(cli, mem_ctx, &domain_name, &info);
2318
2319         if (NT_STATUS_IS_OK(result)) {
2320                 printf("min_password_length: %d\n", info.min_password_length);
2321                 display_password_properties(info.password_properties);
2322         }
2323
2324         return result;
2325 }
2326
2327 /* Look up domain name */
2328
2329 static NTSTATUS cmd_samr_lookup_domain(struct rpc_pipe_client *cli,
2330                                        TALLOC_CTX *mem_ctx,
2331                                        int argc, const char **argv)
2332 {
2333         POLICY_HND connect_pol, domain_pol;
2334         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2335         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2336         fstring sid_string;
2337         struct lsa_String domain_name;
2338         DOM_SID *sid = NULL;
2339
2340         if (argc != 2) {
2341                 printf("Usage: %s domain_name\n", argv[0]);
2342                 return NT_STATUS_OK;
2343         }
2344
2345         init_lsa_String(&domain_name, argv[1]);
2346
2347         result = try_samr_connects(cli, mem_ctx, access_mask, &connect_pol);
2348
2349         if (!NT_STATUS_IS_OK(result))
2350                 goto done;
2351
2352         result = rpccli_samr_OpenDomain(cli, mem_ctx,
2353                                         &connect_pol,
2354                                         access_mask,
2355                                         &domain_sid,
2356                                         &domain_pol);
2357
2358         if (!NT_STATUS_IS_OK(result))
2359                 goto done;
2360
2361         result = rpccli_samr_LookupDomain(cli, mem_ctx,
2362                                           &connect_pol,
2363                                           &domain_name,
2364                                           &sid);
2365
2366         if (NT_STATUS_IS_OK(result)) {
2367                 sid_to_fstring(sid_string, sid);
2368                 printf("SAMR_LOOKUP_DOMAIN: Domain Name: %s Domain SID: %s\n",
2369                        argv[1], sid_string);
2370         }
2371
2372         rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2373         rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2374 done:
2375         return result;
2376 }
2377
2378 /* Change user password */
2379
2380 static NTSTATUS cmd_samr_chgpasswd2(struct rpc_pipe_client *cli,
2381                                     TALLOC_CTX *mem_ctx,
2382                                     int argc, const char **argv)
2383 {
2384         POLICY_HND connect_pol, domain_pol;
2385         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2386         const char *user, *oldpass, *newpass;
2387         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2388
2389         if (argc < 3) {
2390                 printf("Usage: %s username oldpass newpass\n", argv[0]);
2391                 return NT_STATUS_INVALID_PARAMETER;
2392         }
2393
2394         user = argv[1];
2395         oldpass = argv[2];
2396         newpass = argv[3];
2397
2398         /* Get sam policy handle */
2399
2400         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2401                                    &connect_pol);
2402
2403         if (!NT_STATUS_IS_OK(result))
2404                 goto done;
2405
2406         /* Get domain policy handle */
2407
2408         result = rpccli_samr_OpenDomain(cli, mem_ctx,
2409                                         &connect_pol,
2410                                         access_mask,
2411                                         &domain_sid,
2412                                         &domain_pol);
2413
2414         if (!NT_STATUS_IS_OK(result))
2415                 goto done;
2416
2417         /* Change user password */
2418         result = rpccli_samr_chgpasswd_user(cli, mem_ctx, user, newpass, oldpass);
2419
2420         if (!NT_STATUS_IS_OK(result))
2421                 goto done;
2422
2423         result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2424         if (!NT_STATUS_IS_OK(result)) goto done;
2425
2426         result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2427         if (!NT_STATUS_IS_OK(result)) goto done;
2428
2429  done:
2430         return result;
2431 }
2432
2433
2434 /* Change user password */
2435
2436 static NTSTATUS cmd_samr_chgpasswd3(struct rpc_pipe_client *cli,
2437                                     TALLOC_CTX *mem_ctx,
2438                                     int argc, const char **argv)
2439 {
2440         POLICY_HND connect_pol, domain_pol;
2441         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2442         const char *user, *oldpass, *newpass;
2443         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2444         struct samr_DomInfo1 *info = NULL;
2445         struct samr_ChangeReject *reject = NULL;
2446
2447         if (argc < 3) {
2448                 printf("Usage: %s username oldpass newpass\n", argv[0]);
2449                 return NT_STATUS_INVALID_PARAMETER;
2450         }
2451
2452         user = argv[1];
2453         oldpass = argv[2];
2454         newpass = argv[3];
2455
2456         /* Get sam policy handle */
2457
2458         result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2459                                    &connect_pol);
2460
2461         if (!NT_STATUS_IS_OK(result))
2462                 goto done;
2463
2464         /* Get domain policy handle */
2465
2466         result = rpccli_samr_OpenDomain(cli, mem_ctx,
2467                                         &connect_pol,
2468                                         access_mask,
2469                                         &domain_sid,
2470                                         &domain_pol);
2471
2472         if (!NT_STATUS_IS_OK(result))
2473                 goto done;
2474
2475         /* Change user password */
2476         result = rpccli_samr_chgpasswd3(cli, mem_ctx,
2477                                         user,
2478                                         newpass,
2479                                         oldpass,
2480                                         &info,
2481                                         &reject);
2482
2483         if (NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_RESTRICTION)) {
2484
2485                 display_sam_dom_info_1(info);
2486
2487                 switch (reject->reason) {
2488                         case SAMR_REJECT_TOO_SHORT:
2489                                 d_printf("SAMR_REJECT_TOO_SHORT\n");
2490                                 break;
2491                         case SAMR_REJECT_IN_HISTORY:
2492                                 d_printf("SAMR_REJECT_IN_HISTORY\n");
2493                                 break;
2494                         case SAMR_REJECT_COMPLEXITY:
2495                                 d_printf("SAMR_REJECT_COMPLEXITY\n");
2496                                 break;
2497                         case SAMR_REJECT_OTHER:
2498                                 d_printf("SAMR_REJECT_OTHER\n");
2499                                 break;
2500                         default:
2501                                 d_printf("unknown reject reason: %d\n",
2502                                         reject->reason);
2503                                 break;
2504                 }
2505         }
2506
2507         if (!NT_STATUS_IS_OK(result))
2508                 goto done;
2509
2510         result = rpccli_samr_Close(cli, mem_ctx, &domain_pol);
2511         if (!NT_STATUS_IS_OK(result)) goto done;
2512
2513         result = rpccli_samr_Close(cli, mem_ctx, &connect_pol);
2514         if (!NT_STATUS_IS_OK(result)) goto done;
2515
2516  done:
2517         return result;
2518 }
2519
2520 /* List of commands exported by this module */
2521
2522 struct cmd_set samr_commands[] = {
2523
2524         { "SAMR" },
2525
2526         { "queryuser",  RPC_RTYPE_NTSTATUS, cmd_samr_query_user,                NULL, PI_SAMR, NULL,    "Query user info",         "" },
2527         { "querygroup",         RPC_RTYPE_NTSTATUS, cmd_samr_query_group,               NULL, PI_SAMR, NULL,    "Query group info",        "" },
2528         { "queryusergroups",    RPC_RTYPE_NTSTATUS, cmd_samr_query_usergroups,  NULL, PI_SAMR, NULL,    "Query user groups",       "" },
2529         { "queryuseraliases",   RPC_RTYPE_NTSTATUS, cmd_samr_query_useraliases,         NULL, PI_SAMR, NULL,    "Query user aliases",      "" },
2530         { "querygroupmem",      RPC_RTYPE_NTSTATUS, cmd_samr_query_groupmem,    NULL, PI_SAMR, NULL,    "Query group membership",  "" },
2531         { "queryaliasmem",      RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasmem,    NULL, PI_SAMR, NULL,    "Query alias membership",  "" },
2532         { "queryaliasinfo",     RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasinfo,   NULL, PI_SAMR, NULL,    "Query alias info",       "" },
2533         { "deletealias",        RPC_RTYPE_NTSTATUS, cmd_samr_delete_alias,      NULL, PI_SAMR, NULL,    "Delete an alias",  "" },
2534         { "querydispinfo",      RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo,    NULL, PI_SAMR, NULL,    "Query display info",      "" },
2535         { "querydominfo",       RPC_RTYPE_NTSTATUS, cmd_samr_query_dominfo,     NULL, PI_SAMR, NULL,    "Query domain info",       "" },
2536         { "enumdomusers",       RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_users,       NULL, PI_SAMR, NULL, "Enumerate domain users", "" },
2537         { "enumdomgroups",      RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_groups,       NULL, PI_SAMR, NULL,        "Enumerate domain groups", "" },
2538         { "enumalsgroups",      RPC_RTYPE_NTSTATUS, cmd_samr_enum_als_groups,       NULL, PI_SAMR, NULL,        "Enumerate alias groups",  "" },
2539         { "enumdomains",        RPC_RTYPE_NTSTATUS, cmd_samr_enum_domains,          NULL, PI_SAMR, NULL,        "Enumerate domains",  "" },
2540
2541         { "createdomuser",      RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_user,       NULL, PI_SAMR, NULL,        "Create domain user",      "" },
2542         { "createdomgroup",     RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_group,      NULL, PI_SAMR, NULL,        "Create domain group",     "" },
2543         { "createdomalias",     RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_alias,      NULL, PI_SAMR, NULL,        "Create domain alias",     "" },
2544         { "samlookupnames",     RPC_RTYPE_NTSTATUS, cmd_samr_lookup_names,          NULL, PI_SAMR, NULL,        "Look up names",           "" },
2545         { "samlookuprids",      RPC_RTYPE_NTSTATUS, cmd_samr_lookup_rids,           NULL, PI_SAMR, NULL,        "Look up names",           "" },
2546         { "deletedomgroup",     RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_group,      NULL, PI_SAMR, NULL,        "Delete domain group",     "" },
2547         { "deletedomuser",      RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_user,       NULL, PI_SAMR, NULL,        "Delete domain user",      "" },
2548         { "samquerysecobj",     RPC_RTYPE_NTSTATUS, cmd_samr_query_sec_obj,         NULL, PI_SAMR, NULL, "Query SAMR security object",   "" },
2549         { "getdompwinfo",       RPC_RTYPE_NTSTATUS, cmd_samr_get_dom_pwinfo,        NULL, PI_SAMR, NULL, "Retrieve domain password info", "" },
2550         { "getusrdompwinfo",    RPC_RTYPE_NTSTATUS, cmd_samr_get_usrdom_pwinfo,     NULL, PI_SAMR, NULL, "Retrieve user domain password info", "" },
2551
2552         { "lookupdomain",       RPC_RTYPE_NTSTATUS, cmd_samr_lookup_domain,         NULL, PI_SAMR, NULL, "Lookup Domain Name", "" },
2553         { "chgpasswd2",         RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd2,            NULL, PI_SAMR, NULL, "Change user password", "" },
2554         { "chgpasswd3",         RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd3,            NULL, PI_SAMR, NULL, "Change user password", "" },
2555         { NULL }
2556 };