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