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