s3:libsmb: remove unused change_trust_account_password()
[mat/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 #include "../libcli/auth/libcli_auth.h"
28 #include "../librpc/gen_ndr/ndr_samr.h"
29 #include "../librpc/gen_ndr/ndr_samr_c.h"
30 #include "rpc_client/cli_samr.h"
31 #include "rpc_client/init_samr.h"
32 #include "rpc_client/init_lsa.h"
33 #include "../libcli/security/security.h"
34
35 extern struct dom_sid domain_sid;
36
37 /****************************************************************************
38  display samr_user_info_7 structure
39  ****************************************************************************/
40 static void display_samr_user_info_7(struct samr_UserInfo7 *r)
41 {
42         printf("\tUser Name   :\t%s\n", r->account_name.string);
43 }
44
45 /****************************************************************************
46  display samr_user_info_9 structure
47  ****************************************************************************/
48 static void display_samr_user_info_9(struct samr_UserInfo9 *r)
49 {
50         printf("\tPrimary group RID   :\tox%x\n", r->primary_gid);
51 }
52
53 /****************************************************************************
54  display samr_user_info_16 structure
55  ****************************************************************************/
56 static void display_samr_user_info_16(struct samr_UserInfo16 *r)
57 {
58         printf("\tAcct Flags   :\tox%x\n", r->acct_flags);
59 }
60
61 /****************************************************************************
62  display samr_user_info_20 structure
63  ****************************************************************************/
64 static void display_samr_user_info_20(struct samr_UserInfo20 *r)
65 {
66         printf("\tRemote Dial :\n");
67         dump_data(0, (uint8_t *)r->parameters.array, r->parameters.length*2);
68 }
69
70
71 /****************************************************************************
72  display samr_user_info_21 structure
73  ****************************************************************************/
74 static void display_samr_user_info_21(struct samr_UserInfo21 *r)
75 {
76         printf("\tUser Name   :\t%s\n", r->account_name.string);
77         printf("\tFull Name   :\t%s\n", r->full_name.string);
78         printf("\tHome Drive  :\t%s\n", r->home_directory.string);
79         printf("\tDir Drive   :\t%s\n", r->home_drive.string);
80         printf("\tProfile Path:\t%s\n", r->profile_path.string);
81         printf("\tLogon Script:\t%s\n", r->logon_script.string);
82         printf("\tDescription :\t%s\n", r->description.string);
83         printf("\tWorkstations:\t%s\n", r->workstations.string);
84         printf("\tComment     :\t%s\n", r->comment.string);
85         printf("\tRemote Dial :\n");
86         dump_data(0, (uint8_t *)r->parameters.array, r->parameters.length*2);
87
88         printf("\tLogon Time               :\t%s\n",
89                http_timestring(talloc_tos(), nt_time_to_unix(r->last_logon)));
90         printf("\tLogoff Time              :\t%s\n",
91                http_timestring(talloc_tos(), nt_time_to_unix(r->last_logoff)));
92         printf("\tKickoff Time             :\t%s\n",
93                http_timestring(talloc_tos(), nt_time_to_unix(r->acct_expiry)));
94         printf("\tPassword last set Time   :\t%s\n",
95                http_timestring(talloc_tos(), nt_time_to_unix(r->last_password_change)));
96         printf("\tPassword can change Time :\t%s\n",
97                http_timestring(talloc_tos(), nt_time_to_unix(r->allow_password_change)));
98         printf("\tPassword must change Time:\t%s\n",
99                http_timestring(talloc_tos(), nt_time_to_unix(r->force_password_change)));
100
101         printf("\tunknown_2[0..31]...\n"); /* user passwords? */
102
103         printf("\tuser_rid :\t0x%x\n"  , r->rid); /* User ID */
104         printf("\tgroup_rid:\t0x%x\n"  , r->primary_gid); /* Group ID */
105         printf("\tacb_info :\t0x%08x\n", r->acct_flags); /* Account Control Info */
106
107         printf("\tfields_present:\t0x%08x\n", r->fields_present); /* 0x00ff ffff */
108         printf("\tlogon_divs:\t%d\n", r->logon_hours.units_per_week); /* 0x0000 00a8 which is 168 which is num hrs in a week */
109         printf("\tbad_password_count:\t0x%08x\n", r->bad_password_count);
110         printf("\tlogon_count:\t0x%08x\n", r->logon_count);
111
112         printf("\tpadding1[0..7]...\n");
113
114         if (r->logon_hours.bits) {
115                 printf("\tlogon_hrs[0..%d]...\n", r->logon_hours.units_per_week/8);
116         }
117 }
118
119
120 static void display_password_properties(uint32_t password_properties)
121 {
122         printf("password_properties: 0x%08x\n", password_properties);
123
124         if (password_properties & DOMAIN_PASSWORD_COMPLEX)
125                 printf("\tDOMAIN_PASSWORD_COMPLEX\n");
126
127         if (password_properties & DOMAIN_PASSWORD_NO_ANON_CHANGE)
128                 printf("\tDOMAIN_PASSWORD_NO_ANON_CHANGE\n");
129
130         if (password_properties & DOMAIN_PASSWORD_NO_CLEAR_CHANGE)
131                 printf("\tDOMAIN_PASSWORD_NO_CLEAR_CHANGE\n");
132
133         if (password_properties & DOMAIN_PASSWORD_LOCKOUT_ADMINS)
134                 printf("\tDOMAIN_PASSWORD_LOCKOUT_ADMINS\n");
135
136         if (password_properties & DOMAIN_PASSWORD_STORE_CLEARTEXT)
137                 printf("\tDOMAIN_PASSWORD_STORE_CLEARTEXT\n");
138
139         if (password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE)
140                 printf("\tDOMAIN_REFUSE_PASSWORD_CHANGE\n");
141 }
142
143 static void display_sam_dom_info_1(struct samr_DomInfo1 *info1)
144 {
145         printf("Minimum password length:\t\t\t%d\n",
146                 info1->min_password_length);
147         printf("Password uniqueness (remember x passwords):\t%d\n",
148                 info1->password_history_length);
149         display_password_properties(info1->password_properties);
150         printf("password expire in:\t\t\t\t%s\n",
151                 display_time(info1->max_password_age));
152         printf("Min password age (allow changing in x days):\t%s\n",
153                 display_time(info1->min_password_age));
154 }
155
156 static void display_sam_dom_info_2(struct samr_DomGeneralInformation *general)
157 {
158         printf("Domain:\t\t%s\n", general->domain_name.string);
159         printf("Server:\t\t%s\n", general->primary.string);
160         printf("Comment:\t%s\n", general->oem_information.string);
161
162         printf("Total Users:\t%d\n", general->num_users);
163         printf("Total Groups:\t%d\n", general->num_groups);
164         printf("Total Aliases:\t%d\n", general->num_aliases);
165
166         printf("Sequence No:\t%llu\n", (unsigned long long)general->sequence_num);
167
168         printf("Force Logoff:\t%d\n",
169                 (int)nt_time_to_unix_abs(&general->force_logoff_time));
170
171         printf("Domain Server State:\t0x%x\n", general->domain_server_state);
172         printf("Server Role:\t%s\n", server_role_str(general->role));
173         printf("Unknown 3:\t0x%x\n", general->unknown3);
174 }
175
176 static void display_sam_dom_info_3(struct samr_DomInfo3 *info3)
177 {
178         printf("Force Logoff:\t%d\n",
179                 (int)nt_time_to_unix_abs(&info3->force_logoff_time));
180 }
181
182 static void display_sam_dom_info_4(struct samr_DomOEMInformation *oem)
183 {
184         printf("Comment:\t%s\n", oem->oem_information.string);
185 }
186
187 static void display_sam_dom_info_5(struct samr_DomInfo5 *info5)
188 {
189         printf("Domain:\t\t%s\n", info5->domain_name.string);
190 }
191
192 static void display_sam_dom_info_6(struct samr_DomInfo6 *info6)
193 {
194         printf("Server:\t\t%s\n", info6->primary.string);
195 }
196
197 static void display_sam_dom_info_7(struct samr_DomInfo7 *info7)
198 {
199         printf("Server Role:\t%s\n", server_role_str(info7->role));
200 }
201
202 static void display_sam_dom_info_8(struct samr_DomInfo8 *info8)
203 {
204         printf("Sequence No:\t%llu\n", (unsigned long long)info8->sequence_num);
205         printf("Domain Create Time:\t%s\n",
206                 http_timestring(talloc_tos(), nt_time_to_unix(info8->domain_create_time)));
207 }
208
209 static void display_sam_dom_info_9(struct samr_DomInfo9 *info9)
210 {
211         printf("Domain Server State:\t0x%x\n", info9->domain_server_state);
212 }
213
214 static void display_sam_dom_info_12(struct samr_DomInfo12 *info12)
215 {
216         printf("Bad password lockout duration:               %s\n",
217                 display_time(info12->lockout_duration));
218         printf("Reset Lockout after:                         %s\n",
219                 display_time(info12->lockout_window));
220         printf("Lockout after bad attempts:                  %d\n",
221                 info12->lockout_threshold);
222 }
223
224 static void display_sam_dom_info_13(struct samr_DomInfo13 *info13)
225 {
226         printf("Sequence No:\t%llu\n", (unsigned long long)info13->sequence_num);
227         printf("Domain Create Time:\t%s\n",
228                 http_timestring(talloc_tos(), nt_time_to_unix(info13->domain_create_time)));
229         printf("Sequence No at last promotion:\t%llu\n",
230                 (unsigned long long)info13->modified_count_at_last_promotion);
231 }
232
233 static void display_sam_info_1(struct samr_DispEntryGeneral *r)
234 {
235         printf("index: 0x%x ", r->idx);
236         printf("RID: 0x%x ", r->rid);
237         printf("acb: 0x%08x ", r->acct_flags);
238         printf("Account: %s\t", r->account_name.string);
239         printf("Name: %s\t", r->full_name.string);
240         printf("Desc: %s\n", r->description.string);
241 }
242
243 static void display_sam_info_2(struct samr_DispEntryFull *r)
244 {
245         printf("index: 0x%x ", r->idx);
246         printf("RID: 0x%x ", r->rid);
247         printf("acb: 0x%08x ", r->acct_flags);
248         printf("Account: %s\t", r->account_name.string);
249         printf("Desc: %s\n", r->description.string);
250 }
251
252 static void display_sam_info_3(struct samr_DispEntryFullGroup *r)
253 {
254         printf("index: 0x%x ", r->idx);
255         printf("RID: 0x%x ", r->rid);
256         printf("acb: 0x%08x ", r->acct_flags);
257         printf("Account: %s\t", r->account_name.string);
258         printf("Desc: %s\n", r->description.string);
259 }
260
261 static void display_sam_info_4(struct samr_DispEntryAscii *r)
262 {
263         printf("index: 0x%x ", r->idx);
264         printf("Account: %s\n", r->account_name.string);
265 }
266
267 static void display_sam_info_5(struct samr_DispEntryAscii *r)
268 {
269         printf("index: 0x%x ", r->idx);
270         printf("Account: %s\n", r->account_name.string);
271 }
272
273 /****************************************************************************
274  ****************************************************************************/
275
276 static NTSTATUS get_domain_handle(struct rpc_pipe_client *cli,
277                                   TALLOC_CTX *mem_ctx,
278                                   const char *sam,
279                                   struct policy_handle *connect_pol,
280                                   uint32_t access_mask,
281                                   struct dom_sid *_domain_sid,
282                                   struct policy_handle *domain_pol)
283 {
284         struct dcerpc_binding_handle *b = cli->binding_handle;
285         NTSTATUS status = NT_STATUS_INVALID_PARAMETER, result;
286
287         if (strcasecmp_m(sam, "domain") == 0) {
288                 status = dcerpc_samr_OpenDomain(b, mem_ctx,
289                                               connect_pol,
290                                               access_mask,
291                                               _domain_sid,
292                                               domain_pol,
293                                               &result);
294         } else if (strcasecmp_m(sam, "builtin") == 0) {
295                 status = dcerpc_samr_OpenDomain(b, mem_ctx,
296                                               connect_pol,
297                                               access_mask,
298                                               discard_const_p(struct dom_sid2, &global_sid_Builtin),
299                                               domain_pol,
300                                               &result);
301         }
302
303         if (!NT_STATUS_IS_OK(status)) {
304                 return status;
305         }
306
307         return result;
308 }
309
310 /**********************************************************************
311  * Query user information
312  */
313 static NTSTATUS cmd_samr_query_user(struct rpc_pipe_client *cli,
314                                     TALLOC_CTX *mem_ctx,
315                                     int argc, const char **argv)
316 {
317         struct policy_handle connect_pol, domain_pol, user_pol;
318         NTSTATUS status, result;
319         uint32 info_level = 21;
320         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
321         union samr_UserInfo *info = NULL;
322         uint32 user_rid = 0;
323         struct dcerpc_binding_handle *b = cli->binding_handle;
324
325         if ((argc < 2) || (argc > 4)) {
326                 printf("Usage: %s rid [info level] [access mask] \n", argv[0]);
327                 return NT_STATUS_OK;
328         }
329
330         sscanf(argv[1], "%i", &user_rid);
331
332         if (argc > 2)
333                 sscanf(argv[2], "%i", &info_level);
334
335         if (argc > 3)
336                 sscanf(argv[3], "%x", &access_mask);
337
338
339         status = rpccli_try_samr_connects(cli, mem_ctx,
340                                           MAXIMUM_ALLOWED_ACCESS,
341                                           &connect_pol);
342         if (!NT_STATUS_IS_OK(status)) {
343                 goto done;
344         }
345
346         status = dcerpc_samr_OpenDomain(b, mem_ctx,
347                                         &connect_pol,
348                                         MAXIMUM_ALLOWED_ACCESS,
349                                         &domain_sid,
350                                         &domain_pol,
351                                         &result);
352         if (!NT_STATUS_IS_OK(status)) {
353                 goto done;
354         }
355         if (!NT_STATUS_IS_OK(result)) {
356                 status = result;
357                 goto done;
358         }
359
360         status = dcerpc_samr_OpenUser(b, mem_ctx,
361                                       &domain_pol,
362                                       access_mask,
363                                       user_rid,
364                                       &user_pol,
365                                       &result);
366         if (!NT_STATUS_IS_OK(status)) {
367                 goto done;
368         }
369         if (NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_USER) &&
370             (user_rid == 0)) {
371
372                 /* Probably this was a user name, try lookupnames */
373                 struct samr_Ids rids, types;
374                 struct lsa_String lsa_acct_name;
375
376                 init_lsa_String(&lsa_acct_name, argv[1]);
377
378                 status = dcerpc_samr_LookupNames(b, mem_ctx,
379                                                  &domain_pol,
380                                                  1,
381                                                  &lsa_acct_name,
382                                                  &rids,
383                                                  &types,
384                                                  &result);
385                 if (!NT_STATUS_IS_OK(status)) {
386                         goto done;
387                 }
388                 if (NT_STATUS_IS_OK(result)) {
389                         status = dcerpc_samr_OpenUser(b, mem_ctx,
390                                                       &domain_pol,
391                                                       access_mask,
392                                                       rids.ids[0],
393                                                       &user_pol,
394                                                       &result);
395                         if (!NT_STATUS_IS_OK(status)) {
396                                 goto done;
397                         }
398                 }
399         }
400
401
402         if (!NT_STATUS_IS_OK(result)) {
403                 status = result;
404                 goto done;
405         }
406
407         status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
408                                            &user_pol,
409                                            info_level,
410                                            &info,
411                                            &result);
412         if (!NT_STATUS_IS_OK(status)) {
413                 goto done;
414         }
415         if (!NT_STATUS_IS_OK(result)) {
416                 status = result;
417                 goto done;
418         }
419
420         switch (info_level) {
421         case 7:
422                 display_samr_user_info_7(&info->info7);
423                 break;
424         case 9:
425                 display_samr_user_info_9(&info->info9);
426                 break;
427         case 16:
428                 display_samr_user_info_16(&info->info16);
429                 break;
430         case 20:
431                 display_samr_user_info_20(&info->info20);
432                 break;
433         case 21:
434                 display_samr_user_info_21(&info->info21);
435                 break;
436         default:
437                 printf("Unsupported infolevel: %d\n", info_level);
438                 break;
439         }
440
441         dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
442         dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
443         dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
444
445 done:
446         return status;
447 }
448
449 /****************************************************************************
450  display group info
451  ****************************************************************************/
452 static void display_group_info1(struct samr_GroupInfoAll *info1)
453 {
454         printf("\tGroup Name:\t%s\n", info1->name.string);
455         printf("\tDescription:\t%s\n", info1->description.string);
456         printf("\tGroup Attribute:%d\n", info1->attributes);
457         printf("\tNum Members:%d\n", info1->num_members);
458 }
459
460 /****************************************************************************
461  display group info
462  ****************************************************************************/
463 static void display_group_info2(struct lsa_String *info2)
464 {
465         printf("\tGroup Description:%s\n", info2->string);
466 }
467
468
469 /****************************************************************************
470  display group info
471  ****************************************************************************/
472 static void display_group_info3(struct samr_GroupInfoAttributes *info3)
473 {
474         printf("\tGroup Attribute:%d\n", info3->attributes);
475 }
476
477
478 /****************************************************************************
479  display group info
480  ****************************************************************************/
481 static void display_group_info4(struct lsa_String *info4)
482 {
483         printf("\tGroup Description:%s\n", info4->string);
484 }
485
486 /****************************************************************************
487  display group info
488  ****************************************************************************/
489 static void display_group_info5(struct samr_GroupInfoAll *info5)
490 {
491         printf("\tGroup Name:\t%s\n", info5->name.string);
492         printf("\tDescription:\t%s\n", info5->description.string);
493         printf("\tGroup Attribute:%d\n", info5->attributes);
494         printf("\tNum Members:%d\n", info5->num_members);
495 }
496
497 /****************************************************************************
498  display sam sync structure
499  ****************************************************************************/
500 static void display_group_info(union samr_GroupInfo *info,
501                                enum samr_GroupInfoEnum level)
502 {
503         switch (level) {
504                 case 1:
505                         display_group_info1(&info->all);
506                         break;
507                 case 2:
508                         display_group_info2(&info->name);
509                         break;
510                 case 3:
511                         display_group_info3(&info->attributes);
512                         break;
513                 case 4:
514                         display_group_info4(&info->description);
515                         break;
516                 case 5:
517                         display_group_info5(&info->all2);
518                         break;
519         }
520 }
521
522 /***********************************************************************
523  * Query group information
524  */
525 static NTSTATUS cmd_samr_query_group(struct rpc_pipe_client *cli,
526                                      TALLOC_CTX *mem_ctx,
527                                      int argc, const char **argv)
528 {
529         struct policy_handle connect_pol, domain_pol, group_pol;
530         NTSTATUS status, result;
531         enum samr_GroupInfoEnum info_level = GROUPINFOALL;
532         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
533         union samr_GroupInfo *group_info = NULL;
534         uint32 group_rid;
535         struct dcerpc_binding_handle *b = cli->binding_handle;
536
537         if ((argc < 2) || (argc > 4)) {
538                 printf("Usage: %s rid [info level] [access mask]\n", argv[0]);
539                 return NT_STATUS_OK;
540         }
541
542         sscanf(argv[1], "%i", &group_rid);
543
544         if (argc > 2)
545                 info_level = atoi(argv[2]);
546
547         if (argc > 3)
548                 sscanf(argv[3], "%x", &access_mask);
549
550         status = rpccli_try_samr_connects(cli, mem_ctx,
551                                           MAXIMUM_ALLOWED_ACCESS,
552                                           &connect_pol);
553         if (!NT_STATUS_IS_OK(status)) {
554                 goto done;
555         }
556
557         status = dcerpc_samr_OpenDomain(b, mem_ctx,
558                                         &connect_pol,
559                                         MAXIMUM_ALLOWED_ACCESS,
560                                         &domain_sid,
561                                         &domain_pol,
562                                         &result);
563         if (!NT_STATUS_IS_OK(status)) {
564                 goto done;
565         }
566         if (!NT_STATUS_IS_OK(result)) {
567                 status = result;
568                 goto done;
569         }
570
571         status = dcerpc_samr_OpenGroup(b, mem_ctx,
572                                        &domain_pol,
573                                        access_mask,
574                                        group_rid,
575                                        &group_pol,
576                                        &result);
577         if (!NT_STATUS_IS_OK(status)) {
578                 goto done;
579         }
580         if (!NT_STATUS_IS_OK(result)) {
581                 status = result;
582                 goto done;
583         }
584
585         status = dcerpc_samr_QueryGroupInfo(b, mem_ctx,
586                                             &group_pol,
587                                             info_level,
588                                             &group_info,
589                                             &result);
590         if (!NT_STATUS_IS_OK(status)) {
591                 goto done;
592         }
593         if (!NT_STATUS_IS_OK(result)) {
594                 status = result;
595                 goto done;
596         }
597
598         display_group_info(group_info, info_level);
599
600         dcerpc_samr_Close(b, mem_ctx, &group_pol, &result);
601         dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
602         dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
603 done:
604         return status;
605 }
606
607 /* Query groups a user is a member of */
608
609 static NTSTATUS cmd_samr_query_usergroups(struct rpc_pipe_client *cli,
610                                           TALLOC_CTX *mem_ctx,
611                                           int argc, const char **argv)
612 {
613         struct policy_handle            connect_pol,
614                                 domain_pol,
615                                 user_pol;
616         NTSTATUS status, result;
617         uint32                  user_rid;
618         uint32                  access_mask = MAXIMUM_ALLOWED_ACCESS;
619         int                     i;
620         struct samr_RidWithAttributeArray *rid_array = NULL;
621         struct dcerpc_binding_handle *b = cli->binding_handle;
622
623         if ((argc < 2) || (argc > 3)) {
624                 printf("Usage: %s rid [access mask]\n", argv[0]);
625                 return NT_STATUS_OK;
626         }
627
628         sscanf(argv[1], "%i", &user_rid);
629
630         if (argc > 2)
631                 sscanf(argv[2], "%x", &access_mask);
632
633         status = rpccli_try_samr_connects(cli, mem_ctx,
634                                           MAXIMUM_ALLOWED_ACCESS,
635                                           &connect_pol);
636         if (!NT_STATUS_IS_OK(status)) {
637                 goto done;
638         }
639
640         status = dcerpc_samr_OpenDomain(b, mem_ctx,
641                                         &connect_pol,
642                                         MAXIMUM_ALLOWED_ACCESS,
643                                         &domain_sid,
644                                         &domain_pol,
645                                         &result);
646         if (!NT_STATUS_IS_OK(status)) {
647                 goto done;
648         }
649         if (!NT_STATUS_IS_OK(result)) {
650                 status = result;
651                 goto done;
652         }
653
654         status = dcerpc_samr_OpenUser(b, mem_ctx,
655                                       &domain_pol,
656                                       access_mask,
657                                       user_rid,
658                                       &user_pol,
659                                       &result);
660
661         if (!NT_STATUS_IS_OK(status)) {
662                 goto done;
663         }
664         if (!NT_STATUS_IS_OK(result)) {
665                 status = result;
666                 goto done;
667         }
668
669         status = dcerpc_samr_GetGroupsForUser(b, mem_ctx,
670                                               &user_pol,
671                                               &rid_array,
672                                               &result);
673         if (!NT_STATUS_IS_OK(status)) {
674                 goto done;
675         }
676         if (!NT_STATUS_IS_OK(result)) {
677                 status = result;
678                 goto done;
679         }
680
681         for (i = 0; i < rid_array->count; i++) {
682                 printf("\tgroup rid:[0x%x] attr:[0x%x]\n",
683                        rid_array->rids[i].rid,
684                        rid_array->rids[i].attributes);
685         }
686
687         dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
688         dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
689         dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
690  done:
691         return status;
692 }
693
694 /* Query aliases a user is a member of */
695
696 static NTSTATUS cmd_samr_query_useraliases(struct rpc_pipe_client *cli,
697                                            TALLOC_CTX *mem_ctx,
698                                            int argc, const char **argv)
699 {
700         struct policy_handle            connect_pol, domain_pol;
701         NTSTATUS status, result;
702         struct dom_sid                *sids;
703         uint32_t                     num_sids;
704         uint32                  access_mask = MAXIMUM_ALLOWED_ACCESS;
705         int                     i;
706         struct lsa_SidArray sid_array;
707         struct samr_Ids alias_rids;
708         struct dcerpc_binding_handle *b = cli->binding_handle;
709
710         if (argc < 3) {
711                 printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
712                 return NT_STATUS_INVALID_PARAMETER;
713         }
714
715         sids = NULL;
716         num_sids = 0;
717
718         for (i=2; i<argc; i++) {
719                 struct dom_sid tmp_sid;
720                 if (!string_to_sid(&tmp_sid, argv[i])) {
721                         printf("%s is not a legal SID\n", argv[i]);
722                         return NT_STATUS_INVALID_PARAMETER;
723                 }
724                 result = add_sid_to_array(mem_ctx, &tmp_sid, &sids, &num_sids);
725                 if (!NT_STATUS_IS_OK(result)) {
726                         return result;
727                 }
728         }
729
730         if (num_sids) {
731                 sid_array.sids = talloc_zero_array(mem_ctx, struct lsa_SidPtr, num_sids);
732                 if (sid_array.sids == NULL)
733                         return NT_STATUS_NO_MEMORY;
734         } else {
735                 sid_array.sids = NULL;
736         }
737
738         for (i=0; i<num_sids; i++) {
739                 sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sids[i]);
740                 if (!sid_array.sids[i].sid) {
741                         return NT_STATUS_NO_MEMORY;
742                 }
743         }
744
745         sid_array.num_sids = num_sids;
746
747         status = rpccli_try_samr_connects(cli, mem_ctx,
748                                           MAXIMUM_ALLOWED_ACCESS,
749                                           &connect_pol);
750         if (!NT_STATUS_IS_OK(status)) {
751                 goto done;
752         }
753
754         status = get_domain_handle(cli, mem_ctx, argv[1],
755                                    &connect_pol,
756                                    access_mask,
757                                    &domain_sid,
758                                    &domain_pol);
759         if (!NT_STATUS_IS_OK(status)) {
760                 goto done;
761         }
762
763         status = dcerpc_samr_GetAliasMembership(b, mem_ctx,
764                                                 &domain_pol,
765                                                 &sid_array,
766                                                 &alias_rids,
767                                                 &result);
768         if (!NT_STATUS_IS_OK(status)) {
769                 goto done;
770         }
771         if (!NT_STATUS_IS_OK(result)) {
772                 status = result;
773                 goto done;
774         }
775
776         for (i = 0; i < alias_rids.count; i++) {
777                 printf("\tgroup rid:[0x%x]\n", alias_rids.ids[i]);
778         }
779
780         dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
781         dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
782  done:
783         return status;
784 }
785
786 /* Query members of a group */
787
788 static NTSTATUS cmd_samr_query_groupmem(struct rpc_pipe_client *cli,
789                                         TALLOC_CTX *mem_ctx,
790                                         int argc, const char **argv)
791 {
792         struct policy_handle connect_pol, domain_pol, group_pol;
793         NTSTATUS status, result;
794         uint32 group_rid;
795         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
796         int i;
797         unsigned int old_timeout;
798         struct samr_RidAttrArray *rids = NULL;
799         struct dcerpc_binding_handle *b = cli->binding_handle;
800
801         if ((argc < 2) || (argc > 3)) {
802                 printf("Usage: %s rid [access mask]\n", argv[0]);
803                 return NT_STATUS_OK;
804         }
805
806         sscanf(argv[1], "%i", &group_rid);
807
808         if (argc > 2)
809                 sscanf(argv[2], "%x", &access_mask);
810
811         status = rpccli_try_samr_connects(cli, mem_ctx,
812                                           MAXIMUM_ALLOWED_ACCESS,
813                                           &connect_pol);
814         if (!NT_STATUS_IS_OK(status)) {
815                 goto done;
816         }
817
818         status = dcerpc_samr_OpenDomain(b, mem_ctx,
819                                         &connect_pol,
820                                         MAXIMUM_ALLOWED_ACCESS,
821                                         &domain_sid,
822                                         &domain_pol,
823                                         &result);
824         if (!NT_STATUS_IS_OK(status)) {
825                 goto done;
826         }
827         if (!NT_STATUS_IS_OK(result)) {
828                 status = result;
829                 goto done;
830         }
831
832         status = dcerpc_samr_OpenGroup(b, mem_ctx,
833                                        &domain_pol,
834                                        access_mask,
835                                        group_rid,
836                                        &group_pol,
837                                        &result);
838         if (!NT_STATUS_IS_OK(status)) {
839                 goto done;
840         }
841         if (!NT_STATUS_IS_OK(result)) {
842                 status = result;
843                 goto done;
844         }
845
846         /* Make sure to wait for our DC's reply */
847         old_timeout = rpccli_set_timeout(cli, 30000); /* 30 seconds. */
848         rpccli_set_timeout(cli, MAX(30000, old_timeout)); /* At least 30 sec */
849
850         status = dcerpc_samr_QueryGroupMember(b, mem_ctx,
851                                               &group_pol,
852                                               &rids,
853                                               &result);
854
855         rpccli_set_timeout(cli, old_timeout);
856
857         if (!NT_STATUS_IS_OK(status)) {
858                 goto done;
859         }
860         if (!NT_STATUS_IS_OK(result)) {
861                 status = result;
862                 goto done;
863         }
864
865         for (i = 0; i < rids->count; i++) {
866                 printf("\trid:[0x%x] attr:[0x%x]\n", rids->rids[i],
867                        rids->attributes[i]);
868         }
869
870         dcerpc_samr_Close(b, mem_ctx, &group_pol, &result);
871         dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
872         dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
873  done:
874         return status;
875 }
876
877 /* Enumerate domain users */
878
879 static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli,
880                                         TALLOC_CTX *mem_ctx,
881                                         int argc, const char **argv)
882 {
883         struct policy_handle connect_pol;
884         struct policy_handle domain_pol = { 0, };
885         NTSTATUS status, result;
886         uint32 start_idx, num_dom_users, i;
887         struct samr_SamArray *dom_users = NULL;
888         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
889         uint32 acb_mask = ACB_NORMAL;
890         uint32_t size = 0xffff;
891         struct dcerpc_binding_handle *b = cli->binding_handle;
892
893         if ((argc < 1) || (argc > 4)) {
894                 printf("Usage: %s [access_mask] [acb_mask] [size]\n", argv[0]);
895                 return NT_STATUS_OK;
896         }
897
898         if (argc > 1) {
899                 sscanf(argv[1], "%x", &access_mask);
900         }
901
902         if (argc > 2) {
903                 sscanf(argv[2], "%x", &acb_mask);
904         }
905
906         if (argc > 3) {
907                 sscanf(argv[3], "%x", &size);
908         }
909
910         /* Get sam policy handle */
911
912         status = rpccli_try_samr_connects(cli, mem_ctx,
913                                           MAXIMUM_ALLOWED_ACCESS,
914                                           &connect_pol);
915         if (!NT_STATUS_IS_OK(status)) {
916                 goto done;
917         }
918
919         /* Get domain policy handle */
920
921         status = get_domain_handle(cli, mem_ctx, "domain",
922                                    &connect_pol,
923                                    access_mask,
924                                    &domain_sid,
925                                    &domain_pol);
926         if (!NT_STATUS_IS_OK(status)) {
927                 goto done;
928         }
929
930         /* Enumerate domain users */
931
932         start_idx = 0;
933
934         do {
935                 status = dcerpc_samr_EnumDomainUsers(b, mem_ctx,
936                                                      &domain_pol,
937                                                      &start_idx,
938                                                      acb_mask,
939                                                      &dom_users,
940                                                      size,
941                                                      &num_dom_users,
942                                                      &result);
943                 if (!NT_STATUS_IS_OK(status)) {
944                         goto done;
945                 }
946                 if (NT_STATUS_IS_OK(result) ||
947                     NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
948
949                         for (i = 0; i < num_dom_users; i++)
950                                printf("user:[%s] rid:[0x%x]\n",
951                                        dom_users->entries[i].name.string,
952                                        dom_users->entries[i].idx);
953                 }
954
955         } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
956
957  done:
958         if (is_valid_policy_hnd(&domain_pol))
959                 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
960
961         if (is_valid_policy_hnd(&connect_pol))
962                 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
963
964         return status;
965 }
966
967 /* Enumerate domain groups */
968
969 static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli,
970                                          TALLOC_CTX *mem_ctx,
971                                          int argc, const char **argv)
972 {
973         struct policy_handle connect_pol;
974         struct policy_handle domain_pol = { 0, };
975         NTSTATUS status, result;
976         uint32 start_idx, num_dom_groups, i;
977         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
978         struct samr_SamArray *dom_groups = NULL;
979         uint32_t size = 0xffff;
980         struct dcerpc_binding_handle *b = cli->binding_handle;
981
982         if ((argc < 1) || (argc > 3)) {
983                 printf("Usage: %s [access_mask] [max_size]\n", argv[0]);
984                 return NT_STATUS_OK;
985         }
986
987         if (argc > 1) {
988                 sscanf(argv[1], "%x", &access_mask);
989         }
990
991         if (argc > 2) {
992                 sscanf(argv[2], "%x", &size);
993         }
994
995         /* Get sam policy handle */
996
997         status = rpccli_try_samr_connects(cli, mem_ctx,
998                                           MAXIMUM_ALLOWED_ACCESS,
999                                           &connect_pol);
1000         if (!NT_STATUS_IS_OK(status)) {
1001                 goto done;
1002         }
1003
1004         /* Get domain policy handle */
1005
1006         status = get_domain_handle(cli, mem_ctx, "domain",
1007                                    &connect_pol,
1008                                    access_mask,
1009                                    &domain_sid,
1010                                    &domain_pol);
1011         if (!NT_STATUS_IS_OK(status)) {
1012                 goto done;
1013         }
1014
1015         /* Enumerate domain groups */
1016
1017         start_idx = 0;
1018
1019         do {
1020                 status = dcerpc_samr_EnumDomainGroups(b, mem_ctx,
1021                                                       &domain_pol,
1022                                                       &start_idx,
1023                                                       &dom_groups,
1024                                                       size,
1025                                                       &num_dom_groups,
1026                                                       &result);
1027                 if (!NT_STATUS_IS_OK(status)) {
1028                         goto done;
1029                 }
1030                 if (NT_STATUS_IS_OK(result) ||
1031                     NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1032
1033                         for (i = 0; i < num_dom_groups; i++)
1034                                 printf("group:[%s] rid:[0x%x]\n",
1035                                        dom_groups->entries[i].name.string,
1036                                        dom_groups->entries[i].idx);
1037                 }
1038
1039         } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1040
1041  done:
1042         if (is_valid_policy_hnd(&domain_pol))
1043                 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1044
1045         if (is_valid_policy_hnd(&connect_pol))
1046                 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1047
1048         return status;
1049 }
1050
1051 /* Enumerate alias groups */
1052
1053 static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli,
1054                                          TALLOC_CTX *mem_ctx,
1055                                          int argc, const char **argv)
1056 {
1057         struct policy_handle connect_pol;
1058         struct policy_handle domain_pol = { 0, };
1059         NTSTATUS status, result;
1060         uint32 start_idx, num_als_groups, i;
1061         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1062         struct samr_SamArray *als_groups = NULL;
1063         uint32_t size = 0xffff;
1064         struct dcerpc_binding_handle *b = cli->binding_handle;
1065
1066         if ((argc < 2) || (argc > 4)) {
1067                 printf("Usage: %s builtin|domain [access mask] [max_size]\n", argv[0]);
1068                 return NT_STATUS_OK;
1069         }
1070
1071         if (argc > 2) {
1072                 sscanf(argv[2], "%x", &access_mask);
1073         }
1074
1075         if (argc > 3) {
1076                 sscanf(argv[3], "%x", &size);
1077         }
1078
1079         /* Get sam policy handle */
1080
1081         status = rpccli_try_samr_connects(cli, mem_ctx,
1082                                           MAXIMUM_ALLOWED_ACCESS,
1083                                           &connect_pol);
1084         if (!NT_STATUS_IS_OK(status)) {
1085                 goto done;
1086         }
1087
1088         /* Get domain policy handle */
1089
1090         status = get_domain_handle(cli, mem_ctx, argv[1],
1091                                    &connect_pol,
1092                                    access_mask,
1093                                    &domain_sid,
1094                                    &domain_pol);
1095         if (!NT_STATUS_IS_OK(status)) {
1096                 goto done;
1097         }
1098
1099         /* Enumerate alias groups */
1100
1101         start_idx = 0;
1102
1103         do {
1104                 status = dcerpc_samr_EnumDomainAliases(b, mem_ctx,
1105                                                        &domain_pol,
1106                                                        &start_idx,
1107                                                        &als_groups,
1108                                                        size,
1109                                                        &num_als_groups,
1110                                                        &result);
1111                 if (!NT_STATUS_IS_OK(status)) {
1112                         goto done;
1113                 }
1114                 if (NT_STATUS_IS_OK(result) ||
1115                     NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1116
1117                         for (i = 0; i < num_als_groups; i++)
1118                                 printf("group:[%s] rid:[0x%x]\n",
1119                                        als_groups->entries[i].name.string,
1120                                        als_groups->entries[i].idx);
1121                 }
1122         } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1123
1124  done:
1125         if (is_valid_policy_hnd(&domain_pol))
1126                 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1127
1128         if (is_valid_policy_hnd(&connect_pol))
1129                 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1130
1131         return status;
1132 }
1133
1134 /* Enumerate domains */
1135
1136 static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli,
1137                                       TALLOC_CTX *mem_ctx,
1138                                       int argc, const char **argv)
1139 {
1140         struct policy_handle connect_pol;
1141         NTSTATUS status, result;
1142         uint32 start_idx, size, num_entries, i;
1143         uint32 access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1144         struct samr_SamArray *sam = NULL;
1145         struct dcerpc_binding_handle *b = cli->binding_handle;
1146
1147         if ((argc < 1) || (argc > 2)) {
1148                 printf("Usage: %s [access mask]\n", argv[0]);
1149                 return NT_STATUS_OK;
1150         }
1151
1152         if (argc > 1) {
1153                 sscanf(argv[1], "%x", &access_mask);
1154         }
1155
1156         /* Get sam policy handle */
1157
1158         status = rpccli_try_samr_connects(cli, mem_ctx,
1159                                           access_mask,
1160                                           &connect_pol);
1161         if (!NT_STATUS_IS_OK(status)) {
1162                 goto done;
1163         }
1164
1165         /* Enumerate alias groups */
1166
1167         start_idx = 0;
1168         size = 0xffff;
1169
1170         do {
1171                 status = dcerpc_samr_EnumDomains(b, mem_ctx,
1172                                                  &connect_pol,
1173                                                  &start_idx,
1174                                                  &sam,
1175                                                  size,
1176                                                  &num_entries,
1177                                                  &result);
1178                 if (!NT_STATUS_IS_OK(status)) {
1179                         goto done;
1180                 }
1181                 if (NT_STATUS_IS_OK(result) ||
1182                     NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1183
1184                         for (i = 0; i < num_entries; i++)
1185                                 printf("name:[%s] idx:[0x%x]\n",
1186                                        sam->entries[i].name.string,
1187                                        sam->entries[i].idx);
1188                 }
1189         } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
1190
1191  done:
1192         if (is_valid_policy_hnd(&connect_pol)) {
1193                 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1194         }
1195
1196         return status;
1197 }
1198
1199
1200 /* Query alias membership */
1201
1202 static NTSTATUS cmd_samr_query_aliasmem(struct rpc_pipe_client *cli,
1203                                         TALLOC_CTX *mem_ctx,
1204                                         int argc, const char **argv)
1205 {
1206         struct policy_handle connect_pol, domain_pol, alias_pol;
1207         NTSTATUS status, result;
1208         uint32 alias_rid, i;
1209         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1210         struct lsa_SidArray sid_array;
1211         struct dcerpc_binding_handle *b = cli->binding_handle;
1212
1213         if ((argc < 3) || (argc > 4)) {
1214                 printf("Usage: %s builtin|domain rid [access mask]\n", argv[0]);
1215                 return NT_STATUS_OK;
1216         }
1217
1218         sscanf(argv[2], "%i", &alias_rid);
1219
1220         if (argc > 3)
1221                 sscanf(argv[3], "%x", &access_mask);
1222
1223         /* Open SAMR handle */
1224
1225         status = rpccli_try_samr_connects(cli, mem_ctx,
1226                                           MAXIMUM_ALLOWED_ACCESS,
1227                                           &connect_pol);
1228         if (!NT_STATUS_IS_OK(status)) {
1229                 goto done;
1230         }
1231
1232         /* Open handle on domain */
1233
1234         status = get_domain_handle(cli, mem_ctx, argv[1],
1235                                    &connect_pol,
1236                                    MAXIMUM_ALLOWED_ACCESS,
1237                                    &domain_sid,
1238                                    &domain_pol);
1239         if (!NT_STATUS_IS_OK(status)) {
1240                 goto done;
1241         }
1242
1243         /* Open handle on alias */
1244
1245         status = dcerpc_samr_OpenAlias(b, mem_ctx,
1246                                        &domain_pol,
1247                                        access_mask,
1248                                        alias_rid,
1249                                        &alias_pol,
1250                                        &result);
1251         if (!NT_STATUS_IS_OK(status)) {
1252                 goto done;
1253         }
1254         if (!NT_STATUS_IS_OK(result)) {
1255                 status = result;
1256                 goto done;
1257         }
1258
1259         status = dcerpc_samr_GetMembersInAlias(b, mem_ctx,
1260                                                &alias_pol,
1261                                                &sid_array,
1262                                                &result);
1263         if (!NT_STATUS_IS_OK(status)) {
1264                 goto done;
1265         }
1266         if (!NT_STATUS_IS_OK(result)) {
1267                 status = result;
1268                 goto done;
1269         }
1270
1271         for (i = 0; i < sid_array.num_sids; i++) {
1272                 fstring sid_str;
1273
1274                 sid_to_fstring(sid_str, sid_array.sids[i].sid);
1275                 printf("\tsid:[%s]\n", sid_str);
1276         }
1277
1278         dcerpc_samr_Close(b, mem_ctx, &alias_pol, &result);
1279         dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1280         dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1281  done:
1282         return status;
1283 }
1284
1285 /* Query alias info */
1286
1287 static NTSTATUS cmd_samr_query_aliasinfo(struct rpc_pipe_client *cli,
1288                                          TALLOC_CTX *mem_ctx,
1289                                          int argc, const char **argv)
1290 {
1291         struct policy_handle connect_pol, domain_pol, alias_pol;
1292         NTSTATUS status, result;
1293         uint32_t alias_rid;
1294         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1295         union samr_AliasInfo *info = NULL;
1296         enum samr_AliasInfoEnum level = ALIASINFOALL;
1297         struct dcerpc_binding_handle *b = cli->binding_handle;
1298
1299         if ((argc < 3) || (argc > 4)) {
1300                 printf("Usage: %s builtin|domain rid [level] [access mask]\n",
1301                         argv[0]);
1302                 return NT_STATUS_OK;
1303         }
1304
1305         sscanf(argv[2], "%i", &alias_rid);
1306
1307         if (argc > 2) {
1308                 level = atoi(argv[3]);
1309         }
1310
1311         if (argc > 3) {
1312                 sscanf(argv[4], "%x", &access_mask);
1313         }
1314
1315         /* Open SAMR handle */
1316
1317         status = rpccli_try_samr_connects(cli, mem_ctx,
1318                                           SEC_FLAG_MAXIMUM_ALLOWED,
1319                                           &connect_pol);
1320         if (!NT_STATUS_IS_OK(status)) {
1321                 goto done;
1322         }
1323
1324         /* Open handle on domain */
1325
1326         status = get_domain_handle(cli, mem_ctx, argv[1],
1327                                    &connect_pol,
1328                                    SEC_FLAG_MAXIMUM_ALLOWED,
1329                                    &domain_sid,
1330                                    &domain_pol);
1331         if (!NT_STATUS_IS_OK(status)) {
1332                 goto done;
1333         }
1334
1335         /* Open handle on alias */
1336
1337         status = dcerpc_samr_OpenAlias(b, mem_ctx,
1338                                        &domain_pol,
1339                                        access_mask,
1340                                        alias_rid,
1341                                        &alias_pol,
1342                                        &result);
1343         if (!NT_STATUS_IS_OK(status)) {
1344                 goto done;
1345         }
1346         if (!NT_STATUS_IS_OK(result)) {
1347                 status = result;
1348                 goto done;
1349         }
1350
1351         status = dcerpc_samr_QueryAliasInfo(b, mem_ctx,
1352                                             &alias_pol,
1353                                             level,
1354                                             &info,
1355                                             &result);
1356         if (!NT_STATUS_IS_OK(status)) {
1357                 goto done;
1358         }
1359         if (!NT_STATUS_IS_OK(result)) {
1360                 status = result;
1361                 goto done;
1362         }
1363
1364         switch (level) {
1365                 case ALIASINFOALL:
1366                         printf("Name: %s\n", info->all.name.string);
1367                         printf("Description: %s\n", info->all.description.string);
1368                         printf("Num Members: %d\n", info->all.num_members);
1369                         break;
1370                 case ALIASINFONAME:
1371                         printf("Name: %s\n", info->name.string);
1372                         break;
1373                 case ALIASINFODESCRIPTION:
1374                         printf("Description: %s\n", info->description.string);
1375                         break;
1376                 default:
1377                         break;
1378         }
1379
1380         dcerpc_samr_Close(b, mem_ctx, &alias_pol, &result);
1381         dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1382         dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1383  done:
1384         return status;
1385 }
1386
1387
1388 /* Query delete an alias membership */
1389
1390 static NTSTATUS cmd_samr_delete_alias(struct rpc_pipe_client *cli,
1391                                       TALLOC_CTX *mem_ctx,
1392                                       int argc, const char **argv)
1393 {
1394         struct policy_handle connect_pol, domain_pol, alias_pol;
1395         NTSTATUS status, result;
1396         uint32 alias_rid;
1397         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1398         struct dcerpc_binding_handle *b = cli->binding_handle;
1399
1400         if (argc != 3) {
1401                 printf("Usage: %s builtin|domain [rid|name]\n", argv[0]);
1402                 return NT_STATUS_OK;
1403         }
1404
1405         alias_rid = strtoul(argv[2], NULL, 10);
1406
1407         /* Open SAMR handle */
1408
1409         status = rpccli_try_samr_connects(cli, mem_ctx,
1410                                           MAXIMUM_ALLOWED_ACCESS,
1411                                           &connect_pol);
1412         if (!NT_STATUS_IS_OK(status)) {
1413                 goto done;
1414         }
1415
1416         /* Open handle on domain */
1417
1418         status = get_domain_handle(cli, mem_ctx, argv[1],
1419                                    &connect_pol,
1420                                    MAXIMUM_ALLOWED_ACCESS,
1421                                    &domain_sid,
1422                                    &domain_pol);
1423         if (!NT_STATUS_IS_OK(status)) {
1424                 goto done;
1425         }
1426
1427         /* Open handle on alias */
1428
1429         status = dcerpc_samr_OpenAlias(b, mem_ctx,
1430                                        &domain_pol,
1431                                        access_mask,
1432                                        alias_rid,
1433                                        &alias_pol,
1434                                        &result);
1435         if (!NT_STATUS_IS_OK(status)) {
1436                 goto done;
1437         }
1438         if (!NT_STATUS_IS_OK(result) && (alias_rid == 0)) {
1439                 /* Probably this was a user name, try lookupnames */
1440                 struct samr_Ids rids, types;
1441                 struct lsa_String lsa_acct_name;
1442
1443                 init_lsa_String(&lsa_acct_name, argv[2]);
1444
1445                 status = dcerpc_samr_LookupNames(b, mem_ctx,
1446                                                  &domain_pol,
1447                                                  1,
1448                                                  &lsa_acct_name,
1449                                                  &rids,
1450                                                  &types,
1451                                                  &result);
1452                 if (!NT_STATUS_IS_OK(status)) {
1453                         goto done;
1454                 }
1455                 if (NT_STATUS_IS_OK(result)) {
1456                         status = dcerpc_samr_OpenAlias(b, mem_ctx,
1457                                                        &domain_pol,
1458                                                        access_mask,
1459                                                        rids.ids[0],
1460                                                        &alias_pol,
1461                                                        &result);
1462                         if (!NT_STATUS_IS_OK(status)) {
1463                                 goto done;
1464                         }
1465                 }
1466         }
1467
1468         status = dcerpc_samr_DeleteDomAlias(b, mem_ctx,
1469                                             &alias_pol,
1470                                             &result);
1471         if (!NT_STATUS_IS_OK(status)) {
1472                 goto done;
1473         }
1474         if (!NT_STATUS_IS_OK(result)) {
1475                 status = result;
1476                 goto done;
1477         }
1478
1479         dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1480         dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1481  done:
1482         return status;
1483 }
1484
1485 /* Query display info */
1486
1487 static NTSTATUS cmd_samr_query_dispinfo_internal(struct rpc_pipe_client *cli,
1488                                                  TALLOC_CTX *mem_ctx,
1489                                                  int argc, const char **argv,
1490                                                  uint32_t opcode)
1491 {
1492         struct policy_handle connect_pol, domain_pol;
1493         NTSTATUS status, result;
1494         uint32 start_idx=0, max_entries=250, max_size = 0xffff, num_entries = 0, i;
1495         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1496         uint32 info_level = 1;
1497         union samr_DispInfo info;
1498         int loop_count = 0;
1499         bool got_params = False; /* Use get_query_dispinfo_params() or not? */
1500         uint32_t total_size, returned_size;
1501         struct dcerpc_binding_handle *b = cli->binding_handle;
1502
1503         if (argc > 6) {
1504                 printf("Usage: %s [info level] [start index] [max entries] [max size] [access mask]\n", argv[0]);
1505                 return NT_STATUS_OK;
1506         }
1507
1508         if (argc >= 2)
1509                 sscanf(argv[1], "%i", &info_level);
1510
1511         if (argc >= 3)
1512                 sscanf(argv[2], "%i", &start_idx);
1513
1514         if (argc >= 4) {
1515                 sscanf(argv[3], "%i", &max_entries);
1516                 got_params = True;
1517         }
1518
1519         if (argc >= 5) {
1520                 sscanf(argv[4], "%i", &max_size);
1521                 got_params = True;
1522         }
1523
1524         if (argc >= 6)
1525                 sscanf(argv[5], "%x", &access_mask);
1526
1527         /* Get sam policy handle */
1528
1529         status = rpccli_try_samr_connects(cli, mem_ctx,
1530                                           MAXIMUM_ALLOWED_ACCESS,
1531                                           &connect_pol);
1532         if (!NT_STATUS_IS_OK(status)) {
1533                 goto done;
1534         }
1535
1536         /* Get domain policy handle */
1537
1538         status = dcerpc_samr_OpenDomain(b, mem_ctx,
1539                                         &connect_pol,
1540                                         access_mask,
1541                                         &domain_sid,
1542                                         &domain_pol,
1543                                         &result);
1544         if (!NT_STATUS_IS_OK(status)) {
1545                 goto done;
1546         }
1547         if (!NT_STATUS_IS_OK(result)) {
1548                 status = result;
1549                 goto done;
1550         }
1551
1552         /* Query display info */
1553
1554         do {
1555
1556                 if (!got_params)
1557                         dcerpc_get_query_dispinfo_params(
1558                                 loop_count, &max_entries, &max_size);
1559
1560                 switch (opcode) {
1561                 case NDR_SAMR_QUERYDISPLAYINFO:
1562                         status = dcerpc_samr_QueryDisplayInfo(b, mem_ctx,
1563                                                               &domain_pol,
1564                                                               info_level,
1565                                                               start_idx,
1566                                                               max_entries,
1567                                                               max_size,
1568                                                               &total_size,
1569                                                               &returned_size,
1570                                                               &info,
1571                                                               &result);
1572                         break;
1573                 case NDR_SAMR_QUERYDISPLAYINFO2:
1574                         status = dcerpc_samr_QueryDisplayInfo2(b, mem_ctx,
1575                                                                &domain_pol,
1576                                                                info_level,
1577                                                                start_idx,
1578                                                                max_entries,
1579                                                                max_size,
1580                                                                &total_size,
1581                                                                &returned_size,
1582                                                                &info,
1583                                                                &result);
1584
1585                         break;
1586                 case NDR_SAMR_QUERYDISPLAYINFO3:
1587                         status = dcerpc_samr_QueryDisplayInfo3(b, mem_ctx,
1588                                                                &domain_pol,
1589                                                                info_level,
1590                                                                start_idx,
1591                                                                max_entries,
1592                                                                max_size,
1593                                                                &total_size,
1594                                                                &returned_size,
1595                                                                &info,
1596                                                                &result);
1597
1598                         break;
1599                 default:
1600                         return NT_STATUS_INVALID_PARAMETER;
1601                 }
1602
1603                 if (!NT_STATUS_IS_OK(status)) {
1604                         break;
1605                 }
1606                 status = result;
1607                 if (!NT_STATUS_IS_OK(result) &&
1608                     !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) &&
1609                     !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
1610                         break;
1611                 }
1612
1613                 loop_count++;
1614
1615                 switch (info_level) {
1616                         case 1:
1617                                 num_entries = info.info1.count;
1618                                 break;
1619                         case 2:
1620                                 num_entries = info.info2.count;
1621                                 break;
1622                         case 3:
1623                                 num_entries = info.info3.count;
1624                                 break;
1625                         case 4:
1626                                 num_entries = info.info4.count;
1627                                 break;
1628                         case 5:
1629                                 num_entries = info.info5.count;
1630                                 break;
1631                         default:
1632                                 break;
1633                 }
1634
1635                 start_idx += num_entries;
1636
1637                 if (num_entries == 0)
1638                         break;
1639
1640                 for (i = 0; i < num_entries; i++) {
1641                         switch (info_level) {
1642                         case 1:
1643                                 display_sam_info_1(&info.info1.entries[i]);
1644                                 break;
1645                         case 2:
1646                                 display_sam_info_2(&info.info2.entries[i]);
1647                                 break;
1648                         case 3:
1649                                 display_sam_info_3(&info.info3.entries[i]);
1650                                 break;
1651                         case 4:
1652                                 display_sam_info_4(&info.info4.entries[i]);
1653                                 break;
1654                         case 5:
1655                                 display_sam_info_5(&info.info5.entries[i]);
1656                                 break;
1657                         }
1658                 }
1659         } while ( NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1660
1661         dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1662         dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1663  done:
1664         return status;
1665 }
1666
1667 static NTSTATUS cmd_samr_query_dispinfo(struct rpc_pipe_client *cli,
1668                                         TALLOC_CTX *mem_ctx,
1669                                         int argc, const char **argv)
1670 {
1671         return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1672                                                 NDR_SAMR_QUERYDISPLAYINFO);
1673 }
1674
1675 static NTSTATUS cmd_samr_query_dispinfo2(struct rpc_pipe_client *cli,
1676                                          TALLOC_CTX *mem_ctx,
1677                                          int argc, const char **argv)
1678 {
1679         return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1680                                                 NDR_SAMR_QUERYDISPLAYINFO2);
1681 }
1682
1683 static NTSTATUS cmd_samr_query_dispinfo3(struct rpc_pipe_client *cli,
1684                                          TALLOC_CTX *mem_ctx,
1685                                          int argc, const char **argv)
1686 {
1687         return cmd_samr_query_dispinfo_internal(cli, mem_ctx, argc, argv,
1688                                                 NDR_SAMR_QUERYDISPLAYINFO3);
1689 }
1690
1691 /* Query domain info */
1692
1693 static NTSTATUS cmd_samr_query_dominfo(struct rpc_pipe_client *cli,
1694                                        TALLOC_CTX *mem_ctx,
1695                                        int argc, const char **argv)
1696 {
1697         struct policy_handle connect_pol, domain_pol;
1698         NTSTATUS status, result;
1699         uint32 switch_level = 2;
1700         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1701         union samr_DomainInfo *info = NULL;
1702         struct dcerpc_binding_handle *b = cli->binding_handle;
1703
1704         if (argc > 3) {
1705                 printf("Usage: %s [info level] [access mask]\n", argv[0]);
1706                 return NT_STATUS_OK;
1707         }
1708
1709         if (argc > 1)
1710                 sscanf(argv[1], "%i", &switch_level);
1711
1712         if (argc > 2)
1713                 sscanf(argv[2], "%x", &access_mask);
1714
1715         /* Get sam policy handle */
1716
1717         status = rpccli_try_samr_connects(cli, mem_ctx,
1718                                           MAXIMUM_ALLOWED_ACCESS,
1719                                           &connect_pol);
1720         if (!NT_STATUS_IS_OK(status)) {
1721                 goto done;
1722         }
1723
1724         /* Get domain policy handle */
1725
1726         status = dcerpc_samr_OpenDomain(b, mem_ctx,
1727                                         &connect_pol,
1728                                         access_mask,
1729                                         &domain_sid,
1730                                         &domain_pol,
1731                                         &result);
1732         if (!NT_STATUS_IS_OK(status)) {
1733                 goto done;
1734         }
1735         if (!NT_STATUS_IS_OK(result)) {
1736                 status = result;
1737                 goto done;
1738         }
1739
1740         /* Query domain info */
1741
1742         status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
1743                                              &domain_pol,
1744                                              switch_level,
1745                                              &info,
1746                                              &result);
1747         if (!NT_STATUS_IS_OK(status)) {
1748                 goto done;
1749         }
1750         if (!NT_STATUS_IS_OK(result)) {
1751                 status = result;
1752                 goto done;
1753         }
1754
1755         /* Display domain info */
1756
1757         switch (switch_level) {
1758         case 1:
1759                 display_sam_dom_info_1(&info->info1);
1760                 break;
1761         case 2:
1762                 display_sam_dom_info_2(&info->general);
1763                 break;
1764         case 3:
1765                 display_sam_dom_info_3(&info->info3);
1766                 break;
1767         case 4:
1768                 display_sam_dom_info_4(&info->oem);
1769                 break;
1770         case 5:
1771                 display_sam_dom_info_5(&info->info5);
1772                 break;
1773         case 6:
1774                 display_sam_dom_info_6(&info->info6);
1775                 break;
1776         case 7:
1777                 display_sam_dom_info_7(&info->info7);
1778                 break;
1779         case 8:
1780                 display_sam_dom_info_8(&info->info8);
1781                 break;
1782         case 9:
1783                 display_sam_dom_info_9(&info->info9);
1784                 break;
1785         case 12:
1786                 display_sam_dom_info_12(&info->info12);
1787                 break;
1788         case 13:
1789                 display_sam_dom_info_13(&info->info13);
1790                 break;
1791
1792         default:
1793                 printf("cannot display domain info for switch value %d\n",
1794                        switch_level);
1795                 break;
1796         }
1797
1798  done:
1799
1800         dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1801         dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1802         return status;
1803 }
1804
1805 /* Create domain user */
1806
1807 static NTSTATUS cmd_samr_create_dom_user(struct rpc_pipe_client *cli,
1808                                          TALLOC_CTX *mem_ctx,
1809                                          int argc, const char **argv)
1810 {
1811         struct policy_handle connect_pol, domain_pol, user_pol;
1812         NTSTATUS status, result;
1813         struct lsa_String acct_name;
1814         uint32 acb_info;
1815         uint32 acct_flags, user_rid;
1816         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1817         uint32_t access_granted = 0;
1818         struct dcerpc_binding_handle *b = cli->binding_handle;
1819
1820         if ((argc < 2) || (argc > 3)) {
1821                 printf("Usage: %s username [access mask]\n", argv[0]);
1822                 return NT_STATUS_OK;
1823         }
1824
1825         init_lsa_String(&acct_name, argv[1]);
1826
1827         if (argc > 2)
1828                 sscanf(argv[2], "%x", &access_mask);
1829
1830         /* Get sam policy handle */
1831
1832         status = rpccli_try_samr_connects(cli, mem_ctx,
1833                                           MAXIMUM_ALLOWED_ACCESS,
1834                                           &connect_pol);
1835         if (!NT_STATUS_IS_OK(status)) {
1836                 goto done;
1837         }
1838
1839         /* Get domain policy handle */
1840
1841         status = dcerpc_samr_OpenDomain(b, mem_ctx,
1842                                         &connect_pol,
1843                                         access_mask,
1844                                         &domain_sid,
1845                                         &domain_pol,
1846                                         &result);
1847         if (!NT_STATUS_IS_OK(status)) {
1848                 goto done;
1849         }
1850         if (!NT_STATUS_IS_OK(result)) {
1851                 status = result;
1852                 goto done;
1853         }
1854
1855         /* Create domain user */
1856
1857         acb_info = ACB_NORMAL;
1858         acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
1859                      SEC_STD_WRITE_DAC | SEC_STD_DELETE |
1860                      SAMR_USER_ACCESS_SET_PASSWORD |
1861                      SAMR_USER_ACCESS_GET_ATTRIBUTES |
1862                      SAMR_USER_ACCESS_SET_ATTRIBUTES;
1863
1864         status = dcerpc_samr_CreateUser2(b, mem_ctx,
1865                                          &domain_pol,
1866                                          &acct_name,
1867                                          acb_info,
1868                                          acct_flags,
1869                                          &user_pol,
1870                                          &access_granted,
1871                                          &user_rid,
1872                                          &result);
1873         if (!NT_STATUS_IS_OK(status)) {
1874                 goto done;
1875         }
1876         if (!NT_STATUS_IS_OK(result)) {
1877                 status = result;
1878                 goto done;
1879         }
1880
1881         status = dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
1882         if (!NT_STATUS_IS_OK(status)) goto done;
1883
1884         status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1885         if (!NT_STATUS_IS_OK(status)) goto done;
1886
1887         status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1888         if (!NT_STATUS_IS_OK(status)) goto done;
1889
1890  done:
1891         return status;
1892 }
1893
1894 /* Create domain group */
1895
1896 static NTSTATUS cmd_samr_create_dom_group(struct rpc_pipe_client *cli,
1897                                           TALLOC_CTX *mem_ctx,
1898                                           int argc, const char **argv)
1899 {
1900         struct policy_handle connect_pol, domain_pol, group_pol;
1901         NTSTATUS status, result;
1902         struct lsa_String grp_name;
1903         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1904         uint32_t rid = 0;
1905         struct dcerpc_binding_handle *b = cli->binding_handle;
1906
1907         if ((argc < 2) || (argc > 3)) {
1908                 printf("Usage: %s groupname [access mask]\n", argv[0]);
1909                 return NT_STATUS_OK;
1910         }
1911
1912         init_lsa_String(&grp_name, argv[1]);
1913
1914         if (argc > 2)
1915                 sscanf(argv[2], "%x", &access_mask);
1916
1917         /* Get sam policy handle */
1918
1919         status = rpccli_try_samr_connects(cli, mem_ctx,
1920                                           MAXIMUM_ALLOWED_ACCESS,
1921                                           &connect_pol);
1922         if (!NT_STATUS_IS_OK(status)) {
1923                 goto done;
1924         }
1925
1926         /* Get domain policy handle */
1927
1928         status = dcerpc_samr_OpenDomain(b, mem_ctx,
1929                                         &connect_pol,
1930                                         access_mask,
1931                                         &domain_sid,
1932                                         &domain_pol,
1933                                         &result);
1934         if (!NT_STATUS_IS_OK(status)) {
1935                 goto done;
1936         }
1937         if (!NT_STATUS_IS_OK(result)) {
1938                 status = result;
1939                 goto done;
1940         }
1941
1942         /* Create domain user */
1943         status = dcerpc_samr_CreateDomainGroup(b, mem_ctx,
1944                                                &domain_pol,
1945                                                &grp_name,
1946                                                MAXIMUM_ALLOWED_ACCESS,
1947                                                &group_pol,
1948                                                &rid,
1949                                                &result);
1950         if (!NT_STATUS_IS_OK(status)) {
1951                 goto done;
1952         }
1953         if (!NT_STATUS_IS_OK(result)) {
1954                 status = result;
1955                 goto done;
1956         }
1957
1958         status = dcerpc_samr_Close(b, mem_ctx, &group_pol, &result);
1959         if (!NT_STATUS_IS_OK(status)) goto done;
1960
1961         status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1962         if (!NT_STATUS_IS_OK(status)) goto done;
1963
1964         status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1965         if (!NT_STATUS_IS_OK(status)) goto done;
1966
1967  done:
1968         return status;
1969 }
1970
1971 /* Create domain alias */
1972
1973 static NTSTATUS cmd_samr_create_dom_alias(struct rpc_pipe_client *cli,
1974                                           TALLOC_CTX *mem_ctx,
1975                                           int argc, const char **argv)
1976 {
1977         struct policy_handle connect_pol, domain_pol, alias_pol;
1978         NTSTATUS status, result;
1979         struct lsa_String alias_name;
1980         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
1981         uint32_t rid = 0;
1982         struct dcerpc_binding_handle *b = cli->binding_handle;
1983
1984         if ((argc < 2) || (argc > 3)) {
1985                 printf("Usage: %s aliasname [access mask]\n", argv[0]);
1986                 return NT_STATUS_OK;
1987         }
1988
1989         init_lsa_String(&alias_name, argv[1]);
1990
1991         if (argc > 2)
1992                 sscanf(argv[2], "%x", &access_mask);
1993
1994         /* Get sam policy handle */
1995
1996         status = rpccli_try_samr_connects(cli, mem_ctx,
1997                                           MAXIMUM_ALLOWED_ACCESS,
1998                                           &connect_pol);
1999         if (!NT_STATUS_IS_OK(status)) {
2000                 goto done;
2001         }
2002
2003         /* Get domain policy handle */
2004
2005         status = dcerpc_samr_OpenDomain(b, mem_ctx,
2006                                         &connect_pol,
2007                                         access_mask,
2008                                         &domain_sid,
2009                                         &domain_pol,
2010                                         &result);
2011         if (!NT_STATUS_IS_OK(status)) {
2012                 goto done;
2013         }
2014         if (!NT_STATUS_IS_OK(result)) {
2015                 status = result;
2016                 goto done;
2017         }
2018
2019         /* Create domain user */
2020
2021         status = dcerpc_samr_CreateDomAlias(b, mem_ctx,
2022                                             &domain_pol,
2023                                             &alias_name,
2024                                             MAXIMUM_ALLOWED_ACCESS,
2025                                             &alias_pol,
2026                                             &rid,
2027                                             &result);
2028         if (!NT_STATUS_IS_OK(status)) {
2029                 goto done;
2030         }
2031         if (!NT_STATUS_IS_OK(result)) {
2032                 status = result;
2033                 goto done;
2034         }
2035
2036
2037         status = dcerpc_samr_Close(b, mem_ctx, &alias_pol, &result);
2038         if (!NT_STATUS_IS_OK(status)) goto done;
2039
2040         status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2041         if (!NT_STATUS_IS_OK(status)) goto done;
2042
2043         status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2044         if (!NT_STATUS_IS_OK(status)) goto done;
2045
2046  done:
2047         return status;
2048 }
2049
2050 /* Lookup sam names */
2051
2052 static NTSTATUS cmd_samr_lookup_names(struct rpc_pipe_client *cli,
2053                                       TALLOC_CTX *mem_ctx,
2054                                       int argc, const char **argv)
2055 {
2056         NTSTATUS status, result;
2057         struct policy_handle connect_pol, domain_pol;
2058         uint32 num_names;
2059         struct samr_Ids rids, name_types;
2060         int i;
2061         struct lsa_String *names = NULL;
2062         struct dcerpc_binding_handle *b = cli->binding_handle;
2063
2064         if (argc < 3) {
2065                 printf("Usage: %s  domain|builtin name1 [name2 [name3] [...]]\n", argv[0]);
2066                 printf("check on the domain SID: S-1-5-21-x-y-z\n");
2067                 printf("or check on the builtin SID: S-1-5-32\n");
2068                 return NT_STATUS_OK;
2069         }
2070
2071         /* Get sam policy and domain handles */
2072
2073         status = rpccli_try_samr_connects(cli, mem_ctx,
2074                                           MAXIMUM_ALLOWED_ACCESS,
2075                                           &connect_pol);
2076         if (!NT_STATUS_IS_OK(status)) {
2077                 goto done;
2078         }
2079
2080         status = get_domain_handle(cli, mem_ctx, argv[1],
2081                                    &connect_pol,
2082                                    MAXIMUM_ALLOWED_ACCESS,
2083                                    &domain_sid,
2084                                    &domain_pol);
2085         if (!NT_STATUS_IS_OK(status)) {
2086                 goto done;
2087         }
2088
2089         /* Look up names */
2090
2091         num_names = argc - 2;
2092
2093         if ((names = talloc_array(mem_ctx, struct lsa_String, num_names)) == NULL) {
2094                 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2095                 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2096                 status = NT_STATUS_NO_MEMORY;
2097                 goto done;
2098         }
2099
2100         for (i = 0; i < num_names; i++) {
2101                 init_lsa_String(&names[i], argv[i + 2]);
2102         }
2103
2104         status = dcerpc_samr_LookupNames(b, mem_ctx,
2105                                          &domain_pol,
2106                                          num_names,
2107                                          names,
2108                                          &rids,
2109                                          &name_types,
2110                                          &result);
2111         if (!NT_STATUS_IS_OK(status)) {
2112                 goto done;
2113         }
2114         if (!NT_STATUS_IS_OK(result)) {
2115                 status = result;
2116                 goto done;
2117         }
2118
2119         /* Display results */
2120
2121         for (i = 0; i < num_names; i++)
2122                 printf("name %s: 0x%x (%d)\n", names[i].string, rids.ids[i],
2123                        name_types.ids[i]);
2124
2125         dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2126         dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2127  done:
2128         return status;
2129 }
2130
2131 /* Lookup sam rids */
2132
2133 static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli,
2134                                      TALLOC_CTX *mem_ctx,
2135                                      int argc, const char **argv)
2136 {
2137         NTSTATUS status, result;
2138         struct policy_handle connect_pol, domain_pol;
2139         uint32_t num_rids, *rids;
2140         struct lsa_Strings names;
2141         struct samr_Ids types;
2142         struct dcerpc_binding_handle *b = cli->binding_handle;
2143
2144         int i;
2145
2146         if (argc < 3) {
2147                 printf("Usage: %s domain|builtin rid1 [rid2 [rid3] [...]]\n", argv[0]);
2148                 return NT_STATUS_OK;
2149         }
2150
2151         /* Get sam policy and domain handles */
2152
2153         status = rpccli_try_samr_connects(cli, mem_ctx,
2154                                           MAXIMUM_ALLOWED_ACCESS,
2155                                           &connect_pol);
2156         if (!NT_STATUS_IS_OK(status)) {
2157                 goto done;
2158         }
2159
2160         status = get_domain_handle(cli, mem_ctx, argv[1],
2161                                    &connect_pol,
2162                                    MAXIMUM_ALLOWED_ACCESS,
2163                                    &domain_sid,
2164                                    &domain_pol);
2165         if (!NT_STATUS_IS_OK(status)) {
2166                 goto done;
2167         }
2168
2169         /* Look up rids */
2170
2171         num_rids = argc - 2;
2172
2173         if ((rids = talloc_array(mem_ctx, uint32, num_rids)) == NULL) {
2174                 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2175                 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2176                 status = NT_STATUS_NO_MEMORY;
2177                 goto done;
2178         }
2179
2180         for (i = 0; i < argc - 2; i++)
2181                 sscanf(argv[i + 2], "%i", &rids[i]);
2182
2183         status = dcerpc_samr_LookupRids(b, mem_ctx,
2184                                         &domain_pol,
2185                                         num_rids,
2186                                         rids,
2187                                         &names,
2188                                         &types,
2189                                         &result);
2190         if (!NT_STATUS_IS_OK(status)) {
2191                 goto done;
2192         }
2193         status = result;
2194         if (!NT_STATUS_IS_OK(result) &&
2195             !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
2196                 goto done;
2197
2198         /* Display results */
2199
2200         for (i = 0; i < num_rids; i++) {
2201                 printf("rid 0x%x: %s (%d)\n",
2202                         rids[i], names.names[i].string, types.ids[i]);
2203         }
2204
2205         dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2206         dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2207  done:
2208         return status;
2209 }
2210
2211 /* Delete domain group */
2212
2213 static NTSTATUS cmd_samr_delete_dom_group(struct rpc_pipe_client *cli,
2214                                          TALLOC_CTX *mem_ctx,
2215                                          int argc, const char **argv)
2216 {
2217         NTSTATUS status, result;
2218         struct policy_handle connect_pol, domain_pol, group_pol;
2219         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2220         struct dcerpc_binding_handle *b = cli->binding_handle;
2221
2222         if ((argc < 2) || (argc > 3)) {
2223                 printf("Usage: %s groupname\n", argv[0]);
2224                 return NT_STATUS_OK;
2225         }
2226
2227         if (argc > 2)
2228                 sscanf(argv[2], "%x", &access_mask);
2229
2230         /* Get sam policy and domain handles */
2231
2232         status = rpccli_try_samr_connects(cli, mem_ctx,
2233                                           MAXIMUM_ALLOWED_ACCESS,
2234                                           &connect_pol);
2235         if (!NT_STATUS_IS_OK(status)) {
2236                 goto done;
2237         }
2238
2239         status = dcerpc_samr_OpenDomain(b, mem_ctx,
2240                                         &connect_pol,
2241                                         MAXIMUM_ALLOWED_ACCESS,
2242                                         &domain_sid,
2243                                         &domain_pol,
2244                                         &result);
2245         if (!NT_STATUS_IS_OK(status)) {
2246                 goto done;
2247         }
2248         if (!NT_STATUS_IS_OK(result)) {
2249                 status = result;
2250                 goto done;
2251         }
2252
2253         /* Get handle on group */
2254
2255         {
2256                 struct samr_Ids group_rids, name_types;
2257                 struct lsa_String lsa_acct_name;
2258
2259                 init_lsa_String(&lsa_acct_name, argv[1]);
2260
2261                 status = dcerpc_samr_LookupNames(b, mem_ctx,
2262                                                  &domain_pol,
2263                                                  1,
2264                                                  &lsa_acct_name,
2265                                                  &group_rids,
2266                                                  &name_types,
2267                                                  &result);
2268                 if (!NT_STATUS_IS_OK(status)) {
2269                         goto done;
2270                 }
2271                 if (!NT_STATUS_IS_OK(result)) {
2272                         status = result;
2273                         goto done;
2274                 }
2275
2276                 status = dcerpc_samr_OpenGroup(b, mem_ctx,
2277                                                &domain_pol,
2278                                                access_mask,
2279                                                group_rids.ids[0],
2280                                                &group_pol,
2281                                                &result);
2282                 if (!NT_STATUS_IS_OK(status)) {
2283                         goto done;
2284                 }
2285                 if (!NT_STATUS_IS_OK(result)) {
2286                         status = result;
2287                         goto done;
2288                 }
2289         }
2290
2291         /* Delete group */
2292
2293         status = dcerpc_samr_DeleteDomainGroup(b, mem_ctx,
2294                                                &group_pol,
2295                                                &result);
2296         if (!NT_STATUS_IS_OK(status)) {
2297                 goto done;
2298         }
2299         if (!NT_STATUS_IS_OK(result)) {
2300                 status = result;
2301                 goto done;
2302         }
2303
2304         /* Display results */
2305
2306         dcerpc_samr_Close(b, mem_ctx, &group_pol, &result);
2307         dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2308         dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2309
2310  done:
2311         return status;
2312 }
2313
2314 /* Delete domain user */
2315
2316 static NTSTATUS cmd_samr_delete_dom_user(struct rpc_pipe_client *cli,
2317                                          TALLOC_CTX *mem_ctx,
2318                                          int argc, const char **argv)
2319 {
2320         NTSTATUS status, result;
2321         struct policy_handle connect_pol, domain_pol, user_pol;
2322         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2323         struct dcerpc_binding_handle *b = cli->binding_handle;
2324
2325         if ((argc < 2) || (argc > 3)) {
2326                 printf("Usage: %s username\n", argv[0]);
2327                 return NT_STATUS_OK;
2328         }
2329
2330         if (argc > 2)
2331                 sscanf(argv[2], "%x", &access_mask);
2332
2333         /* Get sam policy and domain handles */
2334
2335         status = rpccli_try_samr_connects(cli, mem_ctx,
2336                                           MAXIMUM_ALLOWED_ACCESS,
2337                                           &connect_pol);
2338         if (!NT_STATUS_IS_OK(status)) {
2339                 goto done;
2340         }
2341
2342         status = dcerpc_samr_OpenDomain(b, mem_ctx,
2343                                         &connect_pol,
2344                                         MAXIMUM_ALLOWED_ACCESS,
2345                                         &domain_sid,
2346                                         &domain_pol,
2347                                         &result);
2348         if (!NT_STATUS_IS_OK(status)) {
2349                 goto done;
2350         }
2351         if (!NT_STATUS_IS_OK(result)) {
2352                 status = result;
2353                 goto done;
2354         }
2355
2356         /* Get handle on user */
2357
2358         {
2359                 struct samr_Ids user_rids, name_types;
2360                 struct lsa_String lsa_acct_name;
2361
2362                 init_lsa_String(&lsa_acct_name, argv[1]);
2363
2364                 status = dcerpc_samr_LookupNames(b, mem_ctx,
2365                                                  &domain_pol,
2366                                                  1,
2367                                                  &lsa_acct_name,
2368                                                  &user_rids,
2369                                                  &name_types,
2370                                                  &result);
2371                 if (!NT_STATUS_IS_OK(status)) {
2372                         goto done;
2373                 }
2374                 if (!NT_STATUS_IS_OK(result)) {
2375                         status = result;
2376                         goto done;
2377                 }
2378
2379                 status = dcerpc_samr_OpenUser(b, mem_ctx,
2380                                               &domain_pol,
2381                                               access_mask,
2382                                               user_rids.ids[0],
2383                                               &user_pol,
2384                                               &result);
2385                 if (!NT_STATUS_IS_OK(status)) {
2386                         goto done;
2387                 }
2388                 if (!NT_STATUS_IS_OK(result)) {
2389                         status = result;
2390                         goto done;
2391                 }
2392         }
2393
2394         /* Delete user */
2395
2396         status = dcerpc_samr_DeleteUser(b, mem_ctx,
2397                                         &user_pol,
2398                                         &result);
2399         if (!NT_STATUS_IS_OK(status)) {
2400                 goto done;
2401         }
2402         if (!NT_STATUS_IS_OK(result)) {
2403                 status = result;
2404                 goto done;
2405         }
2406
2407         /* Display results */
2408
2409         dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
2410         dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2411         dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2412
2413  done:
2414         return status;
2415 }
2416
2417 /**********************************************************************
2418  * Query user security object
2419  */
2420 static NTSTATUS cmd_samr_query_sec_obj(struct rpc_pipe_client *cli,
2421                                     TALLOC_CTX *mem_ctx,
2422                                     int argc, const char **argv)
2423 {
2424         struct policy_handle connect_pol, domain_pol, user_pol, *pol;
2425         NTSTATUS status, result;
2426         uint32 sec_info = SECINFO_DACL;
2427         uint32 user_rid = 0;
2428         TALLOC_CTX *ctx = NULL;
2429         struct sec_desc_buf *sec_desc_buf=NULL;
2430         bool domain = False;
2431         struct dcerpc_binding_handle *b = cli->binding_handle;
2432
2433         ctx=talloc_init("cmd_samr_query_sec_obj");
2434
2435         if ((argc < 1) || (argc > 3)) {
2436                 printf("Usage: %s [rid|-d] [sec_info]\n", argv[0]);
2437                 printf("\tSpecify rid for security on user, -d for security on domain\n");
2438                 talloc_destroy(ctx);
2439                 return NT_STATUS_OK;
2440         }
2441
2442         if (argc > 1) {
2443                 if (strcmp(argv[1], "-d") == 0)
2444                         domain = True;
2445                 else
2446                         sscanf(argv[1], "%i", &user_rid);
2447         }
2448
2449         if (argc == 3) {
2450                 sec_info = atoi(argv[2]);
2451         }
2452
2453         status = rpccli_try_samr_connects(cli, mem_ctx,
2454                                           MAXIMUM_ALLOWED_ACCESS,
2455                                           &connect_pol);
2456         if (!NT_STATUS_IS_OK(status)) {
2457                 goto done;
2458         }
2459
2460         if (domain || user_rid) {
2461                 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2462                                                 &connect_pol,
2463                                                 MAXIMUM_ALLOWED_ACCESS,
2464                                                 &domain_sid,
2465                                                 &domain_pol,
2466                                                 &result);
2467                 if (!NT_STATUS_IS_OK(status)) {
2468                         goto done;
2469                 }
2470                 if (!NT_STATUS_IS_OK(result)) {
2471                         status = result;
2472                         goto done;
2473                 }
2474         }
2475
2476         if (user_rid) {
2477                 status = dcerpc_samr_OpenUser(b, mem_ctx,
2478                                               &domain_pol,
2479                                               MAXIMUM_ALLOWED_ACCESS,
2480                                               user_rid,
2481                                               &user_pol,
2482                                               &result);
2483                 if (!NT_STATUS_IS_OK(status)) {
2484                         goto done;
2485                 }
2486                 if (!NT_STATUS_IS_OK(result)) {
2487                         status = result;
2488                         goto done;
2489                 }
2490         }
2491
2492         /* Pick which query pol to use */
2493
2494         pol = &connect_pol;
2495
2496         if (domain)
2497                 pol = &domain_pol;
2498
2499         if (user_rid)
2500                 pol = &user_pol;
2501
2502         /* Query SAM security object */
2503
2504         status = dcerpc_samr_QuerySecurity(b, mem_ctx,
2505                                            pol,
2506                                            sec_info,
2507                                            &sec_desc_buf,
2508                                            &result);
2509         if (!NT_STATUS_IS_OK(status)) {
2510                 goto done;
2511         }
2512         if (!NT_STATUS_IS_OK(result)) {
2513                 status = result;
2514                 goto done;
2515         }
2516
2517         display_sec_desc(sec_desc_buf->sd);
2518
2519         dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
2520         dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2521         dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2522 done:
2523         talloc_destroy(ctx);
2524         return status;
2525 }
2526
2527 static NTSTATUS cmd_samr_get_usrdom_pwinfo(struct rpc_pipe_client *cli,
2528                                            TALLOC_CTX *mem_ctx,
2529                                            int argc, const char **argv)
2530 {
2531         NTSTATUS status, result;
2532         struct policy_handle connect_pol, domain_pol, user_pol;
2533         struct samr_PwInfo info;
2534         uint32_t rid;
2535         struct dcerpc_binding_handle *b = cli->binding_handle;
2536
2537         if (argc != 2) {
2538                 printf("Usage: %s rid\n", argv[0]);
2539                 return NT_STATUS_OK;
2540         }
2541
2542         sscanf(argv[1], "%i", &rid);
2543
2544         status = rpccli_try_samr_connects(cli, mem_ctx,
2545                                           MAXIMUM_ALLOWED_ACCESS,
2546                                           &connect_pol);
2547         if (!NT_STATUS_IS_OK(status)) {
2548                 goto done;
2549         }
2550
2551         status = dcerpc_samr_OpenDomain(b, mem_ctx,
2552                                         &connect_pol,
2553                                         MAXIMUM_ALLOWED_ACCESS,
2554                                         &domain_sid,
2555                                         &domain_pol,
2556                                         &result);
2557         if (!NT_STATUS_IS_OK(status)) {
2558                 goto done;
2559         }
2560         if (!NT_STATUS_IS_OK(result)) {
2561                 status = result;
2562                 goto done;
2563         }
2564
2565         status = dcerpc_samr_OpenUser(b, mem_ctx,
2566                                       &domain_pol,
2567                                       MAXIMUM_ALLOWED_ACCESS,
2568                                       rid,
2569                                       &user_pol,
2570                                       &result);
2571         if (!NT_STATUS_IS_OK(status)) {
2572                 goto done;
2573         }
2574         if (!NT_STATUS_IS_OK(result)) {
2575                 status = result;
2576                 goto done;
2577         }
2578
2579         status = dcerpc_samr_GetUserPwInfo(b, mem_ctx,
2580                                            &user_pol,
2581                                            &info,
2582                                            &result);
2583         if (!NT_STATUS_IS_OK(status)) {
2584                 goto done;
2585         }
2586         status = result;
2587         if (NT_STATUS_IS_OK(result)) {
2588                 printf("min_password_length: %d\n", info.min_password_length);
2589                 printf("%s\n",
2590                         NDR_PRINT_STRUCT_STRING(mem_ctx,
2591                                 samr_PasswordProperties, &info.password_properties));
2592         }
2593
2594  done:
2595         dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
2596         dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2597         dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2598
2599         return status;
2600 }
2601
2602 static NTSTATUS cmd_samr_get_dom_pwinfo(struct rpc_pipe_client *cli,
2603                                         TALLOC_CTX *mem_ctx,
2604                                         int argc, const char **argv)
2605 {
2606         NTSTATUS status, result;
2607         struct lsa_String domain_name;
2608         struct samr_PwInfo info;
2609         struct dcerpc_binding_handle *b = cli->binding_handle;
2610
2611         if (argc < 1 || argc > 3) {
2612                 printf("Usage: %s <domain>\n", argv[0]);
2613                 return NT_STATUS_OK;
2614         }
2615
2616         init_lsa_String(&domain_name, argv[1]);
2617
2618         status = dcerpc_samr_GetDomPwInfo(b, mem_ctx,
2619                                           &domain_name,
2620                                           &info,
2621                                           &result);
2622         if (!NT_STATUS_IS_OK(status)) {
2623                 return status;
2624         }
2625         if (NT_STATUS_IS_OK(result)) {
2626                 printf("min_password_length: %d\n", info.min_password_length);
2627                 display_password_properties(info.password_properties);
2628         }
2629
2630         return result;
2631 }
2632
2633 /* Look up domain name */
2634
2635 static NTSTATUS cmd_samr_lookup_domain(struct rpc_pipe_client *cli,
2636                                        TALLOC_CTX *mem_ctx,
2637                                        int argc, const char **argv)
2638 {
2639         struct policy_handle connect_pol, domain_pol;
2640         NTSTATUS status, result;
2641         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2642         fstring sid_string;
2643         struct lsa_String domain_name;
2644         struct dom_sid *sid = NULL;
2645         struct dcerpc_binding_handle *b = cli->binding_handle;
2646
2647         if (argc != 2) {
2648                 printf("Usage: %s domain_name\n", argv[0]);
2649                 return NT_STATUS_OK;
2650         }
2651
2652         init_lsa_String(&domain_name, argv[1]);
2653
2654         status = rpccli_try_samr_connects(cli, mem_ctx,
2655                                           access_mask,
2656                                           &connect_pol);
2657         if (!NT_STATUS_IS_OK(status)) {
2658                 goto done;
2659         }
2660
2661         status = dcerpc_samr_OpenDomain(b, mem_ctx,
2662                                         &connect_pol,
2663                                         access_mask,
2664                                         &domain_sid,
2665                                         &domain_pol,
2666                                         &result);
2667         if (!NT_STATUS_IS_OK(status)) {
2668                 goto done;
2669         }
2670         if (!NT_STATUS_IS_OK(result)) {
2671                 status = result;
2672                 goto done;
2673         }
2674
2675         status = dcerpc_samr_LookupDomain(b, mem_ctx,
2676                                           &connect_pol,
2677                                           &domain_name,
2678                                           &sid,
2679                                           &result);
2680         if (!NT_STATUS_IS_OK(status)) {
2681                 goto done;
2682         }
2683         if (!NT_STATUS_IS_OK(result)) {
2684                 status = result;
2685                 goto done;
2686         }
2687
2688         if (NT_STATUS_IS_OK(result)) {
2689                 sid_to_fstring(sid_string, sid);
2690                 printf("SAMR_LOOKUP_DOMAIN: Domain Name: %s Domain SID: %s\n",
2691                        argv[1], sid_string);
2692         }
2693
2694         dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2695         dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2696 done:
2697         return status;
2698 }
2699
2700 /* Change user password */
2701
2702 static NTSTATUS cmd_samr_chgpasswd(struct rpc_pipe_client *cli,
2703                                    TALLOC_CTX *mem_ctx,
2704                                    int argc, const char **argv)
2705 {
2706         struct policy_handle connect_pol;
2707         struct policy_handle domain_pol = { 0, };
2708         struct policy_handle user_pol = { 0, };
2709         NTSTATUS status, result;
2710         const char *user, *oldpass, *newpass;
2711         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2712         struct samr_Ids rids, types;
2713         struct lsa_String lsa_acct_name;
2714         struct dcerpc_binding_handle *b = cli->binding_handle;
2715
2716         if (argc < 3) {
2717                 printf("Usage: %s username oldpass newpass\n", argv[0]);
2718                 return NT_STATUS_INVALID_PARAMETER;
2719         }
2720
2721         user = argv[1];
2722         oldpass = argv[2];
2723         newpass = argv[3];
2724
2725         /* Get sam policy handle */
2726
2727         status = rpccli_try_samr_connects(cli, mem_ctx,
2728                                           MAXIMUM_ALLOWED_ACCESS,
2729                                           &connect_pol);
2730         if (!NT_STATUS_IS_OK(status)) {
2731                 goto done;
2732         }
2733
2734         /* Get domain policy handle */
2735
2736         status = dcerpc_samr_OpenDomain(b, mem_ctx,
2737                                         &connect_pol,
2738                                         access_mask,
2739                                         &domain_sid,
2740                                         &domain_pol,
2741                                         &result);
2742         if (!NT_STATUS_IS_OK(status)) {
2743                 goto done;
2744         }
2745         if (!NT_STATUS_IS_OK(result)) {
2746                 status = result;
2747                 goto done;
2748         }
2749
2750         init_lsa_String(&lsa_acct_name, user);
2751
2752         status = dcerpc_samr_LookupNames(b, mem_ctx,
2753                                          &domain_pol,
2754                                          1,
2755                                          &lsa_acct_name,
2756                                          &rids,
2757                                          &types,
2758                                          &result);
2759         if (!NT_STATUS_IS_OK(status)) {
2760                 goto done;
2761         }
2762         if (!NT_STATUS_IS_OK(result)) {
2763                 status = result;
2764                 goto done;
2765         }
2766
2767         status = dcerpc_samr_OpenUser(b, mem_ctx,
2768                                       &domain_pol,
2769                                       access_mask,
2770                                       rids.ids[0],
2771                                       &user_pol,
2772                                       &result);
2773         if (!NT_STATUS_IS_OK(status)) {
2774                 goto done;
2775         }
2776         if (!NT_STATUS_IS_OK(result)) {
2777                 status = result;
2778                 goto done;
2779         }
2780
2781         /* Change user password */
2782         status = rpccli_samr_chgpasswd_user(cli, mem_ctx,
2783                                             &user_pol,
2784                                             newpass,
2785                                             oldpass);
2786         if (!NT_STATUS_IS_OK(status)) {
2787                 goto done;
2788         }
2789
2790  done:
2791         if (is_valid_policy_hnd(&user_pol)) {
2792                 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
2793         }
2794         if (is_valid_policy_hnd(&domain_pol)) {
2795                 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2796         }
2797         if (is_valid_policy_hnd(&connect_pol)) {
2798                 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2799         }
2800
2801         return status;
2802 }
2803
2804
2805 /* Change user password */
2806
2807 static NTSTATUS cmd_samr_chgpasswd2(struct rpc_pipe_client *cli,
2808                                     TALLOC_CTX *mem_ctx,
2809                                     int argc, const char **argv)
2810 {
2811         struct policy_handle connect_pol, domain_pol;
2812         NTSTATUS status, result;
2813         const char *user, *oldpass, *newpass;
2814         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2815         struct dcerpc_binding_handle *b = cli->binding_handle;
2816
2817         if (argc < 3) {
2818                 printf("Usage: %s username oldpass newpass\n", argv[0]);
2819                 return NT_STATUS_INVALID_PARAMETER;
2820         }
2821
2822         user = argv[1];
2823         oldpass = argv[2];
2824         newpass = argv[3];
2825
2826         /* Get sam policy handle */
2827
2828         status = rpccli_try_samr_connects(cli, mem_ctx,
2829                                           MAXIMUM_ALLOWED_ACCESS,
2830                                           &connect_pol);
2831         if (!NT_STATUS_IS_OK(status)) {
2832                 goto done;
2833         }
2834
2835         /* Get domain policy handle */
2836
2837         status = dcerpc_samr_OpenDomain(b, mem_ctx,
2838                                         &connect_pol,
2839                                         access_mask,
2840                                         &domain_sid,
2841                                         &domain_pol,
2842                                         &result);
2843         if (!NT_STATUS_IS_OK(status)) {
2844                 goto done;
2845         }
2846         if (!NT_STATUS_IS_OK(result)) {
2847                 status = result;
2848                 goto done;
2849         }
2850
2851         /* Change user password */
2852         status = rpccli_samr_chgpasswd_user2(cli, mem_ctx, user, newpass, oldpass);
2853
2854         if (!NT_STATUS_IS_OK(status)) {
2855                 goto done;
2856         }
2857
2858         status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2859         if (!NT_STATUS_IS_OK(status)) goto done;
2860
2861         status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2862         if (!NT_STATUS_IS_OK(status)) goto done;
2863
2864  done:
2865         return status;
2866 }
2867
2868
2869 /* Change user password */
2870
2871 static NTSTATUS cmd_samr_chgpasswd3(struct rpc_pipe_client *cli,
2872                                     TALLOC_CTX *mem_ctx,
2873                                     int argc, const char **argv)
2874 {
2875         struct policy_handle connect_pol, domain_pol;
2876         NTSTATUS status, result;
2877         const char *user, *oldpass, *newpass;
2878         uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
2879         struct samr_DomInfo1 *info = NULL;
2880         struct userPwdChangeFailureInformation *reject = NULL;
2881         struct dcerpc_binding_handle *b = cli->binding_handle;
2882
2883         if (argc < 3) {
2884                 printf("Usage: %s username oldpass newpass\n", argv[0]);
2885                 return NT_STATUS_INVALID_PARAMETER;
2886         }
2887
2888         user = argv[1];
2889         oldpass = argv[2];
2890         newpass = argv[3];
2891
2892         /* Get sam policy handle */
2893
2894         status = rpccli_try_samr_connects(cli, mem_ctx,
2895                                           MAXIMUM_ALLOWED_ACCESS,
2896                                           &connect_pol);
2897         if (!NT_STATUS_IS_OK(status)) {
2898                 goto done;
2899         }
2900
2901         /* Get domain policy handle */
2902
2903         status = dcerpc_samr_OpenDomain(b, mem_ctx,
2904                                         &connect_pol,
2905                                         access_mask,
2906                                         &domain_sid,
2907                                         &domain_pol,
2908                                         &result);
2909         if (!NT_STATUS_IS_OK(status)) {
2910                 goto done;
2911         }
2912         if (!NT_STATUS_IS_OK(result)) {
2913                 status = result;
2914                 goto done;
2915         }
2916
2917         /* Change user password */
2918         status = rpccli_samr_chgpasswd_user3(cli, mem_ctx,
2919                                              user,
2920                                              newpass,
2921                                              oldpass,
2922                                              &info,
2923                                              &reject);
2924         if (!NT_STATUS_IS_OK(status)) {
2925                 goto done;
2926         }
2927
2928         if (NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_RESTRICTION)) {
2929
2930                 display_sam_dom_info_1(info);
2931
2932                 switch (reject->extendedFailureReason) {
2933                         case SAM_PWD_CHANGE_PASSWORD_TOO_SHORT:
2934                                 d_printf("SAM_PWD_CHANGE_PASSWORD_TOO_SHORT\n");
2935                                 break;
2936                         case SAM_PWD_CHANGE_PWD_IN_HISTORY:
2937                                 d_printf("SAM_PWD_CHANGE_PWD_IN_HISTORY\n");
2938                                 break;
2939                         case SAM_PWD_CHANGE_NOT_COMPLEX:
2940                                 d_printf("SAM_PWD_CHANGE_NOT_COMPLEX\n");
2941                                 break;
2942                         default:
2943                                 d_printf("unknown reject reason: %d\n",
2944                                         reject->extendedFailureReason);
2945                                 break;
2946                 }
2947         }
2948
2949         if (!NT_STATUS_IS_OK(result)) {
2950                 status = result;
2951                 goto done;
2952         }
2953
2954         status = dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2955         if (!NT_STATUS_IS_OK(status)) goto done;
2956
2957         status = dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2958         if (!NT_STATUS_IS_OK(status)) goto done;
2959
2960  done:
2961         return status;
2962 }
2963
2964 static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli,
2965                                          TALLOC_CTX *mem_ctx,
2966                                          int argc, const char **argv,
2967                                          int opcode)
2968 {
2969         struct policy_handle connect_pol, domain_pol, user_pol;
2970         NTSTATUS status, result;
2971         const char *user, *param;
2972         uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
2973         uint32_t level;
2974         uint32_t user_rid;
2975         union samr_UserInfo info;
2976         struct samr_CryptPassword pwd_buf;
2977         struct samr_CryptPasswordEx pwd_buf_ex;
2978         uint8_t nt_hash[16];
2979         uint8_t lm_hash[16];
2980         DATA_BLOB session_key;
2981         uint8_t password_expired = 0;
2982         struct dcerpc_binding_handle *b = cli->binding_handle;
2983
2984         if (argc < 4) {
2985                 printf("Usage: %s username level password [password_expired]\n",
2986                         argv[0]);
2987                 return NT_STATUS_INVALID_PARAMETER;
2988         }
2989
2990         user = argv[1];
2991         level = atoi(argv[2]);
2992         param = argv[3];
2993
2994         if (argc >= 5) {
2995                 password_expired = atoi(argv[4]);
2996         }
2997
2998         status = cli_get_session_key(mem_ctx, cli, &session_key);
2999         if (!NT_STATUS_IS_OK(status)) {
3000                 return status;
3001         }
3002
3003         init_samr_CryptPassword(param, &session_key, &pwd_buf);
3004         init_samr_CryptPasswordEx(param, &session_key, &pwd_buf_ex);
3005         nt_lm_owf_gen(param, nt_hash, lm_hash);
3006
3007         switch (level) {
3008         case 18:
3009                 {
3010                         DATA_BLOB in,out;
3011                         in = data_blob_const(nt_hash, 16);
3012                         out = data_blob_talloc_zero(mem_ctx, 16);
3013                         sess_crypt_blob(&out, &in, &session_key, true);
3014                         memcpy(nt_hash, out.data, out.length);
3015                 }
3016                 {
3017                         DATA_BLOB in,out;
3018                         in = data_blob_const(lm_hash, 16);
3019                         out = data_blob_talloc_zero(mem_ctx, 16);
3020                         sess_crypt_blob(&out, &in, &session_key, true);
3021                         memcpy(lm_hash, out.data, out.length);
3022                 }
3023
3024                 memcpy(info.info18.nt_pwd.hash, nt_hash, 16);
3025                 memcpy(info.info18.lm_pwd.hash, lm_hash, 16);
3026                 info.info18.nt_pwd_active       = true;
3027                 info.info18.lm_pwd_active       = true;
3028                 info.info18.password_expired    = password_expired;
3029
3030                 break;
3031         case 21:
3032                 ZERO_STRUCT(info.info21);
3033
3034                 info.info21.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT |
3035                                              SAMR_FIELD_LM_PASSWORD_PRESENT;
3036                 if (argc >= 5) {
3037                         info.info21.fields_present |= SAMR_FIELD_EXPIRED_FLAG;
3038                         info.info21.password_expired = password_expired;
3039                 }
3040
3041                 info.info21.lm_password_set = true;
3042                 info.info21.lm_owf_password.length = 16;
3043                 info.info21.lm_owf_password.size = 16;
3044
3045                 info.info21.nt_password_set = true;
3046                 info.info21.nt_owf_password.length = 16;
3047                 info.info21.nt_owf_password.size = 16;
3048
3049                 {
3050                         DATA_BLOB in,out;
3051                         in = data_blob_const(nt_hash, 16);
3052                         out = data_blob_talloc_zero(mem_ctx, 16);
3053                         sess_crypt_blob(&out, &in, &session_key, true);
3054                         info.info21.nt_owf_password.array =
3055                                 (uint16_t *)talloc_memdup(mem_ctx, out.data, 16);
3056                 }
3057                 {
3058                         DATA_BLOB in,out;
3059                         in = data_blob_const(lm_hash, 16);
3060                         out = data_blob_talloc_zero(mem_ctx, 16);
3061                         sess_crypt_blob(&out, &in, &session_key, true);
3062                         info.info21.lm_owf_password.array =
3063                                 (uint16_t *)talloc_memdup(mem_ctx, out.data, 16);
3064                 }
3065
3066                 break;
3067         case 23:
3068                 ZERO_STRUCT(info.info23);
3069
3070                 info.info23.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT |
3071                                                   SAMR_FIELD_LM_PASSWORD_PRESENT;
3072                 if (argc >= 5) {
3073                         info.info23.info.fields_present |= SAMR_FIELD_EXPIRED_FLAG;
3074                         info.info23.info.password_expired = password_expired;
3075                 }
3076
3077                 info.info23.password = pwd_buf;
3078
3079                 break;
3080         case 24:
3081                 info.info24.password            = pwd_buf;
3082                 info.info24.password_expired    = password_expired;
3083
3084                 break;
3085         case 25:
3086                 ZERO_STRUCT(info.info25);
3087
3088                 info.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT |
3089                                                   SAMR_FIELD_LM_PASSWORD_PRESENT;
3090                 if (argc >= 5) {
3091                         info.info25.info.fields_present |= SAMR_FIELD_EXPIRED_FLAG;
3092                         info.info25.info.password_expired = password_expired;
3093                 }
3094
3095                 info.info25.password = pwd_buf_ex;
3096
3097                 break;
3098         case 26:
3099                 info.info26.password            = pwd_buf_ex;
3100                 info.info26.password_expired    = password_expired;
3101
3102                 break;
3103         default:
3104                 return NT_STATUS_INVALID_INFO_CLASS;
3105         }
3106
3107         /* Get sam policy handle */
3108
3109         status = rpccli_try_samr_connects(cli, mem_ctx,
3110                                           MAXIMUM_ALLOWED_ACCESS,
3111                                           &connect_pol);
3112         if (!NT_STATUS_IS_OK(status)) {
3113                 goto done;
3114         }
3115
3116         /* Get domain policy handle */
3117
3118         status = dcerpc_samr_OpenDomain(b, mem_ctx,
3119                                         &connect_pol,
3120                                         access_mask,
3121                                         &domain_sid,
3122                                         &domain_pol,
3123                                         &result);
3124
3125         if (!NT_STATUS_IS_OK(status))
3126                 goto done;
3127         if (!NT_STATUS_IS_OK(result)) {
3128                 status = result;
3129                 goto done;
3130         }
3131
3132         user_rid = strtol(user, NULL, 0);
3133         if (user_rid) {
3134                 status = dcerpc_samr_OpenUser(b, mem_ctx,
3135                                               &domain_pol,
3136                                               access_mask,
3137                                               user_rid,
3138                                               &user_pol,
3139                                               &result);
3140                 if (!NT_STATUS_IS_OK(status)) {
3141                         goto done;
3142                 }
3143
3144                 status = result;
3145         }
3146
3147         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER) ||
3148             (user_rid == 0)) {
3149
3150                 /* Probably this was a user name, try lookupnames */
3151                 struct samr_Ids rids, types;
3152                 struct lsa_String lsa_acct_name;
3153
3154                 init_lsa_String(&lsa_acct_name, user);
3155
3156                 status = dcerpc_samr_LookupNames(b, mem_ctx,
3157                                                  &domain_pol,
3158                                                  1,
3159                                                  &lsa_acct_name,
3160                                                  &rids,
3161                                                  &types,
3162                                                  &result);
3163                 if (!NT_STATUS_IS_OK(status)) {
3164                         return status;
3165                 }
3166                 if (!NT_STATUS_IS_OK(result)) {
3167                         return result;
3168                 }
3169
3170
3171                 status = dcerpc_samr_OpenUser(b, mem_ctx,
3172                                               &domain_pol,
3173                                               access_mask,
3174                                               rids.ids[0],
3175                                               &user_pol,
3176                                               &result);
3177                 if (!NT_STATUS_IS_OK(status)) {
3178                         return status;
3179                 }
3180                 if (!NT_STATUS_IS_OK(result)) {
3181                         return result;
3182                 }
3183         }
3184
3185         switch (opcode) {
3186         case NDR_SAMR_SETUSERINFO:
3187                 status = dcerpc_samr_SetUserInfo(b, mem_ctx,
3188                                                  &user_pol,
3189                                                  level,
3190                                                  &info,
3191                                                  &result);
3192                 break;
3193         case NDR_SAMR_SETUSERINFO2:
3194                 status = dcerpc_samr_SetUserInfo2(b, mem_ctx,
3195                                                   &user_pol,
3196                                                   level,
3197                                                   &info,
3198                                                   &result);
3199                 break;
3200         default:
3201                 return NT_STATUS_INVALID_PARAMETER;
3202         }
3203         if (!NT_STATUS_IS_OK(status)) {
3204                 DEBUG(0,("status: %s\n", nt_errstr(status)));
3205                 goto done;
3206         }
3207         if (!NT_STATUS_IS_OK(result)) {
3208                 status = result;
3209                 DEBUG(0,("result: %s\n", nt_errstr(status)));
3210                 goto done;
3211         }
3212  done:
3213         return status;
3214 }
3215
3216 static NTSTATUS cmd_samr_setuserinfo(struct rpc_pipe_client *cli,
3217                                      TALLOC_CTX *mem_ctx,
3218                                      int argc, const char **argv)
3219 {
3220         return cmd_samr_setuserinfo_int(cli, mem_ctx, argc, argv,
3221                                         NDR_SAMR_SETUSERINFO);
3222 }
3223
3224 static NTSTATUS cmd_samr_setuserinfo2(struct rpc_pipe_client *cli,
3225                                       TALLOC_CTX *mem_ctx,
3226                                       int argc, const char **argv)
3227 {
3228         return cmd_samr_setuserinfo_int(cli, mem_ctx, argc, argv,
3229                                         NDR_SAMR_SETUSERINFO2);
3230 }
3231
3232 static NTSTATUS cmd_samr_get_dispinfo_idx(struct rpc_pipe_client *cli,
3233                                           TALLOC_CTX *mem_ctx,
3234                                           int argc, const char **argv)
3235 {
3236         NTSTATUS status, result;
3237         struct policy_handle connect_handle;
3238         struct policy_handle domain_handle = { 0, };
3239         uint16_t level = 1;
3240         struct lsa_String name;
3241         uint32_t idx = 0;
3242         struct dcerpc_binding_handle *b = cli->binding_handle;
3243
3244         if (argc < 2 || argc > 3) {
3245                 printf("Usage: %s name level\n", argv[0]);
3246                 return NT_STATUS_INVALID_PARAMETER;
3247         }
3248
3249         init_lsa_String(&name, argv[1]);
3250
3251         if (argc == 3) {
3252                 level = atoi(argv[2]);
3253         }
3254
3255         status = rpccli_try_samr_connects(cli, mem_ctx,
3256                                           SEC_FLAG_MAXIMUM_ALLOWED,
3257                                           &connect_handle);
3258         if (!NT_STATUS_IS_OK(status)) {
3259                 goto done;
3260         }
3261
3262         status = dcerpc_samr_OpenDomain(b, mem_ctx,
3263                                         &connect_handle,
3264                                         SEC_FLAG_MAXIMUM_ALLOWED,
3265                                         &domain_sid,
3266                                         &domain_handle,
3267                                         &result);
3268         if (!NT_STATUS_IS_OK(status)) {
3269                 goto done;
3270         }
3271         if (!NT_STATUS_IS_OK(result)) {
3272                 status = result;
3273                 goto done;
3274         }
3275
3276         status = dcerpc_samr_GetDisplayEnumerationIndex(b, mem_ctx,
3277                                                         &domain_handle,
3278                                                         level,
3279                                                         &name,
3280                                                         &idx,
3281                                                         &result);
3282         if (!NT_STATUS_IS_OK(status)) {
3283                 goto done;
3284         }
3285
3286         status = result;
3287
3288         if (NT_STATUS_IS_OK(status) ||
3289             NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
3290                 printf("idx: %d (0x%08x)\n", idx, idx);
3291         }
3292  done:
3293
3294         if (is_valid_policy_hnd(&domain_handle)) {
3295                 dcerpc_samr_Close(b, mem_ctx, &domain_handle, &result);
3296         }
3297         if (is_valid_policy_hnd(&connect_handle)) {
3298                 dcerpc_samr_Close(b, mem_ctx, &connect_handle, &result);
3299         }
3300
3301         return status;
3302
3303 }
3304 /* List of commands exported by this module */
3305
3306 struct cmd_set samr_commands[] = {
3307
3308         { "SAMR" },
3309
3310         { "queryuser",  RPC_RTYPE_NTSTATUS, cmd_samr_query_user,                NULL, &ndr_table_samr, NULL,    "Query user info",         "" },
3311         { "querygroup",         RPC_RTYPE_NTSTATUS, cmd_samr_query_group,               NULL, &ndr_table_samr, NULL,    "Query group info",        "" },
3312         { "queryusergroups",    RPC_RTYPE_NTSTATUS, cmd_samr_query_usergroups,  NULL, &ndr_table_samr, NULL,    "Query user groups",       "" },
3313         { "queryuseraliases",   RPC_RTYPE_NTSTATUS, cmd_samr_query_useraliases,         NULL, &ndr_table_samr, NULL,    "Query user aliases",      "" },
3314         { "querygroupmem",      RPC_RTYPE_NTSTATUS, cmd_samr_query_groupmem,    NULL, &ndr_table_samr, NULL,    "Query group membership",  "" },
3315         { "queryaliasmem",      RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasmem,    NULL, &ndr_table_samr, NULL,    "Query alias membership",  "" },
3316         { "queryaliasinfo",     RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasinfo,   NULL, &ndr_table_samr, NULL,    "Query alias info",       "" },
3317         { "deletealias",        RPC_RTYPE_NTSTATUS, cmd_samr_delete_alias,      NULL, &ndr_table_samr, NULL,    "Delete an alias",  "" },
3318         { "querydispinfo",      RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo,    NULL, &ndr_table_samr, NULL,    "Query display info",      "" },
3319         { "querydispinfo2",     RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo2,   NULL, &ndr_table_samr, NULL,    "Query display info",      "" },
3320         { "querydispinfo3",     RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo3,   NULL, &ndr_table_samr, NULL,    "Query display info",      "" },
3321         { "querydominfo",       RPC_RTYPE_NTSTATUS, cmd_samr_query_dominfo,     NULL, &ndr_table_samr, NULL,    "Query domain info",       "" },
3322         { "enumdomusers",       RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_users,       NULL, &ndr_table_samr, NULL, "Enumerate domain users", "" },
3323         { "enumdomgroups",      RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_groups,       NULL, &ndr_table_samr, NULL,        "Enumerate domain groups", "" },
3324         { "enumalsgroups",      RPC_RTYPE_NTSTATUS, cmd_samr_enum_als_groups,       NULL, &ndr_table_samr, NULL,        "Enumerate alias groups",  "" },
3325         { "enumdomains",        RPC_RTYPE_NTSTATUS, cmd_samr_enum_domains,          NULL, &ndr_table_samr, NULL,        "Enumerate domains",  "" },
3326
3327         { "createdomuser",      RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_user,       NULL, &ndr_table_samr, NULL,        "Create domain user",      "" },
3328         { "createdomgroup",     RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_group,      NULL, &ndr_table_samr, NULL,        "Create domain group",     "" },
3329         { "createdomalias",     RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_alias,      NULL, &ndr_table_samr, NULL,        "Create domain alias",     "" },
3330         { "samlookupnames",     RPC_RTYPE_NTSTATUS, cmd_samr_lookup_names,          NULL, &ndr_table_samr, NULL,        "Look up names",           "" },
3331         { "samlookuprids",      RPC_RTYPE_NTSTATUS, cmd_samr_lookup_rids,           NULL, &ndr_table_samr, NULL,        "Look up names",           "" },
3332         { "deletedomgroup",     RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_group,      NULL, &ndr_table_samr, NULL,        "Delete domain group",     "" },
3333         { "deletedomuser",      RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_user,       NULL, &ndr_table_samr, NULL,        "Delete domain user",      "" },
3334         { "samquerysecobj",     RPC_RTYPE_NTSTATUS, cmd_samr_query_sec_obj,         NULL, &ndr_table_samr, NULL, "Query SAMR security object",   "" },
3335         { "getdompwinfo",       RPC_RTYPE_NTSTATUS, cmd_samr_get_dom_pwinfo,        NULL, &ndr_table_samr, NULL, "Retrieve domain password info", "" },
3336         { "getusrdompwinfo",    RPC_RTYPE_NTSTATUS, cmd_samr_get_usrdom_pwinfo,     NULL, &ndr_table_samr, NULL, "Retrieve user domain password info", "" },
3337
3338         { "lookupdomain",       RPC_RTYPE_NTSTATUS, cmd_samr_lookup_domain,         NULL, &ndr_table_samr, NULL, "Lookup Domain Name", "" },
3339         { "chgpasswd",          RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd,             NULL, &ndr_table_samr, NULL, "Change user password", "" },
3340         { "chgpasswd2",         RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd2,            NULL, &ndr_table_samr, NULL, "Change user password", "" },
3341         { "chgpasswd3",         RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd3,            NULL, &ndr_table_samr, NULL, "Change user password", "" },
3342         { "getdispinfoidx",     RPC_RTYPE_NTSTATUS, cmd_samr_get_dispinfo_idx,      NULL, &ndr_table_samr, NULL, "Get Display Information Index", "" },
3343         { "setuserinfo",        RPC_RTYPE_NTSTATUS, cmd_samr_setuserinfo,           NULL, &ndr_table_samr, NULL, "Set user info", "" },
3344         { "setuserinfo2",       RPC_RTYPE_NTSTATUS, cmd_samr_setuserinfo2,          NULL, &ndr_table_samr, NULL, "Set user info2", "" },
3345         { NULL }
3346 };