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