- lib/unix_sec_ctxt.c
[samba.git] / source / rpcclient / cmd_samr.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    NT Domain Authentication SMB / MSRPC client
5    Copyright (C) Andrew Tridgell 1994-1997
6    Copyright (C) Luke Kenneth Casson Leighton 1996-1997
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23
24
25 #ifdef SYSLOG
26 #undef SYSLOG
27 #endif
28
29 #include "includes.h"
30 #include "nterr.h"
31
32 extern int DEBUGLEVEL;
33
34 #define DEBUG_TESTING
35
36 extern struct cli_state *smb_cli;
37
38 extern FILE* out_hnd;
39
40
41 /****************************************************************************
42 SAM password change
43 ****************************************************************************/
44 void cmd_sam_ntchange_pwd(struct client_info *info)
45 {
46         fstring srv_name;
47         fstring domain;
48         fstring sid;
49         char *new_passwd;
50         BOOL res = True;
51         char nt_newpass[516];
52         uchar nt_hshhash[16];
53         uchar nt_newhash[16];
54         uchar nt_oldhash[16];
55         char lm_newpass[516];
56         uchar lm_newhash[16];
57         uchar lm_hshhash[16];
58         uchar lm_oldhash[16];
59
60         sid_to_string(sid, &info->dom.level5_sid);
61         fstrcpy(domain, info->dom.level5_dom);
62
63         fstrcpy(srv_name, "\\\\");
64         fstrcat(srv_name, info->dest_host);
65         strupper(srv_name);
66
67         fprintf(out_hnd, "SAM NT Password Change\n");
68
69 #if 0
70         struct pwd_info new_pwd;
71         pwd_read(&new_pwd, "New Password (ONCE: this is test code!):", True);
72 #endif
73         new_passwd = (char*)getpass("New Password (ONCE ONLY - get it right :-)");
74
75         nt_lm_owf_gen(new_passwd, lm_newhash, nt_newhash);
76         pwd_get_lm_nt_16(&(smb_cli->pwd), lm_oldhash, nt_oldhash );
77         make_oem_passwd_hash(nt_newpass, new_passwd, nt_oldhash, True);
78         make_oem_passwd_hash(lm_newpass, new_passwd, lm_oldhash, True);
79         E_old_pw_hash(lm_newhash, lm_oldhash, lm_hshhash);
80         E_old_pw_hash(lm_newhash, nt_oldhash, nt_hshhash);
81
82         cli_nt_set_ntlmssp_flgs(smb_cli,
83                                     NTLMSSP_NEGOTIATE_UNICODE |
84                                     NTLMSSP_NEGOTIATE_OEM |
85                                     NTLMSSP_NEGOTIATE_SIGN |
86                                     NTLMSSP_NEGOTIATE_SEAL |
87                                     NTLMSSP_NEGOTIATE_LM_KEY |
88                                     NTLMSSP_NEGOTIATE_NTLM |
89                                     NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
90                                     NTLMSSP_NEGOTIATE_00001000 |
91                                     NTLMSSP_NEGOTIATE_00002000);
92
93         /* open SAMR session.  */
94         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
95
96         /* establish a connection. */
97         res = res ? samr_unknown_38(smb_cli, srv_name) : False;
98
99         /* establish a connection. */
100         res = res ? samr_chgpasswd_user(smb_cli,
101                                            srv_name, smb_cli->user_name,
102                                            nt_newpass, nt_hshhash,
103                                            lm_newpass, lm_hshhash) : False;
104         /* close the session */
105         cli_nt_session_close(smb_cli);
106
107         if (res)
108         {
109                 fprintf(out_hnd, "NT Password changed OK\n");
110         }
111         else
112         {
113                 fprintf(out_hnd, "NT Password change FAILED\n");
114         }
115 }
116
117
118 /****************************************************************************
119 experimental SAM encryted rpc test connection
120 ****************************************************************************/
121 void cmd_sam_test(struct client_info *info)
122 {
123         fstring srv_name;
124         fstring domain;
125         fstring sid;
126         BOOL res = True;
127
128         sid_to_string(sid, &info->dom.level5_sid);
129         fstrcpy(domain, info->dom.level5_dom);
130
131 /*
132         if (strlen(sid) == 0)
133         {
134                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
135                 return;
136         }
137 */
138         fstrcpy(srv_name, "\\\\");
139         fstrcat(srv_name, info->dest_host);
140         strupper(srv_name);
141
142         fprintf(out_hnd, "SAM Encryption Test\n");
143
144         cli_nt_set_ntlmssp_flgs(smb_cli,
145                                     NTLMSSP_NEGOTIATE_UNICODE |
146                                     NTLMSSP_NEGOTIATE_OEM |
147                                     NTLMSSP_NEGOTIATE_SIGN |
148                                     NTLMSSP_NEGOTIATE_SEAL |
149                                     NTLMSSP_NEGOTIATE_LM_KEY |
150                                     NTLMSSP_NEGOTIATE_NTLM |
151                                     NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
152                                     NTLMSSP_NEGOTIATE_00001000 |
153                                     NTLMSSP_NEGOTIATE_00002000);
154
155         /* open SAMR session.  */
156         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
157
158         /* establish a connection. */
159         res = res ? samr_unknown_38(smb_cli, srv_name) : False;
160
161         /* close the session */
162         cli_nt_session_close(smb_cli);
163
164         if (res)
165         {
166                 DEBUG(5,("cmd_sam_test: succeeded\n"));
167         }
168         else
169         {
170                 DEBUG(5,("cmd_sam_test: failed\n"));
171         }
172 }
173
174 /****************************************************************************
175 SAM delete alias member.
176 ****************************************************************************/
177 void cmd_sam_del_aliasmem(struct client_info *info)
178 {
179         fstring srv_name;
180         fstring domain;
181         fstring tmp;
182         fstring sid;
183         DOM_SID sid1;
184         POLICY_HND alias_pol;
185         BOOL res = True;
186         BOOL res1 = True;
187         BOOL res2 = True;
188         uint32 flags = 0x200003f3; /* absolutely no idea. */
189         DOM_SID member_sid; 
190         uint32 alias_rid;
191
192         sid_copy(&sid1, &info->dom.level5_sid);
193         sid_to_string(sid, &sid1);
194         fstrcpy(domain, info->dom.level5_dom);
195
196         if (sid1.num_auths == 0)
197         {
198                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
199                 return;
200         }
201
202         fstrcpy(srv_name, "\\\\");
203         fstrcat(srv_name, info->dest_host);
204         strupper(srv_name);
205
206         if (!next_token(NULL, tmp, NULL, sizeof(tmp)))
207         {
208                 fprintf(out_hnd, "delaliasmem: <alias rid> [member sid1] [member sid2] ...\n");
209                 return;
210         }
211         alias_rid = get_number(tmp);
212
213         fprintf(out_hnd, "SAM Domain Alias Member\n");
214
215         /* open SAMR session.  negotiate credentials */
216         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
217
218         /* establish a connection. */
219         res = res ? samr_connect(smb_cli, 
220                                 srv_name, 0x00000020,
221                                 &info->dom.samr_pol_connect) : False;
222
223         /* connect to the domain */
224         res = res ? samr_open_domain(smb_cli, 
225                     &info->dom.samr_pol_connect, flags, &sid1,
226                     &info->dom.samr_pol_open_domain) : False;
227
228         /* connect to the domain */
229         res1 = res ? samr_open_alias(smb_cli,
230                     &info->dom.samr_pol_open_domain,
231                     0x000f001f, alias_rid, &alias_pol) : False;
232
233         while (next_token(NULL, tmp, NULL, sizeof(tmp)) && res2 && res1)
234         {
235                 /* get a sid, delete a member from the alias */
236                 res2 = res2 ? string_to_sid(&member_sid, tmp) : False;
237                 res2 = res2 ? samr_del_aliasmem(smb_cli, &alias_pol, &member_sid) : False;
238
239                 if (res2)
240                 {
241                         fprintf(out_hnd, "SID deleted from Alias 0x%x: %s\n", alias_rid, tmp);
242                 }
243         }
244
245         res1 = res1 ? samr_close(smb_cli, &alias_pol) : False;
246         res  = res  ? samr_close(smb_cli, &info->dom.samr_pol_open_domain) : False;
247         res  = res  ? samr_close(smb_cli, &info->dom.samr_pol_connect) : False;
248
249         /* close the session */
250         cli_nt_session_close(smb_cli);
251
252         if (res && res1 && res2)
253         {
254                 DEBUG(5,("cmd_sam_del_aliasmem: succeeded\n"));
255                 fprintf(out_hnd, "Delete Domain Alias Member: OK\n");
256         }
257         else
258         {
259                 DEBUG(5,("cmd_sam_del_aliasmem: failed\n"));
260                 fprintf(out_hnd, "Delete Domain Alias Member: FAILED\n");
261         }
262 }
263
264 /****************************************************************************
265 SAM delete alias.
266 ****************************************************************************/
267 void cmd_sam_delete_dom_alias(struct client_info *info)
268 {
269         fstring srv_name;
270         fstring domain;
271         fstring name;
272         fstring sid;
273         DOM_SID sid1;
274         POLICY_HND alias_pol;
275         BOOL res = True;
276         BOOL res1 = True;
277         BOOL res2 = True;
278         uint32 flags = 0x200003f3; /* absolutely no idea. */
279         uint32 alias_rid = 0;
280         const char *names[1];
281         uint32 rid [MAX_LOOKUP_SIDS];
282         uint32 type[MAX_LOOKUP_SIDS];
283         uint32 num_rids;
284
285         sid_copy(&sid1, &info->dom.level5_sid);
286         sid_to_string(sid, &sid1);
287         fstrcpy(domain, info->dom.level5_dom);
288
289         if (sid1.num_auths == 0)
290         {
291                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
292                 return;
293         }
294
295         fstrcpy(srv_name, "\\\\");
296         fstrcat(srv_name, info->dest_host);
297         strupper(srv_name);
298
299         if (!next_token(NULL, name, NULL, sizeof(name)))
300         {
301                 fprintf(out_hnd, "delalias <alias name>\n");
302                 return;
303         }
304
305         fprintf(out_hnd, "SAM Delete Domain Alias\n");
306
307         /* open SAMR session.  negotiate credentials */
308         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
309
310         /* establish a connection. */
311         res = res ? samr_connect(smb_cli, 
312                                 srv_name, 0x00000020,
313                                 &info->dom.samr_pol_connect) : False;
314
315         /* connect to the domain */
316         res = res ? samr_open_domain(smb_cli, 
317                     &info->dom.samr_pol_connect, flags, &sid1,
318                     &info->dom.samr_pol_open_domain) : False;
319
320         names[0] = name;
321
322         res1 = res ? samr_query_lookup_names(smb_cli,
323                     &info->dom.samr_pol_open_domain, 0x000003e8,
324                     1, names,
325                     &num_rids, rid, type) : False;
326
327         if (res1 && num_rids == 1)
328         {
329                 alias_rid = rid[0];
330         }
331
332         /* connect to the domain */
333         res1 = res1 ? samr_open_alias(smb_cli,
334                     &info->dom.samr_pol_open_domain,
335                     0x000f001f, alias_rid, &alias_pol) : False;
336
337         res2 = res1 ? samr_delete_dom_alias(smb_cli, &alias_pol) : False;
338
339         res1 = res1 ? samr_close(smb_cli, &alias_pol) : False;
340         res  = res  ? samr_close(smb_cli, &info->dom.samr_pol_open_domain) : False;
341         res  = res  ? samr_close(smb_cli, &info->dom.samr_pol_connect) : False;
342
343         /* close the session */
344         cli_nt_session_close(smb_cli);
345
346         if (res && res1 && res2)
347         {
348                 DEBUG(5,("cmd_sam_delete_dom_alias: succeeded\n"));
349                 fprintf(out_hnd, "Delete Domain Alias: OK\n");
350         }
351         else
352         {
353                 DEBUG(5,("cmd_sam_delete_dom_alias: failed\n"));
354                 fprintf(out_hnd, "Delete Domain Alias: FAILED\n");
355         }
356 }
357
358
359 /****************************************************************************
360 SAM add alias member.
361 ****************************************************************************/
362 void cmd_sam_add_aliasmem(struct client_info *info)
363 {
364         fstring srv_name;
365         fstring domain;
366         fstring tmp;
367         fstring sid;
368         DOM_SID sid1;
369         POLICY_HND alias_pol;
370         BOOL res = True;
371         BOOL res1 = True;
372         BOOL res2 = True;
373         BOOL res3 = True;
374         BOOL res4 = True;
375         uint32 flags = 0x200003f3; /* absolutely no idea. */
376         uint32 alias_rid;
377         const char **names = NULL;
378         uint32 num_names = 0;
379         DOM_SID *sids; 
380         uint32 num_sids;
381         int i;
382
383         sid_copy(&sid1, &info->dom.level5_sid);
384         sid_to_string(sid, &sid1);
385         fstrcpy(domain, info->dom.level5_dom);
386
387         if (sid1.num_auths == 0)
388         {
389                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
390                 return;
391         }
392
393         fstrcpy(srv_name, "\\\\");
394         fstrcat(srv_name, info->dest_host);
395         strupper(srv_name);
396
397         while (next_token(NULL, tmp, NULL, sizeof(tmp)))
398         {
399                 num_names++;
400                 names = Realloc(names, num_names * sizeof(char*));
401                 if (names == NULL)
402                 {
403                         DEBUG(0,("Realloc returned NULL\n"));
404                         return;
405                 }
406                 names[num_names-1] = strdup(tmp);
407         }
408
409         if (num_names < 2)
410         {
411                 fprintf(out_hnd, "addaliasmem <group name> [member name1] [member name2] ...\n");
412                 return;
413         }
414         
415         fprintf(out_hnd, "SAM Domain Alias Member\n");
416
417         /* open LSARPC session. */
418         res3 = res3 ? cli_nt_session_open(smb_cli, PIPE_LSARPC) : False;
419
420         /* lookup domain controller; receive a policy handle */
421         res3 = res3 ? lsa_open_policy(smb_cli,
422                                 srv_name,
423                                 &info->dom.lsa_info_pol, True) : False;
424
425         /* send lsa lookup sids call */
426         res4 = res3 ? lsa_lookup_names(smb_cli, 
427                                        &info->dom.lsa_info_pol,
428                                        num_names, names, 
429                                        &sids, &num_sids) : False;
430
431         res3 = res3 ? lsa_close(smb_cli, &info->dom.lsa_info_pol) : False;
432
433         cli_nt_session_close(smb_cli);
434
435         res4 = num_sids < 2 ? False : res4;
436
437         if (res4)
438         {
439                 /*
440                  * accept domain sid or builtin sid
441                  */
442
443                 DOM_SID sid_1_5_20;
444                 string_to_sid(&sid_1_5_20, "S-1-5-32");
445                 sid_split_rid(&sids[0], &alias_rid);
446
447                 if (sid_equal(&sids[0], &sid_1_5_20))
448                 {
449                         sid_copy(&sid1, &sid_1_5_20);
450                 }
451                 else if (!sid_equal(&sids[0], &sid1))
452                 {       
453                         res4 = False;
454                 }
455         }
456
457         /* open SAMR session.  negotiate credentials */
458         res = res4 ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
459
460         /* establish a connection. */
461         res = res ? samr_connect(smb_cli, 
462                                 srv_name, 0x00000020,
463                                 &info->dom.samr_pol_connect) : False;
464
465         /* connect to the domain */
466         res = res ? samr_open_domain(smb_cli, 
467                     &info->dom.samr_pol_connect, flags, &sid1,
468                     &info->dom.samr_pol_open_domain) : False;
469
470         /* connect to the domain */
471         res1 = res ? samr_open_alias(smb_cli,
472                     &info->dom.samr_pol_open_domain,
473                     0x000f001f, alias_rid, &alias_pol) : False;
474
475         for (i = 1; i < num_sids && res2 && res1; i++)
476         {
477                 /* add a member to the alias */
478                 res2 = res2 ? samr_add_aliasmem(smb_cli, &alias_pol, &sids[i]) : False;
479
480                 if (res2)
481                 {
482                         sid_to_string(tmp, &sids[i]);
483                         fprintf(out_hnd, "SID added to Alias 0x%x: %s\n", alias_rid, tmp);
484                 }
485         }
486
487         res1 = res1 ? samr_close(smb_cli, &alias_pol) : False;
488         res  = res  ? samr_close(smb_cli, &info->dom.samr_pol_open_domain) : False;
489         res  = res  ? samr_close(smb_cli, &info->dom.samr_pol_connect) : False;
490
491         /* close the session */
492         cli_nt_session_close(smb_cli);
493
494         if (sids != NULL)
495         {
496                 free(sids);
497         }
498         
499         if (names != NULL)
500         {
501                 for (i = 0; i < num_names; i++)
502                 {
503                         if (names[i] != NULL)
504                         {
505                                 free(((char**)(names))[i]);
506                         }
507                 }
508                 free(names);
509         }
510         
511         if (res && res1 && res2)
512         {
513                 DEBUG(5,("cmd_sam_add_aliasmem: succeeded\n"));
514                 fprintf(out_hnd, "Add Domain Alias Member: OK\n");
515         }
516         else
517         {
518                 DEBUG(5,("cmd_sam_add_aliasmem: failed\n"));
519                 fprintf(out_hnd, "Add Domain Alias Member: FAILED\n");
520         }
521 }
522
523
524 /****************************************************************************
525 SAM create domain alias.
526 ****************************************************************************/
527 void cmd_sam_create_dom_alias(struct client_info *info)
528 {
529         fstring srv_name;
530         fstring domain;
531         fstring acct_name;
532         fstring acct_desc;
533         fstring sid;
534         DOM_SID sid1;
535         BOOL res = True;
536         BOOL res1 = True;
537         uint32 flags = 0x200003f3; /* absolutely no idea. */
538         uint32 alias_rid; 
539
540         sid_copy(&sid1, &info->dom.level5_sid);
541         sid_to_string(sid, &sid1);
542         fstrcpy(domain, info->dom.level5_dom);
543
544         if (sid1.num_auths == 0)
545         {
546                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
547                 return;
548         }
549
550
551         fstrcpy(srv_name, "\\\\");
552         fstrcat(srv_name, info->dest_host);
553         strupper(srv_name);
554
555         if (!next_token(NULL, acct_name, NULL, sizeof(acct_name)))
556         {
557                 fprintf(out_hnd, "createalias: <acct name> [acct description]\n");
558         }
559
560         if (!next_token(NULL, acct_desc, NULL, sizeof(acct_desc)))
561         {
562                 acct_desc[0] = 0;
563         }
564
565
566         fprintf(out_hnd, "SAM Create Domain Alias\n");
567         fprintf(out_hnd, "Domain: %s Name: %s Description: %s\n",
568                           domain, acct_name, acct_desc);
569
570         /* open SAMR session.  negotiate credentials */
571         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
572
573         /* establish a connection. */
574         res = res ? samr_connect(smb_cli, 
575                                 srv_name, 0x00000020,
576                                 &info->dom.samr_pol_connect) : False;
577
578         /* connect to the domain */
579         res = res ? samr_open_domain(smb_cli, 
580                     &info->dom.samr_pol_connect, flags, &sid1,
581                     &info->dom.samr_pol_open_domain) : False;
582
583         /* create a domain alias */
584         res1 = res ? create_samr_domain_alias(smb_cli, 
585                                 &info->dom.samr_pol_open_domain,
586                                 acct_name, acct_desc, &alias_rid) : False;
587
588         res = res ? samr_close(smb_cli,
589                     &info->dom.samr_pol_open_domain) : False;
590
591         res = res ? samr_close(smb_cli,
592                     &info->dom.samr_pol_connect) : False;
593
594         /* close the session */
595         cli_nt_session_close(smb_cli);
596
597         if (res && res1)
598         {
599                 DEBUG(5,("cmd_sam_create_dom_alias: succeeded\n"));
600                 fprintf(out_hnd, "Create Domain Alias: OK\n");
601         }
602         else
603         {
604                 DEBUG(5,("cmd_sam_create_dom_alias: failed\n"));
605                 fprintf(out_hnd, "Create Domain Alias: FAILED\n");
606         }
607 }
608
609
610 /****************************************************************************
611 SAM delete group member.
612 ****************************************************************************/
613 void cmd_sam_del_groupmem(struct client_info *info)
614 {
615         fstring srv_name;
616         fstring domain;
617         fstring tmp;
618         fstring sid;
619         DOM_SID sid1;
620         POLICY_HND group_pol;
621         BOOL res = True;
622         BOOL res1 = True;
623         BOOL res2 = True;
624         uint32 flags = 0x200003f3; /* absolutely no idea. */
625         uint32 member_rid; 
626         uint32 group_rid;
627
628         sid_copy(&sid1, &info->dom.level5_sid);
629         sid_to_string(sid, &sid1);
630         fstrcpy(domain, info->dom.level5_dom);
631
632         if (sid1.num_auths == 0)
633         {
634                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
635                 return;
636         }
637
638         fstrcpy(srv_name, "\\\\");
639         fstrcat(srv_name, info->dest_host);
640         strupper(srv_name);
641
642         if (!next_token(NULL, tmp, NULL, sizeof(tmp)))
643         {
644                 fprintf(out_hnd, "delgroupmem: <group rid> [member rid1] [member rid2] ...\n");
645                 return;
646         }
647         group_rid = get_number(tmp);
648
649         fprintf(out_hnd, "SAM Add Domain Group member\n");
650
651         /* open SAMR session.  negotiate credentials */
652         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
653
654         /* establish a connection. */
655         res = res ? samr_connect(smb_cli, 
656                                 srv_name, 0x00000020,
657                                 &info->dom.samr_pol_connect) : False;
658
659         /* connect to the domain */
660         res = res ? samr_open_domain(smb_cli, 
661                     &info->dom.samr_pol_connect, flags, &sid1,
662                     &info->dom.samr_pol_open_domain) : False;
663
664         /* connect to the domain */
665         res1 = res ? samr_open_group(smb_cli,
666                     &info->dom.samr_pol_open_domain,
667                     0x0000001f, group_rid, &group_pol) : False;
668
669         while (next_token(NULL, tmp, NULL, sizeof(tmp)) && res2 && res1)
670         {
671                 /* get a rid, delete a member from the group */
672                 member_rid = get_number(tmp);
673                 res2 = res2 ? samr_del_groupmem(smb_cli, &group_pol, member_rid) : False;
674
675                 if (res2)
676                 {
677                         fprintf(out_hnd, "RID deleted from Group 0x%x: 0x%x\n", group_rid, member_rid);
678                 }
679         }
680
681         res1 = res1 ? samr_close(smb_cli, &group_pol) : False;
682         res  = res  ? samr_close(smb_cli, &info->dom.samr_pol_open_domain) : False;
683         res  = res  ? samr_close(smb_cli, &info->dom.samr_pol_connect) : False;
684
685         /* close the session */
686         cli_nt_session_close(smb_cli);
687
688         if (res && res1 && res2)
689         {
690                 DEBUG(5,("cmd_sam_del_groupmem: succeeded\n"));
691                 fprintf(out_hnd, "Add Domain Group Member: OK\n");
692         }
693         else
694         {
695                 DEBUG(5,("cmd_sam_del_groupmem: failed\n"));
696                 fprintf(out_hnd, "Add Domain Group Member: FAILED\n");
697         }
698 }
699
700
701 /****************************************************************************
702 SAM delete group.
703 ****************************************************************************/
704 void cmd_sam_delete_dom_group(struct client_info *info)
705 {
706         fstring srv_name;
707         fstring domain;
708         fstring name;
709         fstring sid;
710         DOM_SID sid1;
711         POLICY_HND group_pol;
712         BOOL res = True;
713         BOOL res1 = True;
714         BOOL res2 = True;
715         uint32 flags = 0x200003f3; /* absolutely no idea. */
716         uint32 group_rid = 0;
717         const char *names[1];
718         uint32 rid [MAX_LOOKUP_SIDS];
719         uint32 type[MAX_LOOKUP_SIDS];
720         uint32 num_rids;
721
722         sid_copy(&sid1, &info->dom.level5_sid);
723         sid_to_string(sid, &sid1);
724         fstrcpy(domain, info->dom.level5_dom);
725
726         if (sid1.num_auths == 0)
727         {
728                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
729                 return;
730         }
731
732         fstrcpy(srv_name, "\\\\");
733         fstrcat(srv_name, info->dest_host);
734         strupper(srv_name);
735
736         if (!next_token(NULL, name, NULL, sizeof(name)))
737         {
738                 fprintf(out_hnd, "delgroup <group name>\n");
739                 return;
740         }
741
742         fprintf(out_hnd, "SAM Delete Domain Group\n");
743
744         /* open SAMR session.  negotiate credentials */
745         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
746
747         /* establish a connection. */
748         res = res ? samr_connect(smb_cli, 
749                                 srv_name, 0x00000020,
750                                 &info->dom.samr_pol_connect) : False;
751
752         /* connect to the domain */
753         res = res ? samr_open_domain(smb_cli, 
754                     &info->dom.samr_pol_connect, flags, &sid1,
755                     &info->dom.samr_pol_open_domain) : False;
756
757         names[0] = name;
758
759         res1 = res ? samr_query_lookup_names(smb_cli,
760                     &info->dom.samr_pol_open_domain, 0x000003e8,
761                     1, names,
762                     &num_rids, rid, type) : False;
763
764         if (res1 && num_rids == 1)
765         {
766                 group_rid = rid[0];
767         }
768
769         /* connect to the domain */
770         res1 = res1 ? samr_open_group(smb_cli,
771                     &info->dom.samr_pol_open_domain,
772                     0x0000001f, group_rid, &group_pol) : False;
773
774         res2 = res1 ? samr_delete_dom_group(smb_cli, &group_pol) : False;
775
776         res1 = res1 ? samr_close(smb_cli, &group_pol) : False;
777         res  = res  ? samr_close(smb_cli, &info->dom.samr_pol_open_domain) : False;
778         res  = res  ? samr_close(smb_cli, &info->dom.samr_pol_connect) : False;
779
780         /* close the session */
781         cli_nt_session_close(smb_cli);
782
783         if (res && res1 && res2)
784         {
785                 DEBUG(5,("cmd_sam_delete_dom_group: succeeded\n"));
786                 fprintf(out_hnd, "Delete Domain Group: OK\n");
787         }
788         else
789         {
790                 DEBUG(5,("cmd_sam_delete_dom_group: failed\n"));
791                 fprintf(out_hnd, "Delete Domain Group: FAILED\n");
792         }
793 }
794
795
796 /****************************************************************************
797 SAM add group member.
798 ****************************************************************************/
799 void cmd_sam_add_groupmem(struct client_info *info)
800 {
801         fstring srv_name;
802         fstring domain;
803         fstring tmp;
804         fstring sid;
805         DOM_SID sid1;
806         POLICY_HND group_pol;
807         BOOL res = True;
808         BOOL res1 = True;
809         BOOL res2 = True;
810         uint32 flags = 0x200003f3; /* absolutely no idea. */
811         uint32 group_rid = 0;
812         const char **names = NULL;
813         uint32 num_names = 0;
814         uint32 rid [MAX_LOOKUP_SIDS];
815         uint32 type[MAX_LOOKUP_SIDS];
816         uint32 num_rids;
817         int i;
818
819         sid_copy(&sid1, &info->dom.level5_sid);
820         sid_to_string(sid, &sid1);
821         fstrcpy(domain, info->dom.level5_dom);
822
823         if (sid1.num_auths == 0)
824         {
825                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
826                 return;
827         }
828
829         fstrcpy(srv_name, "\\\\");
830         fstrcat(srv_name, info->dest_host);
831         strupper(srv_name);
832
833         while (next_token(NULL, tmp, NULL, sizeof(tmp)))
834         {
835                 num_names++;
836                 names = Realloc(names, num_names * sizeof(char*));
837                 if (names == NULL)
838                 {
839                         DEBUG(0,("Realloc returned NULL\n"));
840                         return;
841                 }
842                 names[num_names-1] = strdup(tmp);
843         }
844
845         if (num_names < 2)
846         {
847                 fprintf(out_hnd, "addgroupmem <group name> [member name1] [member name2] ...\n");
848                 return;
849         }
850         
851         fprintf(out_hnd, "SAM Add Domain Group member\n");
852
853         /* open SAMR session.  negotiate credentials */
854         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
855
856         /* establish a connection. */
857         res = res ? samr_connect(smb_cli, 
858                                 srv_name, 0x00000020,
859                                 &info->dom.samr_pol_connect) : False;
860
861         /* connect to the domain */
862         res = res ? samr_open_domain(smb_cli, 
863                     &info->dom.samr_pol_connect, flags, &sid1,
864                     &info->dom.samr_pol_open_domain) : False;
865
866         res1 = res ? samr_query_lookup_names(smb_cli,
867                     &info->dom.samr_pol_open_domain, 0x000003e8,
868                     num_names, names,
869                     &num_rids, rid, type) : False;
870
871         if (res1 && num_rids != 0)
872         {
873                 group_rid = rid[0];
874         }
875
876         /* connect to the domain */
877         res1 = res1 ? samr_open_group(smb_cli,
878                     &info->dom.samr_pol_open_domain,
879                     0x0000001f, group_rid, &group_pol) : False;
880
881         for (i = 1; i < num_rids && res2 && res1; i++)
882         {
883                 res2 = res2 ? samr_add_groupmem(smb_cli, &group_pol, rid[i]) : False;
884
885                 if (res2)
886                 {
887                         fprintf(out_hnd, "RID added to Group 0x%x: 0x%x\n", group_rid, rid[i]);
888                 }
889         }
890
891         res1 = res1 ? samr_close(smb_cli, &group_pol) : False;
892         res  = res  ? samr_close(smb_cli, &info->dom.samr_pol_open_domain) : False;
893         res  = res  ? samr_close(smb_cli, &info->dom.samr_pol_connect) : False;
894
895         /* close the session */
896         cli_nt_session_close(smb_cli);
897
898         if (names != NULL)
899         {
900                 for (i = 0; i < num_names; i++)
901                 {
902                         if (names[i] != NULL)
903                         {
904                                 free(((char**)(names))[i]);
905                         }
906                 }
907                 free(names);
908         }
909         
910         if (res && res1 && res2)
911         {
912                 DEBUG(5,("cmd_sam_add_groupmem: succeeded\n"));
913                 fprintf(out_hnd, "Add Domain Group Member: OK\n");
914         }
915         else
916         {
917                 DEBUG(5,("cmd_sam_add_groupmem: failed\n"));
918                 fprintf(out_hnd, "Add Domain Group Member: FAILED\n");
919         }
920 }
921
922
923 /****************************************************************************
924 SAM create domain group.
925 ****************************************************************************/
926 void cmd_sam_create_dom_group(struct client_info *info)
927 {
928         fstring srv_name;
929         fstring domain;
930         fstring acct_name;
931         fstring acct_desc;
932         fstring sid;
933         DOM_SID sid1;
934         BOOL res = True;
935         BOOL res1 = True;
936         uint32 flags = 0x220; /* absolutely no idea. */
937         uint32 group_rid; 
938
939         sid_copy(&sid1, &info->dom.level5_sid);
940         sid_to_string(sid, &sid1);
941         fstrcpy(domain, info->dom.level5_dom);
942
943         if (sid1.num_auths == 0)
944         {
945                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
946                 return;
947         }
948
949
950         fstrcpy(srv_name, "\\\\");
951         fstrcat(srv_name, info->dest_host);
952         strupper(srv_name);
953
954         if (!next_token(NULL, acct_name, NULL, sizeof(acct_name)))
955         {
956                 fprintf(out_hnd, "creategroup: <acct name> [acct description]\n");
957         }
958
959         if (!next_token(NULL, acct_desc, NULL, sizeof(acct_desc)))
960         {
961                 acct_desc[0] = 0;
962         }
963
964
965         fprintf(out_hnd, "SAM Create Domain Group\n");
966         fprintf(out_hnd, "Domain: %s Name: %s Description: %s\n",
967                           domain, acct_name, acct_desc);
968
969         /* open SAMR session.  negotiate credentials */
970         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
971
972         /* establish a connection. */
973         res = res ? samr_connect(smb_cli, 
974                                 srv_name, 0x00000020,
975                                 &info->dom.samr_pol_connect) : False;
976
977         /* connect to the domain */
978         res = res ? samr_open_domain(smb_cli, 
979                     &info->dom.samr_pol_connect, flags, &sid1,
980                     &info->dom.samr_pol_open_domain) : False;
981
982         /* read some users */
983         res1 = res ? create_samr_domain_group(smb_cli, 
984                                 &info->dom.samr_pol_open_domain,
985                                 acct_name, acct_desc, &group_rid) : False;
986
987         res = res ? samr_close(smb_cli,
988                     &info->dom.samr_pol_open_domain) : False;
989
990         res = res ? samr_close(smb_cli,
991                     &info->dom.samr_pol_connect) : False;
992
993         /* close the session */
994         cli_nt_session_close(smb_cli);
995
996         if (res && res1)
997         {
998                 DEBUG(5,("cmd_sam_create_dom_group: succeeded\n"));
999                 fprintf(out_hnd, "Create Domain Group: OK\n");
1000         }
1001         else
1002         {
1003                 DEBUG(5,("cmd_sam_create_dom_group: failed\n"));
1004                 fprintf(out_hnd, "Create Domain Group: FAILED\n");
1005         }
1006 }
1007
1008
1009 /****************************************************************************
1010 experimental SAM users enum.
1011 ****************************************************************************/
1012 void cmd_sam_enum_users(struct client_info *info)
1013 {
1014         fstring srv_name;
1015         fstring domain;
1016         fstring sid;
1017         DOM_SID sid1;
1018         DOM_SID sid_1_5_20;
1019         int user_idx;
1020         BOOL res = True;
1021         BOOL res1 = True;
1022         BOOL request_user_info  = False;
1023         BOOL request_group_info = False;
1024         BOOL request_alias_info = False;
1025         uint16 num_entries = 0;
1026         uint16 unk_0 = 0x0;
1027         uint16 acb_mask = 0;
1028         uint16 unk_1 = 0x0;
1029         uint32 flags = 0x304; /* absolutely no idea. */
1030         fstring tmp;
1031         int i;
1032
1033         sid_copy(&sid1, &info->dom.level5_sid);
1034         sid_to_string(sid, &sid1);
1035         fstrcpy(domain, info->dom.level5_dom);
1036
1037         if (sid1.num_auths == 0)
1038         {
1039                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
1040                 return;
1041         }
1042
1043
1044         fstrcpy(srv_name, "\\\\");
1045         fstrcat(srv_name, info->dest_host);
1046         strupper(srv_name);
1047
1048         for (i = 0; i < 3; i++)
1049         {
1050                 /* a bad way to do token parsing... */
1051                 if (next_token(NULL, tmp, NULL, sizeof(tmp)))
1052                 {
1053                         request_user_info  |= strequal(tmp, "-u");
1054                         request_group_info |= strequal(tmp, "-g");
1055                         request_alias_info |= strequal(tmp, "-a");
1056                 }
1057                 else
1058                 {
1059                         break;
1060                 }
1061         }
1062
1063 #ifdef DEBUG_TESTING
1064         if (next_token(NULL, tmp, NULL, sizeof(tmp)))
1065         {
1066                 num_entries = (uint16)strtol(tmp, (char**)NULL, 16);
1067         }
1068
1069         if (next_token(NULL, tmp, NULL, sizeof(tmp)))
1070         {
1071                 unk_0 = (uint16)strtol(tmp, (char**)NULL, 16);
1072         }
1073
1074         if (next_token(NULL, tmp, NULL, sizeof(tmp)))
1075         {
1076                 acb_mask = (uint16)strtol(tmp, (char**)NULL, 16);
1077         }
1078
1079         if (next_token(NULL, tmp, NULL, sizeof(tmp)))
1080         {
1081                 unk_1 = (uint16)strtol(tmp, (char**)NULL, 16);
1082         }
1083 #endif
1084
1085         string_to_sid(&sid_1_5_20, "S-1-5-32");
1086
1087         fprintf(out_hnd, "SAM Enumerate Users\n");
1088         fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
1089                           info->myhostname, srv_name, domain, sid);
1090
1091 #ifdef DEBUG_TESTING
1092         DEBUG(5,("Number of entries:%d unk_0:%04x acb_mask:%04x unk_1:%04x\n",
1093                   num_entries, unk_0, acb_mask, unk_1));
1094 #endif
1095
1096         /* open SAMR session.  negotiate credentials */
1097         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
1098
1099         /* establish a connection. */
1100         res = res ? samr_connect(smb_cli, 
1101                                 srv_name, 0x00000020,
1102                                 &info->dom.samr_pol_connect) : False;
1103
1104         /* connect to the domain */
1105         res = res ? samr_open_domain(smb_cli, 
1106                     &info->dom.samr_pol_connect, flags, &sid1,
1107                     &info->dom.samr_pol_open_domain) : False;
1108
1109         /* connect to the S-1-5-20 domain */
1110         res1 = res ? samr_open_domain(smb_cli, 
1111                     &info->dom.samr_pol_connect, flags, &sid_1_5_20,
1112                     &info->dom.samr_pol_open_builtindom) : False;
1113
1114         info->dom.sam = NULL;
1115
1116         /* read some users */
1117         res = res ? samr_enum_dom_users(smb_cli, 
1118                                 &info->dom.samr_pol_open_domain,
1119                     num_entries, unk_0, acb_mask, unk_1, 0xffff,
1120                                 &info->dom.sam, &info->dom.num_sam_entries) : False;
1121
1122         if (res && info->dom.num_sam_entries == 0)
1123         {
1124                 fprintf(out_hnd, "No users\n");
1125         }
1126
1127                 /* query all the users */
1128         for (user_idx = 0; res && user_idx < info->dom.num_sam_entries; user_idx++)
1129                 {
1130                 uint32 user_rid = info->dom.sam[user_idx].rid;
1131                         SAM_USER_INFO_21 usr;
1132
1133                         fprintf(out_hnd, "User RID: %8x  User Name: %s\n",
1134                                           user_rid,
1135                                           info->dom.sam[user_idx].acct_name);
1136
1137                         if (request_user_info)
1138                         {
1139                                 /* send user info query, level 0x15 */
1140                                 if (get_samr_query_userinfo(smb_cli,
1141                                                         &info->dom.samr_pol_open_domain,
1142                                                         0x15, user_rid, &usr))
1143                                 {
1144                                         display_sam_user_info_21(out_hnd, ACTION_HEADER   , &usr);
1145                                         display_sam_user_info_21(out_hnd, ACTION_ENUMERATE, &usr);
1146                                         display_sam_user_info_21(out_hnd, ACTION_FOOTER   , &usr);
1147                                 }
1148                         }
1149
1150                         if (request_group_info)
1151                         {
1152                                 uint32 num_groups;
1153                                 DOM_GID gid[LSA_MAX_GROUPS];
1154
1155                                 /* send user group query */
1156                                 if (get_samr_query_usergroups(smb_cli,
1157                                                         &info->dom.samr_pol_open_domain,
1158                                                         user_rid, &num_groups, gid))
1159                                 {
1160                                 uint32 num_names;
1161                                 uint32  rid_mem[MAX_LOOKUP_SIDS];
1162                                 fstring name   [MAX_LOOKUP_SIDS];
1163                                 uint32  type   [MAX_LOOKUP_SIDS];
1164
1165                                 for (i = 0; i < num_groups; i++)
1166                                 {
1167                                         rid_mem[i] = gid[i].g_rid;
1168                                 }
1169
1170                                 if (samr_query_lookup_rids(smb_cli, 
1171                                                 &info->dom.samr_pol_open_domain, 0x3e8,
1172                                                 num_groups, rid_mem, 
1173                                                 &num_names, name, type))
1174                                 {
1175                                         display_group_members(out_hnd, ACTION_HEADER   , num_names, name, type);
1176                                         display_group_members(out_hnd, ACTION_ENUMERATE, num_names, name, type);
1177                                         display_group_members(out_hnd, ACTION_FOOTER   , num_names, name, type);
1178                                 }
1179                                 }
1180                         }
1181
1182                         if (request_alias_info)
1183                         {
1184                                 uint32 num_aliases;
1185                                 uint32 rid[LSA_MAX_GROUPS];
1186                                 DOM_SID als_sid;
1187
1188                                 sid_copy(&als_sid, &sid1);
1189                                 sid_append_rid(&als_sid, user_rid);
1190
1191                                 /* send user alias query */
1192                                 if (samr_query_useraliases(smb_cli,
1193                                                         &info->dom.samr_pol_open_domain,
1194                                                         &als_sid, &num_aliases, rid))
1195                                 {
1196                                 uint32 num_names;
1197                                 fstring name   [MAX_LOOKUP_SIDS];
1198                                 uint32  type   [MAX_LOOKUP_SIDS];
1199
1200                                 if (samr_query_lookup_rids(smb_cli, 
1201                                                 &info->dom.samr_pol_open_domain, 0x3e8,
1202                                                 num_aliases, rid, 
1203                                                 &num_names, name, type))
1204                                 {
1205                                         display_group_members(out_hnd, ACTION_HEADER   , num_names, name, type);
1206                                         display_group_members(out_hnd, ACTION_ENUMERATE, num_names, name, type);
1207                                         display_group_members(out_hnd, ACTION_FOOTER   , num_names, name, type);
1208                                 }
1209                         }
1210
1211                         /* send user alias query */
1212                         if (res1 && samr_query_useraliases(smb_cli,
1213                                                 &info->dom.samr_pol_open_builtindom,
1214                                                 &als_sid, &num_aliases, rid))
1215                         {
1216                                 uint32 num_names;
1217                                 fstring name   [MAX_LOOKUP_SIDS];
1218                                 uint32  type   [MAX_LOOKUP_SIDS];
1219
1220                                 if (samr_query_lookup_rids(smb_cli, 
1221                                                 &info->dom.samr_pol_open_builtindom, 0x3e8,
1222                                                 num_aliases, rid, 
1223                                                 &num_names, name, type))
1224                                 {
1225                                         display_group_members(out_hnd, ACTION_HEADER   , num_names, name, type);
1226                                         display_group_members(out_hnd, ACTION_ENUMERATE, num_names, name, type);
1227                                         display_group_members(out_hnd, ACTION_FOOTER   , num_names, name, type);
1228                                 }
1229                         }
1230                 }
1231         }
1232
1233         res1 = res1 ? samr_close(smb_cli,
1234                     &info->dom.samr_pol_open_builtindom) : False;
1235
1236         res = res ? samr_close(smb_cli,
1237                     &info->dom.samr_pol_open_domain) : False;
1238
1239         res = res ? samr_close(smb_cli,
1240                     &info->dom.samr_pol_connect) : False;
1241
1242         /* close the session */
1243         cli_nt_session_close(smb_cli);
1244
1245         if (info->dom.sam != NULL)
1246         {
1247                 free(info->dom.sam);
1248         }
1249
1250         if (res)
1251         {
1252                 DEBUG(5,("cmd_sam_enum_users: succeeded\n"));
1253         }
1254         else
1255         {
1256                 DEBUG(5,("cmd_sam_enum_users: failed\n"));
1257         }
1258 }
1259
1260
1261 /****************************************************************************
1262 experimental SAM user query.
1263 ****************************************************************************/
1264 void cmd_sam_query_user(struct client_info *info)
1265 {
1266         fstring srv_name;
1267         fstring domain;
1268         fstring sid;
1269         DOM_SID sid1;
1270         int user_idx = 0;  /* FIXME maybe ... */
1271         BOOL res = True;
1272         uint32 flags = 0x304; /* absolutely no idea. */
1273         fstring rid_str ;
1274         fstring info_str;
1275         uint32 user_rid = 0;
1276         uint32 info_level = 0x15;
1277
1278         SAM_USER_INFO_21 usr;
1279
1280         sid_to_string(sid, &info->dom.level5_sid);
1281         fstrcpy(domain, info->dom.level5_dom);
1282
1283         if (strlen(sid) == 0)
1284         {
1285                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
1286                 return;
1287         }
1288
1289         string_to_sid(&sid1, sid);
1290
1291         fstrcpy(srv_name, "\\\\");
1292         fstrcat(srv_name, info->dest_host);
1293         strupper(srv_name);
1294
1295         if (next_token(NULL, rid_str , NULL, sizeof(rid_str )) &&
1296             next_token(NULL, info_str, NULL, sizeof(info_str)))
1297         {
1298                 user_rid   = strtoul(rid_str , (char**)NULL, 16);
1299                 info_level = strtoul(info_str, (char**)NULL, 10);
1300         }
1301
1302         fprintf(out_hnd, "SAM Query User: rid %x info level %d\n",
1303                           user_rid, info_level);
1304         fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
1305                           info->myhostname, srv_name, domain, sid);
1306
1307         /* open SAMR session.  negotiate credentials */
1308         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
1309
1310         /* establish a connection. */
1311         res = res ? samr_connect(smb_cli,
1312                                 srv_name, 0x00000020,
1313                                 &info->dom.samr_pol_connect) : False;
1314
1315         /* connect to the domain */
1316         res = res ? samr_open_domain(smb_cli,
1317                     &info->dom.samr_pol_connect, flags, &sid1,
1318                     &info->dom.samr_pol_open_domain) : False;
1319
1320         fprintf(out_hnd, "User RID: %8x  User Name: %s\n",
1321                           user_rid,
1322                           info->dom.sam[user_idx].acct_name);
1323
1324         /* send user info query, level */
1325         if (get_samr_query_userinfo(smb_cli,
1326                                         &info->dom.samr_pol_open_domain,
1327                                         info_level, user_rid, &usr))
1328         {
1329                 if (info_level == 0x15)
1330                 {
1331                         display_sam_user_info_21(out_hnd, ACTION_HEADER   , &usr);
1332                         display_sam_user_info_21(out_hnd, ACTION_ENUMERATE, &usr);
1333                         display_sam_user_info_21(out_hnd, ACTION_FOOTER   , &usr);
1334                 }
1335         }
1336
1337         res = res ? samr_close(smb_cli,
1338                     &info->dom.samr_pol_connect) : False;
1339
1340         res = res ? samr_close(smb_cli,
1341                     &info->dom.samr_pol_open_domain) : False;
1342
1343         /* close the session */
1344         cli_nt_session_close(smb_cli);
1345
1346         if (res)
1347         {
1348                 DEBUG(5,("cmd_sam_query_user: succeeded\n"));
1349         }
1350         else
1351         {
1352                 DEBUG(5,("cmd_sam_query_user: failed\n"));
1353         }
1354 }
1355
1356
1357 /****************************************************************************
1358 experimental SAM domain info query.
1359 ****************************************************************************/
1360 void cmd_sam_query_dominfo(struct client_info *info)
1361 {
1362         fstring srv_name;
1363         fstring domain;
1364         fstring sid;
1365         DOM_SID sid1;
1366         BOOL res = True;
1367         fstring info_str;
1368         uint32 switch_value = 2;
1369         uint32 flags = 0x304; /* absolutely no idea. */
1370
1371         sid_to_string(sid, &info->dom.level5_sid);
1372         fstrcpy(domain, info->dom.level5_dom);
1373
1374         if (strlen(sid) == 0)
1375         {
1376                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
1377                 return;
1378         }
1379
1380         string_to_sid(&sid1, sid);
1381
1382         fstrcpy(srv_name, "\\\\");
1383         fstrcat(srv_name, info->dest_host);
1384         strupper(srv_name);
1385
1386         if (next_token(NULL, info_str, NULL, sizeof(info_str)))
1387         {
1388                 switch_value = strtoul(info_str, (char**)NULL, 10);
1389         }
1390
1391         fprintf(out_hnd, "SAM Query Domain Info: info level %d\n", switch_value);
1392         fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
1393                           info->myhostname, srv_name, domain, sid);
1394
1395         /* open SAMR session.  negotiate credentials */
1396         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
1397
1398         /* establish a connection. */
1399         res = res ? samr_connect(smb_cli, 
1400                                 srv_name, 0x00000020,
1401                                 &info->dom.samr_pol_connect) : False;
1402
1403         /* connect to the domain */
1404         res = res ? samr_open_domain(smb_cli, 
1405                     &info->dom.samr_pol_connect, flags, &sid1,
1406                     &info->dom.samr_pol_open_domain) : False;
1407
1408         /* send a samr 0x8 command */
1409         res = res ? samr_query_dom_info(smb_cli,
1410                     &info->dom.samr_pol_open_domain, switch_value) : False;
1411
1412         res = res ? samr_close(smb_cli,
1413                     &info->dom.samr_pol_connect) : False;
1414
1415         res = res ? samr_close(smb_cli, 
1416                     &info->dom.samr_pol_open_domain) : False;
1417
1418         /* close the session */
1419         cli_nt_session_close(smb_cli);
1420
1421         if (res)
1422         {
1423                 DEBUG(5,("cmd_sam_query_dominfo: succeeded\n"));
1424         }
1425         else
1426         {
1427                 DEBUG(5,("cmd_sam_query_dominfo: failed\n"));
1428         }
1429 }
1430
1431
1432 /****************************************************************************
1433 experimental SAM aliases query.
1434 ****************************************************************************/
1435 void cmd_sam_enum_aliases(struct client_info *info)
1436 {
1437         fstring srv_name;
1438         fstring domain;
1439         fstring sid;
1440         DOM_SID sid1;
1441         BOOL res = True;
1442         BOOL request_member_info = False;
1443         uint32 flags = 0x200003f3; /* absolutely no idea. */
1444         fstring tmp;
1445         uint32 alias_idx;
1446
1447         sid_to_string(sid, &info->dom.level3_sid);
1448         fstrcpy(domain, info->dom.level3_dom);
1449 #if 0
1450         fstrcpy(sid   , "S-1-5-20");
1451 #endif
1452         if (strlen(sid) == 0)
1453         {
1454                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
1455                 return;
1456         }
1457
1458         string_to_sid(&sid1, sid);
1459
1460         fstrcpy(srv_name, "\\\\");
1461         fstrcat(srv_name, info->dest_host);
1462         strupper(srv_name);
1463
1464         /* a bad way to do token parsing... */
1465         if (next_token(NULL, tmp, NULL, sizeof(tmp)))
1466         {
1467                 request_member_info |= strequal(tmp, "-m");
1468         }
1469
1470         fprintf(out_hnd, "SAM Enumerate Aliases\n");
1471         fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
1472                           info->myhostname, srv_name, domain, sid);
1473
1474         /* open SAMR session.  negotiate credentials */
1475         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
1476
1477         /* establish a connection. */
1478         res = res ? samr_connect(smb_cli,
1479                                 srv_name, 0x00000020,
1480                                 &info->dom.samr_pol_connect) : False;
1481
1482         /* connect to the domain */
1483         res = res ? samr_open_domain(smb_cli,
1484                     &info->dom.samr_pol_connect, flags, &sid1,
1485                     &info->dom.samr_pol_open_domain) : False;
1486
1487         info->dom.sam = NULL;
1488
1489         /* read some aliases */
1490         res = res ? samr_enum_dom_aliases(smb_cli,
1491                                 &info->dom.samr_pol_open_domain,
1492                                 0xffff,
1493                                 &info->dom.sam, &info->dom.num_sam_entries) : False;
1494
1495         if (res && info->dom.num_sam_entries == 0)
1496         {
1497                 fprintf(out_hnd, "No aliases\n");
1498         }
1499
1500
1501         for (alias_idx = 0; alias_idx < info->dom.num_sam_entries; alias_idx++)
1502         {
1503                 uint32 alias_rid = info->dom.sam[alias_idx].rid;
1504
1505                 fprintf(out_hnd, "Alias RID: %8x  Group Name: %s\n",
1506                                   alias_rid,
1507                                   info->dom.sam[alias_idx].acct_name);
1508
1509                 if (request_member_info)
1510                 {
1511                         uint32 num_aliases;
1512                         DOM_SID2 sid_mem[MAX_LOOKUP_SIDS];
1513
1514                         /* send user aliases query */
1515                         if (get_samr_query_aliasmem(smb_cli, 
1516                                 &info->dom.samr_pol_open_domain,
1517                                                 alias_rid, &num_aliases, sid_mem))
1518                         {
1519                                 BOOL res3 = True;
1520                                 BOOL res4 = True;
1521                                 char **names = NULL;
1522                                 int num_names = 0;
1523                                 DOM_SID **sids = NULL;
1524                                 int i;
1525
1526                                 uint16 old_fnum = smb_cli->nt_pipe_fnum;
1527
1528                                 if (num_aliases != 0)
1529                                 {
1530                                         sids = malloc(num_aliases * sizeof(DOM_SID*));
1531                                 }
1532
1533                                 res3 = sids != NULL;
1534                                 if (res3)
1535                                 {
1536                                         for (i = 0; i < num_aliases; i++)
1537                                         {
1538                                                 sids[i] = &sid_mem[i].sid;
1539                                         }
1540                                 }
1541
1542                                 /* open LSARPC session. */
1543                                 res3 = res3 ? cli_nt_session_open(smb_cli, PIPE_LSARPC) : False;
1544
1545                                 /* lookup domain controller; receive a policy handle */
1546                                 res3 = res3 ? lsa_open_policy(smb_cli,
1547                                                         srv_name,
1548                                                         &info->dom.lsa_info_pol, True) : False;
1549
1550                                 /* send lsa lookup sids call */
1551                                 res4 = res3 ? lsa_lookup_sids(smb_cli, 
1552                                                                &info->dom.lsa_info_pol,
1553                                                                num_aliases, sids, 
1554                                                                &names, &num_names) : False;
1555
1556                                 res3 = res3 ? lsa_close(smb_cli, &info->dom.lsa_info_pol) : False;
1557
1558                                 cli_nt_session_close(smb_cli);
1559
1560                                 smb_cli->nt_pipe_fnum = old_fnum;
1561
1562                                 if (res4 && names != NULL)
1563                                 {
1564                                         display_alias_members(out_hnd, ACTION_HEADER   , num_names, names);
1565                                         display_alias_members(out_hnd, ACTION_ENUMERATE, num_names, names);
1566                                         display_alias_members(out_hnd, ACTION_FOOTER   , num_names, names);
1567                                 }
1568                                 if (names != NULL)
1569                                 {
1570                                         for (i = 0; i < num_names; i++)
1571                                         {
1572                                                 if (names[i] != NULL)
1573                                                 {
1574                                                         free(names[i]);
1575                                                 }
1576                                         }
1577                                         free(names);
1578                                 }
1579                                 if (sids != NULL)
1580                                 {
1581                                         free(sids);
1582                                 }
1583                         }
1584                 }
1585         }
1586
1587         res = res ? samr_close(smb_cli, 
1588                     &info->dom.samr_pol_connect) : False;
1589
1590         res = res ? samr_close(smb_cli,
1591                     &info->dom.samr_pol_open_domain) : False;
1592
1593         /* close the session */
1594         cli_nt_session_close(smb_cli);
1595
1596         if (info->dom.sam != NULL)
1597                         {
1598                 free(info->dom.sam);
1599         }
1600
1601         if (res)
1602         {
1603                 DEBUG(5,("cmd_sam_enum_aliases: succeeded\n"));
1604         }
1605         else
1606                                 {
1607                 DEBUG(5,("cmd_sam_enum_aliases: failed\n"));
1608                                 }
1609                         }
1610
1611
1612 /****************************************************************************
1613 experimental SAM groups query.
1614 ****************************************************************************/
1615 void cmd_sam_enum_groups(struct client_info *info)
1616 {
1617         fstring srv_name;
1618         fstring domain;
1619         fstring sid;
1620         DOM_SID sid1;
1621         BOOL res = True;
1622         BOOL request_member_info = False;
1623         uint32 flags = 0x304; /* absolutely no idea. */
1624         fstring tmp;
1625         uint32 group_idx;
1626
1627         sid_to_string(sid, &info->dom.level3_sid);
1628         fstrcpy(domain, info->dom.level3_dom);
1629 #if 0
1630         fstrcpy(sid   , "S-1-5-20");
1631 #endif
1632         if (strlen(sid) == 0)
1633         {
1634                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
1635                 return;
1636                 }
1637
1638         string_to_sid(&sid1, sid);
1639
1640         fstrcpy(srv_name, "\\\\");
1641         fstrcat(srv_name, info->dest_host);
1642         strupper(srv_name);
1643
1644         /* a bad way to do token parsing... */
1645         if (next_token(NULL, tmp, NULL, sizeof(tmp)))
1646         {
1647                 request_member_info |= strequal(tmp, "-m");
1648         }
1649
1650         fprintf(out_hnd, "SAM Enumerate Groups\n");
1651         fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
1652                           info->myhostname, srv_name, domain, sid);
1653
1654         /* open SAMR session.  negotiate credentials */
1655         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
1656
1657         /* establish a connection. */
1658         res = res ? samr_connect(smb_cli,
1659                                 srv_name, 0x00000020,
1660                     &info->dom.samr_pol_connect) : False;
1661
1662         /* connect to the domain */
1663         res = res ? samr_open_domain(smb_cli,
1664                     &info->dom.samr_pol_connect, flags, &sid1,
1665                     &info->dom.samr_pol_open_domain) : False;
1666
1667         info->dom.sam = NULL;
1668
1669         /* read some groups */
1670         res = res ? samr_enum_dom_groups(smb_cli,
1671                                 &info->dom.samr_pol_open_domain,
1672                                 0xffff,
1673                                 &info->dom.sam, &info->dom.num_sam_entries) : False;
1674
1675         if (res && info->dom.num_sam_entries == 0)
1676         {
1677                 fprintf(out_hnd, "No groups\n");
1678         }
1679
1680
1681         for (group_idx = 0; group_idx < info->dom.num_sam_entries; group_idx++)
1682         {
1683                 uint32 group_rid = info->dom.sam[group_idx].rid;
1684
1685                 fprintf(out_hnd, "Group RID: %8x  Group Name: %s Description: %s\n",
1686                                   group_rid,
1687                                   info->dom.sam[group_idx].acct_name,
1688                                   info->dom.sam[group_idx].acct_desc);
1689
1690                 if (request_member_info)
1691                 {
1692                         uint32 num_groups;
1693                         uint32 num_names;
1694                         uint32 attr_mem[MAX_LOOKUP_SIDS];
1695                         uint32 rid_mem [MAX_LOOKUP_SIDS];
1696                         fstring name[MAX_LOOKUP_SIDS];
1697                         uint32  type[MAX_LOOKUP_SIDS];
1698
1699                         /* send user groups query */
1700                         if (get_samr_query_groupmem(smb_cli, 
1701                                                 &info->dom.samr_pol_open_domain,
1702                                                 group_rid, &num_groups,
1703                                                 rid_mem, attr_mem) &&
1704                             samr_query_lookup_rids(smb_cli, 
1705                                                 &info->dom.samr_pol_open_domain, 0x3e8,
1706                                                 num_groups, rid_mem, 
1707                                                 &num_names, name, type))
1708                         {
1709                                 display_group_members(out_hnd, ACTION_HEADER   , num_names, name, type);
1710                                 display_group_members(out_hnd, ACTION_ENUMERATE, num_names, name, type);
1711                                 display_group_members(out_hnd, ACTION_FOOTER   , num_names, name, type);
1712                         }
1713                 }
1714         }
1715
1716         res = res ? samr_close(smb_cli, &info->dom.samr_pol_connect) : False;
1717         res = res ? samr_close(smb_cli, &info->dom.samr_pol_open_domain) : False;
1718
1719         /* close the session */
1720         cli_nt_session_close(smb_cli);
1721
1722         if (info->dom.sam != NULL)
1723         {
1724                 free(info->dom.sam);
1725         }
1726
1727         if (res)
1728         {
1729                 DEBUG(5,("cmd_sam_enum_groups: succeeded\n"));
1730         }
1731         else
1732         {
1733                 DEBUG(5,("cmd_sam_enum_groups: failed\n"));
1734         }
1735 }
1736
1737