ea44db0205a0b5dc1083e6af7d0aae0e5126dfd8
[ira/wip.git] / source3 / 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         uint16 fnum;
47         fstring srv_name;
48         fstring domain;
49         fstring sid;
50         char *new_passwd;
51         BOOL res = True;
52         char nt_newpass[516];
53         uchar nt_hshhash[16];
54         uchar nt_newhash[16];
55         uchar nt_oldhash[16];
56         char lm_newpass[516];
57         uchar lm_newhash[16];
58         uchar lm_hshhash[16];
59         uchar lm_oldhash[16];
60
61         sid_to_string(sid, &info->dom.level5_sid);
62         fstrcpy(domain, info->dom.level5_dom);
63
64         fstrcpy(srv_name, "\\\\");
65         fstrcat(srv_name, info->dest_host);
66         strupper(srv_name);
67
68         report(out_hnd, "SAM NT Password Change\n");
69
70 #if 0
71         struct pwd_info new_pwd;
72         pwd_read(&new_pwd, "New Password (ONCE: this is test code!):", True);
73 #endif
74         new_passwd = (char*)getpass("New Password (ONCE ONLY - get it right :-)");
75
76         nt_lm_owf_gen(new_passwd, lm_newhash, nt_newhash);
77         pwd_get_lm_nt_16(&(smb_cli->pwd), lm_oldhash, nt_oldhash );
78         make_oem_passwd_hash(nt_newpass, new_passwd, nt_oldhash, True);
79         make_oem_passwd_hash(lm_newpass, new_passwd, lm_oldhash, True);
80         E_old_pw_hash(lm_newhash, lm_oldhash, lm_hshhash);
81         E_old_pw_hash(lm_newhash, nt_oldhash, nt_hshhash);
82
83         cli_nt_set_ntlmssp_flgs(smb_cli,
84                                     NTLMSSP_NEGOTIATE_UNICODE |
85                                     NTLMSSP_NEGOTIATE_OEM |
86                                     NTLMSSP_NEGOTIATE_SIGN |
87                                     NTLMSSP_NEGOTIATE_SEAL |
88                                     NTLMSSP_NEGOTIATE_LM_KEY |
89                                     NTLMSSP_NEGOTIATE_NTLM |
90                                     NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
91                                     NTLMSSP_NEGOTIATE_00001000 |
92                                     NTLMSSP_NEGOTIATE_00002000);
93
94         /* open SAMR session.  */
95         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
96
97         /* establish a connection. */
98         res = res ? samr_unknown_38(smb_cli, fnum, srv_name) : False;
99
100         /* establish a connection. */
101         res = res ? samr_chgpasswd_user(smb_cli, fnum,
102                                            srv_name, smb_cli->user_name,
103                                            nt_newpass, nt_hshhash,
104                                            lm_newpass, lm_hshhash) : False;
105         /* close the session */
106         cli_nt_session_close(smb_cli, fnum);
107
108         if (res)
109         {
110                 report(out_hnd, "NT Password changed OK\n");
111         }
112         else
113         {
114                 report(out_hnd, "NT Password change FAILED\n");
115         }
116 }
117
118
119 /****************************************************************************
120 experimental SAM encryted rpc test connection
121 ****************************************************************************/
122 void cmd_sam_test(struct client_info *info)
123 {
124         uint16 fnum;
125         fstring srv_name;
126         fstring domain;
127         fstring sid;
128         BOOL res = True;
129
130         sid_to_string(sid, &info->dom.level5_sid);
131         fstrcpy(domain, info->dom.level5_dom);
132
133 /*
134         if (strlen(sid) == 0)
135         {
136                 report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
137                 return;
138         }
139 */
140         fstrcpy(srv_name, "\\\\");
141         fstrcat(srv_name, info->dest_host);
142         strupper(srv_name);
143
144         report(out_hnd, "SAM Encryption Test\n");
145
146         cli_nt_set_ntlmssp_flgs(smb_cli,
147                                     NTLMSSP_NEGOTIATE_UNICODE |
148                                     NTLMSSP_NEGOTIATE_OEM |
149                                     NTLMSSP_NEGOTIATE_SIGN |
150                                     NTLMSSP_NEGOTIATE_SEAL |
151                                     NTLMSSP_NEGOTIATE_LM_KEY |
152                                     NTLMSSP_NEGOTIATE_NTLM |
153                                     NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
154                                     NTLMSSP_NEGOTIATE_00001000 |
155                                     NTLMSSP_NEGOTIATE_00002000);
156
157         /* open SAMR session.  */
158         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
159
160         /* establish a connection. */
161         res = res ? samr_unknown_38(smb_cli, fnum, srv_name) : False;
162
163         /* close the session */
164         cli_nt_session_close(smb_cli, fnum);
165
166         if (res)
167         {
168                 DEBUG(5,("cmd_sam_test: succeeded\n"));
169         }
170         else
171         {
172                 DEBUG(5,("cmd_sam_test: failed\n"));
173         }
174 }
175
176 /****************************************************************************
177 Lookup domain in SAM server.
178 ****************************************************************************/
179 void cmd_sam_lookup_domain(struct client_info *info)
180 {
181         uint16 fnum;
182         fstring srv_name;
183         fstring domain;
184         fstring str_sid;
185         DOM_SID dom_sid;
186         BOOL res = True;
187
188         fstrcpy(srv_name, "\\\\");
189         fstrcat(srv_name, info->dest_host);
190         strupper(srv_name);
191
192         if (!next_token(NULL, domain, NULL, sizeof(domain)))
193         {
194                 report(out_hnd, "lookupdomain: <name>\n");
195                 return;
196         }
197
198         report(out_hnd, "Lookup Domain in SAM Server\n");
199
200         /* open SAMR session.  negotiate credentials */
201         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
202
203         /* establish a connection. */
204         res = res ? samr_connect(smb_cli, fnum, 
205                                 srv_name, 0x02000000,
206                                 &info->dom.samr_pol_connect) : False;
207
208         /* connect to the domain */
209         res = res ? samr_query_lookup_domain(smb_cli, fnum, 
210                     &info->dom.samr_pol_connect, domain, &dom_sid) : False;
211
212         res = res ? samr_close(smb_cli, fnum, &info->dom.samr_pol_connect) : False;
213
214         /* close the session */
215         cli_nt_session_close(smb_cli, fnum);
216
217         if (res)
218         {
219                 DEBUG(5,("cmd_sam_lookup_domain: succeeded\n"));
220
221                 sid_to_string(str_sid, &dom_sid);
222                 report(out_hnd, "%s SID: %s\n", domain, str_sid);
223                 report(out_hnd, "Lookup Domain: OK\n");
224         }
225         else
226         {
227                 DEBUG(5,("cmd_sam_lookup_domain: failed\n"));
228                 report(out_hnd, "Lookup Domain: FAILED\n");
229         }
230 }
231
232 /****************************************************************************
233 SAM delete alias member.
234 ****************************************************************************/
235 void cmd_sam_del_aliasmem(struct client_info *info)
236 {
237         uint16 fnum;
238         fstring srv_name;
239         fstring domain;
240         fstring tmp;
241         fstring sid;
242         DOM_SID sid1;
243         POLICY_HND alias_pol;
244         BOOL res = True;
245         BOOL res1 = True;
246         BOOL res2 = True;
247         uint32 ace_perms = 0x02000000; /* absolutely no idea. */
248         DOM_SID member_sid; 
249         uint32 alias_rid;
250
251         sid_copy(&sid1, &info->dom.level5_sid);
252         sid_to_string(sid, &sid1);
253         fstrcpy(domain, info->dom.level5_dom);
254
255         if (sid1.num_auths == 0)
256         {
257                 report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
258                 return;
259         }
260
261         fstrcpy(srv_name, "\\\\");
262         fstrcat(srv_name, info->dest_host);
263         strupper(srv_name);
264
265         if (!next_token(NULL, tmp, NULL, sizeof(tmp)))
266         {
267                 report(out_hnd, "delaliasmem: <alias rid> [member sid1] [member sid2] ...\n");
268                 return;
269         }
270         alias_rid = get_number(tmp);
271
272         report(out_hnd, "SAM Domain Alias Member\n");
273
274         /* open SAMR session.  negotiate credentials */
275         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
276
277         /* establish a connection. */
278         res = res ? samr_connect(smb_cli, fnum, 
279                                 srv_name, 0x02000000,
280                                 &info->dom.samr_pol_connect) : False;
281
282         /* connect to the domain */
283         res = res ? samr_open_domain(smb_cli, fnum, 
284                     &info->dom.samr_pol_connect, ace_perms, &sid1,
285                     &info->dom.samr_pol_open_domain) : False;
286
287         /* connect to the domain */
288         res1 = res ? samr_open_alias(smb_cli, fnum,
289                     &info->dom.samr_pol_open_domain,
290                     0x000f001f, alias_rid, &alias_pol) : False;
291
292         while (next_token(NULL, tmp, NULL, sizeof(tmp)) && res2 && res1)
293         {
294                 /* get a sid, delete a member from the alias */
295                 res2 = res2 ? string_to_sid(&member_sid, tmp) : False;
296                 res2 = res2 ? samr_del_aliasmem(smb_cli, fnum, &alias_pol, &member_sid) : False;
297
298                 if (res2)
299                 {
300                         report(out_hnd, "SID deleted from Alias 0x%x: %s\n", alias_rid, tmp);
301                 }
302         }
303
304         res1 = res1 ? samr_close(smb_cli, fnum, &alias_pol) : False;
305         res  = res  ? samr_close(smb_cli, fnum, &info->dom.samr_pol_open_domain) : False;
306         res  = res  ? samr_close(smb_cli, fnum, &info->dom.samr_pol_connect) : False;
307
308         /* close the session */
309         cli_nt_session_close(smb_cli, fnum);
310
311         if (res && res1 && res2)
312         {
313                 DEBUG(5,("cmd_sam_del_aliasmem: succeeded\n"));
314                 report(out_hnd, "Delete Domain Alias Member: OK\n");
315         }
316         else
317         {
318                 DEBUG(5,("cmd_sam_del_aliasmem: failed\n"));
319                 report(out_hnd, "Delete Domain Alias Member: FAILED\n");
320         }
321 }
322
323 /****************************************************************************
324 SAM delete alias.
325 ****************************************************************************/
326 void cmd_sam_delete_dom_alias(struct client_info *info)
327 {
328         uint16 fnum;
329         fstring srv_name;
330         fstring domain;
331         fstring name;
332         fstring sid;
333         DOM_SID sid1;
334         POLICY_HND alias_pol;
335         BOOL res = True;
336         BOOL res1 = True;
337         BOOL res2 = True;
338         uint32 ace_perms = 0x02000000; /* absolutely no idea. */
339         uint32 alias_rid = 0;
340         char *names[1];
341         uint32 rid [MAX_LOOKUP_SIDS];
342         uint32 type[MAX_LOOKUP_SIDS];
343         uint32 num_rids;
344
345         sid_copy(&sid1, &info->dom.level5_sid);
346         sid_to_string(sid, &sid1);
347         fstrcpy(domain, info->dom.level5_dom);
348
349         if (sid1.num_auths == 0)
350         {
351                 report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
352                 return;
353         }
354
355         fstrcpy(srv_name, "\\\\");
356         fstrcat(srv_name, info->dest_host);
357         strupper(srv_name);
358
359         if (!next_token(NULL, name, NULL, sizeof(name)))
360         {
361                 report(out_hnd, "delalias <alias name>\n");
362                 return;
363         }
364
365         report(out_hnd, "SAM Delete Domain Alias\n");
366
367         /* open SAMR session.  negotiate credentials */
368         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
369
370         /* establish a connection. */
371         res = res ? samr_connect(smb_cli, fnum, 
372                                 srv_name, 0x02000000,
373                                 &info->dom.samr_pol_connect) : False;
374
375         /* connect to the domain */
376         res = res ? samr_open_domain(smb_cli, fnum, 
377                     &info->dom.samr_pol_connect, ace_perms, &sid1,
378                     &info->dom.samr_pol_open_domain) : False;
379
380         names[0] = name;
381
382         res1 = res ? samr_query_lookup_names(smb_cli, fnum,
383                     &info->dom.samr_pol_open_domain, 0x000003e8,
384                     1, names,
385                     &num_rids, rid, type) : False;
386
387         if (res1 && num_rids == 1)
388         {
389                 alias_rid = rid[0];
390         }
391
392         /* connect to the domain */
393         res1 = res1 ? samr_open_alias(smb_cli, fnum,
394                     &info->dom.samr_pol_open_domain,
395                     0x000f001f, alias_rid, &alias_pol) : False;
396
397         res2 = res1 ? samr_delete_dom_alias(smb_cli, fnum, &alias_pol) : False;
398
399         res1 = res1 ? samr_close(smb_cli, fnum, &alias_pol) : False;
400         res  = res  ? samr_close(smb_cli, fnum, &info->dom.samr_pol_open_domain) : False;
401         res  = res  ? samr_close(smb_cli, fnum, &info->dom.samr_pol_connect) : False;
402
403         /* close the session */
404         cli_nt_session_close(smb_cli, fnum);
405
406         if (res && res1 && res2)
407         {
408                 DEBUG(5,("cmd_sam_delete_dom_alias: succeeded\n"));
409                 report(out_hnd, "Delete Domain Alias: OK\n");
410         }
411         else
412         {
413                 DEBUG(5,("cmd_sam_delete_dom_alias: failed\n"));
414                 report(out_hnd, "Delete Domain Alias: FAILED\n");
415         }
416 }
417
418 /****************************************************************************
419 SAM add alias member.
420 ****************************************************************************/
421 void cmd_sam_add_aliasmem(struct client_info *info)
422 {
423         uint16 fnum;
424         uint16 fnum_lsa;
425         fstring srv_name;
426         fstring domain;
427         fstring tmp;
428         fstring sid;
429         DOM_SID sid1;
430         POLICY_HND alias_pol;
431         BOOL res = True;
432         BOOL res1 = True;
433         BOOL res2 = True;
434         BOOL res3 = True;
435         BOOL res4 = True;
436         uint32 ace_perms = 0x02000000; /* absolutely no idea. */
437         uint32 alias_rid;
438         char **names = NULL;
439         int num_names = 0;
440         DOM_SID *sids = NULL; 
441         int num_sids = 0;
442         int i;
443
444         sid_copy(&sid1, &info->dom.level5_sid);
445         sid_to_string(sid, &sid1);
446         fstrcpy(domain, info->dom.level5_dom);
447
448         if (sid1.num_auths == 0)
449         {
450                 report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
451                 return;
452         }
453
454         fstrcpy(srv_name, "\\\\");
455         fstrcat(srv_name, info->dest_host);
456         strupper(srv_name);
457
458         while (next_token(NULL, tmp, NULL, sizeof(tmp)))
459         {
460                 num_names++;
461                 names = Realloc(names, num_names * sizeof(char*));
462                 if (names == NULL)
463                 {
464                         DEBUG(0,("Realloc returned NULL\n"));
465                         return;
466                 }
467                 names[num_names-1] = strdup(tmp);
468         }
469
470         if (num_names < 2)
471         {
472                 report(out_hnd, "addaliasmem <group name> [member name1] [member name2] ...\n");
473                 return;
474         }
475         
476         report(out_hnd, "SAM Domain Alias Member\n");
477
478         /* open LSARPC session. */
479         res3 = res3 ? cli_nt_session_open(smb_cli, PIPE_LSARPC, &fnum_lsa) : False;
480
481         /* lookup domain controller; receive a policy handle */
482         res3 = res3 ? lsa_open_policy(smb_cli, fnum_lsa,
483                                 srv_name,
484                                 &info->dom.lsa_info_pol, True) : False;
485
486         /* send lsa lookup sids call */
487         res4 = res3 ? lsa_lookup_names(smb_cli, fnum_lsa, 
488                                        &info->dom.lsa_info_pol,
489                                        num_names, names, 
490                                        &sids, NULL, &num_sids) : False;
491
492         res3 = res3 ? lsa_close(smb_cli, fnum_lsa, &info->dom.lsa_info_pol) : False;
493
494         cli_nt_session_close(smb_cli, fnum_lsa);
495
496         res4 = num_sids < 2 ? False : res4;
497
498         if (res4)
499         {
500                 /*
501                  * accept domain sid or builtin sid
502                  */
503
504                 DOM_SID sid_1_5_20;
505                 string_to_sid(&sid_1_5_20, "S-1-5-32");
506                 sid_split_rid(&sids[0], &alias_rid);
507
508                 if (sid_equal(&sids[0], &sid_1_5_20))
509                 {
510                         sid_copy(&sid1, &sid_1_5_20);
511                 }
512                 else if (!sid_equal(&sids[0], &sid1))
513                 {       
514                         res4 = False;
515                 }
516         }
517
518         /* open SAMR session.  negotiate credentials */
519         res = res4 ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
520
521         /* establish a connection. */
522         res = res ? samr_connect(smb_cli, fnum, 
523                                 srv_name, 0x02000000,
524                                 &info->dom.samr_pol_connect) : False;
525
526         /* connect to the domain */
527         res = res ? samr_open_domain(smb_cli, fnum, 
528                     &info->dom.samr_pol_connect, ace_perms, &sid1,
529                     &info->dom.samr_pol_open_domain) : False;
530
531         /* connect to the domain */
532         res1 = res ? samr_open_alias(smb_cli, fnum,
533                     &info->dom.samr_pol_open_domain,
534                     0x000f001f, alias_rid, &alias_pol) : False;
535
536         for (i = 1; i < num_sids && res2 && res1; i++)
537         {
538                 /* add a member to the alias */
539                 res2 = res2 ? samr_add_aliasmem(smb_cli, fnum, &alias_pol, &sids[i]) : False;
540
541                 if (res2)
542                 {
543                         sid_to_string(tmp, &sids[i]);
544                         report(out_hnd, "SID added to Alias 0x%x: %s\n", alias_rid, tmp);
545                 }
546         }
547
548         res1 = res1 ? samr_close(smb_cli, fnum, &alias_pol) : False;
549         res  = res  ? samr_close(smb_cli, fnum, &info->dom.samr_pol_open_domain) : False;
550         res  = res  ? samr_close(smb_cli, fnum, &info->dom.samr_pol_connect) : False;
551
552         /* close the session */
553         cli_nt_session_close(smb_cli, fnum);
554
555         if (sids != NULL)
556         {
557                 free(sids);
558         }
559         
560         free_char_array(num_names, names);
561
562         if (res && res1 && res2)
563         {
564                 DEBUG(5,("cmd_sam_add_aliasmem: succeeded\n"));
565                 report(out_hnd, "Add Domain Alias Member: OK\n");
566         }
567         else
568         {
569                 DEBUG(5,("cmd_sam_add_aliasmem: failed\n"));
570                 report(out_hnd, "Add Domain Alias Member: FAILED\n");
571         }
572 }
573
574
575 /****************************************************************************
576 SAM create domain user.
577 ****************************************************************************/
578 void cmd_sam_create_dom_user(struct client_info *info)
579 {
580         uint16 fnum;
581         fstring srv_name;
582         fstring domain;
583         fstring acct_name;
584         fstring acct_desc;
585         fstring sid;
586         DOM_SID sid1;
587         BOOL res = True;
588         BOOL res1 = True;
589         uint32 ace_perms = 0x02000000; /* absolutely no idea. */
590         uint32 user_rid; 
591
592         sid_copy(&sid1, &info->dom.level5_sid);
593         sid_to_string(sid, &sid1);
594         fstrcpy(domain, info->dom.level5_dom);
595
596         if (sid1.num_auths == 0)
597         {
598                 report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
599                 return;
600         }
601
602
603         fstrcpy(srv_name, "\\\\");
604         fstrcat(srv_name, info->dest_host);
605         strupper(srv_name);
606
607         if (!next_token(NULL, acct_name, NULL, sizeof(acct_name)))
608         {
609                 report(out_hnd, "createuser: <acct name> [acct description]\n");
610         }
611
612         if (!next_token(NULL, acct_desc, NULL, sizeof(acct_desc)))
613         {
614                 acct_desc[0] = 0;
615         }
616
617
618         report(out_hnd, "SAM Create Domain User\n");
619         report(out_hnd, "Domain: %s Name: %s Description: %s\n",
620                           domain, acct_name, acct_desc);
621
622         /* open SAMR session.  negotiate credentials */
623         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
624
625         /* establish a connection. */
626         res = res ? samr_connect(smb_cli, fnum, 
627                                 srv_name, 0x02000000,
628                                 &info->dom.samr_pol_connect) : False;
629
630         /* connect to the domain */
631         res = res ? samr_open_domain(smb_cli, fnum, 
632                     &info->dom.samr_pol_connect, ace_perms, &sid1,
633                     &info->dom.samr_pol_open_domain) : False;
634
635         /* create a domain user */
636         res1 = res ? create_samr_domain_user(smb_cli, fnum, 
637                                 &info->dom.samr_pol_open_domain,
638                                 acct_name, ACB_NORMAL, &user_rid) : False;
639
640         res = res ? samr_close(smb_cli, fnum,
641                     &info->dom.samr_pol_open_domain) : False;
642
643         res = res ? samr_close(smb_cli, fnum,
644                     &info->dom.samr_pol_connect) : False;
645
646         /* close the session */
647         cli_nt_session_close(smb_cli, fnum);
648
649         if (res && res1)
650         {
651                 DEBUG(5,("cmd_sam_create_dom_user: succeeded\n"));
652                 report(out_hnd, "Create Domain User: OK\n");
653         }
654         else
655         {
656                 DEBUG(5,("cmd_sam_create_dom_user: failed\n"));
657                 report(out_hnd, "Create Domain User: FAILED\n");
658         }
659 }
660
661
662 /****************************************************************************
663 SAM create domain alias.
664 ****************************************************************************/
665 void cmd_sam_create_dom_alias(struct client_info *info)
666 {
667         uint16 fnum;
668         fstring srv_name;
669         fstring domain;
670         fstring acct_name;
671         fstring acct_desc;
672         fstring sid;
673         DOM_SID sid1;
674         BOOL res = True;
675         BOOL res1 = True;
676         uint32 ace_perms = 0x02000000; /* permissions */
677         uint32 alias_rid; 
678
679         sid_copy(&sid1, &info->dom.level5_sid);
680         sid_to_string(sid, &sid1);
681         fstrcpy(domain, info->dom.level5_dom);
682
683         if (sid1.num_auths == 0)
684         {
685                 report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
686                 return;
687         }
688
689
690         fstrcpy(srv_name, "\\\\");
691         fstrcat(srv_name, info->dest_host);
692         strupper(srv_name);
693
694         if (!next_token(NULL, acct_name, NULL, sizeof(acct_name)))
695         {
696                 report(out_hnd, "createalias: <acct name> [acct description]\n");
697         }
698
699         if (!next_token(NULL, acct_desc, NULL, sizeof(acct_desc)))
700         {
701                 acct_desc[0] = 0;
702         }
703
704
705         report(out_hnd, "SAM Create Domain Alias\n");
706         report(out_hnd, "Domain: %s Name: %s Description: %s\n",
707                           domain, acct_name, acct_desc);
708
709         /* open SAMR session.  negotiate credentials */
710         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
711
712         /* establish a connection. */
713         res = res ? samr_connect(smb_cli, fnum, 
714                                 srv_name, 0x02000000,
715                                 &info->dom.samr_pol_connect) : False;
716
717         /* connect to the domain */
718         res = res ? samr_open_domain(smb_cli, fnum, 
719                     &info->dom.samr_pol_connect, ace_perms, &sid1,
720                     &info->dom.samr_pol_open_domain) : False;
721
722         /* create a domain alias */
723         res1 = res ? create_samr_domain_alias(smb_cli, fnum, 
724                                 &info->dom.samr_pol_open_domain,
725                                 acct_name, acct_desc, &alias_rid) : False;
726
727         res = res ? samr_close(smb_cli, fnum,
728                     &info->dom.samr_pol_open_domain) : False;
729
730         res = res ? samr_close(smb_cli, fnum,
731                     &info->dom.samr_pol_connect) : False;
732
733         /* close the session */
734         cli_nt_session_close(smb_cli, fnum);
735
736         if (res && res1)
737         {
738                 DEBUG(5,("cmd_sam_create_dom_alias: succeeded\n"));
739                 report(out_hnd, "Create Domain Alias: OK\n");
740         }
741         else
742         {
743                 DEBUG(5,("cmd_sam_create_dom_alias: failed\n"));
744                 report(out_hnd, "Create Domain Alias: FAILED\n");
745         }
746 }
747
748
749 /****************************************************************************
750 SAM delete group member.
751 ****************************************************************************/
752 void cmd_sam_del_groupmem(struct client_info *info)
753 {
754         uint16 fnum;
755         fstring srv_name;
756         fstring domain;
757         fstring tmp;
758         fstring sid;
759         DOM_SID sid1;
760         POLICY_HND group_pol;
761         BOOL res = True;
762         BOOL res1 = True;
763         BOOL res2 = True;
764         uint32 ace_perms = 0x02000000; /* absolutely no idea. */
765         uint32 member_rid; 
766         uint32 group_rid;
767
768         sid_copy(&sid1, &info->dom.level5_sid);
769         sid_to_string(sid, &sid1);
770         fstrcpy(domain, info->dom.level5_dom);
771
772         if (sid1.num_auths == 0)
773         {
774                 report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
775                 return;
776         }
777
778         fstrcpy(srv_name, "\\\\");
779         fstrcat(srv_name, info->dest_host);
780         strupper(srv_name);
781
782         if (!next_token(NULL, tmp, NULL, sizeof(tmp)))
783         {
784                 report(out_hnd, "delgroupmem: <group rid> [member rid1] [member rid2] ...\n");
785                 return;
786         }
787         group_rid = get_number(tmp);
788
789         report(out_hnd, "SAM Add Domain Group member\n");
790
791         /* open SAMR session.  negotiate credentials */
792         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
793
794         /* establish a connection. */
795         res = res ? samr_connect(smb_cli, fnum, 
796                                 srv_name, 0x02000000,
797                                 &info->dom.samr_pol_connect) : False;
798
799         /* connect to the domain */
800         res = res ? samr_open_domain(smb_cli, fnum, 
801                     &info->dom.samr_pol_connect, ace_perms, &sid1,
802                     &info->dom.samr_pol_open_domain) : False;
803
804         /* connect to the domain */
805         res1 = res ? samr_open_group(smb_cli, fnum,
806                     &info->dom.samr_pol_open_domain,
807                     0x0000001f, group_rid, &group_pol) : False;
808
809         while (next_token(NULL, tmp, NULL, sizeof(tmp)) && res2 && res1)
810         {
811                 /* get a rid, delete a member from the group */
812                 member_rid = get_number(tmp);
813                 res2 = res2 ? samr_del_groupmem(smb_cli, fnum, &group_pol, member_rid) : False;
814
815                 if (res2)
816                 {
817                         report(out_hnd, "RID deleted from Group 0x%x: 0x%x\n", group_rid, member_rid);
818                 }
819         }
820
821         res1 = res1 ? samr_close(smb_cli, fnum, &group_pol) : False;
822         res  = res  ? samr_close(smb_cli, fnum, &info->dom.samr_pol_open_domain) : False;
823         res  = res  ? samr_close(smb_cli, fnum, &info->dom.samr_pol_connect) : False;
824
825         /* close the session */
826         cli_nt_session_close(smb_cli, fnum);
827
828         if (res && res1 && res2)
829         {
830                 DEBUG(5,("cmd_sam_del_groupmem: succeeded\n"));
831                 report(out_hnd, "Add Domain Group Member: OK\n");
832         }
833         else
834         {
835                 DEBUG(5,("cmd_sam_del_groupmem: failed\n"));
836                 report(out_hnd, "Add Domain Group Member: FAILED\n");
837         }
838 }
839
840
841 /****************************************************************************
842 SAM delete group.
843 ****************************************************************************/
844 void cmd_sam_delete_dom_group(struct client_info *info)
845 {
846         uint16 fnum;
847         fstring srv_name;
848         fstring domain;
849         fstring name;
850         fstring sid;
851         DOM_SID sid1;
852         POLICY_HND group_pol;
853         BOOL res = True;
854         BOOL res1 = True;
855         BOOL res2 = True;
856         uint32 ace_perms = 0x02000000; /* absolutely no idea. */
857         uint32 group_rid = 0;
858         char *names[1];
859         uint32 rid [MAX_LOOKUP_SIDS];
860         uint32 type[MAX_LOOKUP_SIDS];
861         uint32 num_rids;
862
863         sid_copy(&sid1, &info->dom.level5_sid);
864         sid_to_string(sid, &sid1);
865         fstrcpy(domain, info->dom.level5_dom);
866
867         if (sid1.num_auths == 0)
868         {
869                 report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
870                 return;
871         }
872
873         fstrcpy(srv_name, "\\\\");
874         fstrcat(srv_name, info->dest_host);
875         strupper(srv_name);
876
877         if (!next_token(NULL, name, NULL, sizeof(name)))
878         {
879                 report(out_hnd, "delgroup <group name>\n");
880                 return;
881         }
882
883         report(out_hnd, "SAM Delete Domain Group\n");
884
885         /* open SAMR session.  negotiate credentials */
886         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
887
888         /* establish a connection. */
889         res = res ? samr_connect(smb_cli, fnum, 
890                                 srv_name, 0x02000000,
891                                 &info->dom.samr_pol_connect) : False;
892
893         /* connect to the domain */
894         res = res ? samr_open_domain(smb_cli, fnum, 
895                     &info->dom.samr_pol_connect, ace_perms, &sid1,
896                     &info->dom.samr_pol_open_domain) : False;
897
898         names[0] = name;
899
900         res1 = res ? samr_query_lookup_names(smb_cli, fnum,
901                     &info->dom.samr_pol_open_domain, 0x000003e8,
902                     1, names,
903                     &num_rids, rid, type) : False;
904
905         if (res1 && num_rids == 1)
906         {
907                 group_rid = rid[0];
908         }
909
910         /* connect to the domain */
911         res1 = res1 ? samr_open_group(smb_cli, fnum,
912                     &info->dom.samr_pol_open_domain,
913                     0x0000001f, group_rid, &group_pol) : False;
914
915         res2 = res1 ? samr_delete_dom_group(smb_cli, fnum, &group_pol) : False;
916
917         res1 = res1 ? samr_close(smb_cli, fnum, &group_pol) : False;
918         res  = res  ? samr_close(smb_cli, fnum, &info->dom.samr_pol_open_domain) : False;
919         res  = res  ? samr_close(smb_cli, fnum, &info->dom.samr_pol_connect) : False;
920
921         /* close the session */
922         cli_nt_session_close(smb_cli, fnum);
923
924         if (res && res1 && res2)
925         {
926                 DEBUG(5,("cmd_sam_delete_dom_group: succeeded\n"));
927                 report(out_hnd, "Delete Domain Group: OK\n");
928         }
929         else
930         {
931                 DEBUG(5,("cmd_sam_delete_dom_group: failed\n"));
932                 report(out_hnd, "Delete Domain Group: FAILED\n");
933         }
934 }
935
936
937 /****************************************************************************
938 SAM add group member.
939 ****************************************************************************/
940 void cmd_sam_add_groupmem(struct client_info *info)
941 {
942         uint16 fnum;
943         fstring srv_name;
944         fstring domain;
945         fstring tmp;
946         fstring sid;
947         DOM_SID sid1;
948         POLICY_HND group_pol;
949         BOOL res = True;
950         BOOL res1 = True;
951         BOOL res2 = True;
952         uint32 ace_perms = 0x02000000; /* absolutely no idea. */
953         uint32 *group_rid = NULL;
954         uint32 *group_type = NULL;
955         char **names = NULL;
956         uint32 num_names = 0;
957         fstring group_name;
958         char *group_names[1];
959         uint32 rid [MAX_LOOKUP_SIDS];
960         uint32 type[MAX_LOOKUP_SIDS];
961         uint32 num_rids;
962         uint32 num_group_rids;
963         int i;
964         DOM_SID sid_1_5_20;
965         string_to_sid(&sid_1_5_20, "S-1-5-32");
966
967         sid_copy(&sid1, &info->dom.level5_sid);
968         sid_to_string(sid, &sid1);
969         fstrcpy(domain, info->dom.level5_dom);
970
971         if (sid1.num_auths == 0)
972         {
973                 report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
974                 return;
975         }
976
977         fstrcpy(srv_name, "\\\\");
978         fstrcat(srv_name, info->dest_host);
979         strupper(srv_name);
980
981         res = next_token(NULL, group_name, NULL, sizeof(group_name));
982         group_names[0] = group_name;
983
984         while (res && next_token(NULL, tmp, NULL, sizeof(tmp)))
985         {
986                 num_names++;
987                 names = Realloc(names, num_names * sizeof(char*));
988                 if (names == NULL)
989                 {
990                         DEBUG(0,("Realloc returned NULL\n"));
991                         return;
992                 }
993                 names[num_names-1] = strdup(tmp);
994         }
995
996         if (num_names < 1)
997         {
998                 report(out_hnd, "addgroupmem <group name> [member name1] [member name2] ...\n");
999                 return;
1000         }
1001         
1002         report(out_hnd, "SAM Add Domain Group member\n");
1003
1004         /* open SAMR session.  negotiate credentials */
1005         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
1006
1007         /* establish a connection. */
1008         res = res ? samr_connect(smb_cli, fnum, 
1009                                 srv_name, 0x02000000,
1010                                 &info->dom.samr_pol_connect) : False;
1011
1012         /* connect to the domain */
1013         res1 = res ? samr_open_domain(smb_cli, fnum, 
1014                     &info->dom.samr_pol_connect, ace_perms, &sid1,
1015                     &info->dom.samr_pol_open_domain) : False;
1016
1017         /* connect to the domain */
1018         res1 = res1 ? samr_open_domain(smb_cli, fnum, 
1019                     &info->dom.samr_pol_connect, ace_perms, &sid_1_5_20,
1020                     &info->dom.samr_pol_open_builtindom) : False;
1021
1022         res2 = res1 ? samr_query_lookup_names(smb_cli, fnum,
1023                     &info->dom.samr_pol_open_domain, 0x000003e8,
1024                     1, group_names,
1025                     &num_group_rids, group_rid, group_type) : False;
1026
1027         /* open the group */
1028         res2 = res2 ? samr_open_group(smb_cli, fnum,
1029                     &info->dom.samr_pol_open_domain,
1030                     0x0000001f, group_rid[0], &group_pol) : False;
1031
1032         if (!res2 || (group_type != NULL && group_type[0] == SID_NAME_UNKNOWN))
1033         {
1034                 res2 = res1 ? samr_query_lookup_names(smb_cli, fnum,
1035                             &info->dom.samr_pol_open_builtindom, 0x000003e8,
1036                             1, group_names, 
1037                             &num_group_rids, group_rid, group_type) : False;
1038
1039                 /* open the group */
1040                 res2 = res2 ? samr_open_group(smb_cli, fnum,
1041                             &info->dom.samr_pol_open_builtindom,
1042                             0x0000001f, group_rid[0], &group_pol) : False;
1043         }
1044
1045         if (group_type[0] == SID_NAME_ALIAS)
1046         {
1047                 report(out_hnd, "%s is a local alias, not a group.  Use addaliasmem command instead\n",
1048                         group_name);
1049                 return;
1050         }
1051         res1 = res2 ? samr_query_lookup_names(smb_cli, fnum,
1052                     &info->dom.samr_pol_open_domain, 0x000003e8,
1053                     num_names, names,
1054                     &num_rids, rid, type) : False;
1055
1056         for (i = 0; i < num_rids && res2 && res1; i++)
1057         {
1058                 res2 = res2 ? samr_add_groupmem(smb_cli, fnum, &group_pol, rid[i]) : False;
1059
1060                 if (res2)
1061                 {
1062                         report(out_hnd, "RID added to Group 0x%x: 0x%x\n",
1063                                          group_rid[0], rid[i]);
1064                 }
1065         }
1066
1067         res1 = res ? samr_close(smb_cli, fnum, &group_pol) : False;
1068         res1 = res ? samr_close(smb_cli, fnum, &info->dom.samr_pol_open_builtindom) : False;
1069         res1 = res ? samr_close(smb_cli, fnum, &info->dom.samr_pol_open_domain) : False;
1070         res  = res ? samr_close(smb_cli, fnum, &info->dom.samr_pol_connect) : False;
1071
1072         /* close the session */
1073         cli_nt_session_close(smb_cli, fnum);
1074
1075         free_char_array(num_names, names);
1076         
1077         if (res && res1 && res2)
1078         {
1079                 DEBUG(5,("cmd_sam_add_groupmem: succeeded\n"));
1080                 report(out_hnd, "Add Domain Group Member: OK\n");
1081         }
1082         else
1083         {
1084                 DEBUG(5,("cmd_sam_add_groupmem: failed\n"));
1085                 report(out_hnd, "Add Domain Group Member: FAILED\n");
1086         }
1087
1088         if (group_rid != NULL)
1089         {
1090                 free(group_rid);
1091         }
1092         if (group_type != NULL)
1093         {
1094                 free(group_type);
1095         }
1096 }
1097
1098
1099 /****************************************************************************
1100 SAM create domain group.
1101 ****************************************************************************/
1102 void cmd_sam_create_dom_group(struct client_info *info)
1103 {
1104         uint16 fnum;
1105         fstring srv_name;
1106         fstring domain;
1107         fstring acct_name;
1108         fstring acct_desc;
1109         fstring sid;
1110         DOM_SID sid1;
1111         BOOL res = True;
1112         BOOL res1 = True;
1113         uint32 ace_perms = 0x02000000; /* absolutely no idea. */
1114         uint32 group_rid; 
1115
1116         sid_copy(&sid1, &info->dom.level5_sid);
1117         sid_to_string(sid, &sid1);
1118         fstrcpy(domain, info->dom.level5_dom);
1119
1120         if (sid1.num_auths == 0)
1121         {
1122                 report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
1123                 return;
1124         }
1125
1126
1127         fstrcpy(srv_name, "\\\\");
1128         fstrcat(srv_name, info->dest_host);
1129         strupper(srv_name);
1130
1131         if (!next_token(NULL, acct_name, NULL, sizeof(acct_name)))
1132         {
1133                 report(out_hnd, "creategroup: <acct name> [acct description]\n");
1134         }
1135
1136         if (!next_token(NULL, acct_desc, NULL, sizeof(acct_desc)))
1137         {
1138                 acct_desc[0] = 0;
1139         }
1140
1141
1142         report(out_hnd, "SAM Create Domain Group\n");
1143         report(out_hnd, "Domain: %s Name: %s Description: %s\n",
1144                           domain, acct_name, acct_desc);
1145
1146         /* open SAMR session.  negotiate credentials */
1147         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
1148
1149         /* establish a connection. */
1150         res = res ? samr_connect(smb_cli, fnum, 
1151                                 srv_name, 0x02000000,
1152                                 &info->dom.samr_pol_connect) : False;
1153
1154         /* connect to the domain */
1155         res = res ? samr_open_domain(smb_cli, fnum, 
1156                     &info->dom.samr_pol_connect, ace_perms, &sid1,
1157                     &info->dom.samr_pol_open_domain) : False;
1158
1159         /* read some users */
1160         res1 = res ? create_samr_domain_group(smb_cli, fnum, 
1161                                 &info->dom.samr_pol_open_domain,
1162                                 acct_name, acct_desc, &group_rid) : False;
1163
1164         res = res ? samr_close(smb_cli, fnum,
1165                     &info->dom.samr_pol_open_domain) : False;
1166
1167         res = res ? samr_close(smb_cli, fnum,
1168                     &info->dom.samr_pol_connect) : False;
1169
1170         /* close the session */
1171         cli_nt_session_close(smb_cli, fnum);
1172
1173         if (res && res1)
1174         {
1175                 DEBUG(5,("cmd_sam_create_dom_group: succeeded\n"));
1176                 report(out_hnd, "Create Domain Group: OK\n");
1177         }
1178         else
1179         {
1180                 DEBUG(5,("cmd_sam_create_dom_group: failed\n"));
1181                 report(out_hnd, "Create Domain Group: FAILED\n");
1182         }
1183 }
1184
1185 static void req_user_info(struct client_info *info, uint16 fnum,
1186                                 uint32 user_rid)
1187 {
1188         SAM_USER_INFO_21 usr;
1189         /* send user info query, level 0x15 */
1190         if (get_samr_query_userinfo(smb_cli, fnum,
1191                                     &info->dom.samr_pol_open_domain,
1192                                     0x15, user_rid, &usr))
1193         {
1194                 display_sam_user_info_21(out_hnd, ACTION_HEADER   , &usr);
1195                 display_sam_user_info_21(out_hnd, ACTION_ENUMERATE, &usr);
1196                 display_sam_user_info_21(out_hnd, ACTION_FOOTER   , &usr);
1197         }
1198 }
1199
1200 static void query_groupinfo(struct client_info *info, uint16 fnum,
1201                                 uint32 group_rid)
1202 {
1203         GROUP_INFO_CTR ctr;
1204
1205         /* send group info query */
1206         if (get_samr_query_groupinfo(smb_cli, fnum,
1207                                       &info->dom.samr_pol_open_domain,
1208                                       1, group_rid, &ctr))
1209         {
1210 #if 0
1211                 display_samr_groupinfo(out_hnd, ACTION_HEADER   , &ctr);
1212                 display_samr_groupinfo(out_hnd, ACTION_ENUMERATE, &ctr);
1213                 display_samr_groupinfo(out_hnd, ACTION_FOOTER   , &ctr);
1214 #endif
1215         }
1216 }
1217
1218 static void req_group_info(struct client_info *info, uint16 fnum,
1219                                 uint32 user_rid)
1220 {
1221         uint32 num_groups;
1222         DOM_GID *gid = NULL;
1223
1224         /* send user group query */
1225         if (get_samr_query_usergroups(smb_cli, fnum,
1226                                       &info->dom.samr_pol_open_domain,
1227                                       user_rid, &num_groups, &gid) &&
1228             gid != NULL)
1229         {
1230                 int i;
1231                 uint32 num_names;
1232                 uint32  *rid_mem = NULL;
1233                 char    **name   = NULL;
1234                 uint32  *type    = NULL;
1235
1236                 rid_mem = malloc(num_groups * sizeof(rid_mem[0]));
1237
1238                 if (rid_mem == NULL)
1239                 {
1240                         free(gid);
1241                         return;
1242                 }
1243
1244                 for (i = 0; i < num_groups; i++)
1245                 {
1246                         rid_mem[i] = gid[i].g_rid;
1247                 }
1248
1249                 if (samr_query_lookup_rids(smb_cli, fnum, 
1250                                 &info->dom.samr_pol_open_domain, 0x3e8,
1251                                 num_groups, rid_mem, 
1252                                 &num_names, &name, &type))
1253                 {
1254                         display_group_members(out_hnd, ACTION_HEADER   , num_names, name, type);
1255                         display_group_members(out_hnd, ACTION_ENUMERATE, num_names, name, type);
1256                         display_group_members(out_hnd, ACTION_FOOTER   , num_names, name, type);
1257                 }
1258
1259                 free_char_array(num_names, name);
1260                 if (type != NULL)
1261                 {
1262                         free(type);
1263                 }
1264         }
1265
1266         if (gid != NULL)
1267         {
1268                 free(gid);
1269         }
1270 }
1271
1272 static void req_alias_info(struct client_info *info, uint16 fnum,
1273                                 DOM_SID *sid1, uint32 user_rid)
1274 {
1275         uint32 num_aliases;
1276         uint32 *rid = NULL;
1277         uint32 *ptr_sid;
1278         DOM_SID2 *als_sid;
1279
1280         ptr_sid = malloc(sizeof(ptr_sid[0]) * 1);
1281         als_sid = malloc(sizeof(als_sid[0]) * 1);
1282
1283         make_dom_sid2(&als_sid[0], sid1);
1284         sid_append_rid(&als_sid[0].sid, user_rid);
1285
1286         ptr_sid[0] = 1;
1287
1288         /* send user alias query */
1289         if (samr_query_useraliases(smb_cli, fnum,
1290                                 &info->dom.samr_pol_open_domain,
1291                                 ptr_sid, als_sid, &num_aliases, &rid))
1292         {
1293                 uint32 num_names;
1294                 char    **name = NULL;
1295                 uint32  *type = NULL;
1296
1297                 if (samr_query_lookup_rids(smb_cli, fnum, 
1298                                 &info->dom.samr_pol_open_domain, 0x3e8,
1299                                 num_aliases, rid, 
1300                                 &num_names, &name, &type))
1301                 {
1302                         display_group_members(out_hnd, ACTION_HEADER   , num_names, name, type);
1303                         display_group_members(out_hnd, ACTION_ENUMERATE, num_names, name, type);
1304                         display_group_members(out_hnd, ACTION_FOOTER   , num_names, name, type);
1305                 }
1306
1307                 free_char_array(num_names, name);
1308                 if (type != NULL)
1309                 {
1310                         free(type);
1311                 }
1312         }
1313
1314         /* send user alias query */
1315         if (samr_query_useraliases(smb_cli, fnum,
1316                                 &info->dom.samr_pol_open_builtindom,
1317                                 ptr_sid, als_sid, &num_aliases, &rid))
1318         {
1319                 uint32 num_names;
1320                 char **name = NULL;
1321                 uint32  *type = NULL;
1322
1323                 if (samr_query_lookup_rids(smb_cli, fnum, 
1324                                 &info->dom.samr_pol_open_builtindom, 0x3e8,
1325                                 num_aliases, rid, 
1326                                 &num_names, &name, &type))
1327                 {
1328                         display_group_members(out_hnd, ACTION_HEADER   , num_names, name, type);
1329                         display_group_members(out_hnd, ACTION_ENUMERATE, num_names, name, type);
1330                         display_group_members(out_hnd, ACTION_FOOTER   , num_names, name, type);
1331                 }
1332                 free_char_array(num_names, name);
1333                 if (type != NULL)
1334                 {
1335                         free(type);
1336                 }
1337         }
1338
1339         if (ptr_sid != NULL)
1340         {
1341                 free(ptr_sid);
1342                 ptr_sid = NULL;
1343         }
1344         if (als_sid != NULL)
1345         {
1346                 free(als_sid);
1347                 als_sid = NULL;
1348         }
1349 }
1350
1351 /****************************************************************************
1352 experimental SAM users enum.
1353 ****************************************************************************/
1354 int msrpc_sam_enum_users(struct client_info *info,
1355                         BOOL request_user_info,
1356                         BOOL request_group_info,
1357                         BOOL request_alias_info)
1358 {
1359         uint16 fnum;
1360         fstring srv_name;
1361         fstring domain;
1362         fstring sid;
1363         DOM_SID sid1;
1364         DOM_SID sid_1_5_20;
1365         int user_idx;
1366         BOOL res = True;
1367         BOOL res1 = True;
1368         uint32 start_idx = 0x0;
1369         uint16 unk_0 = 0x0;
1370         uint16 acb_mask = 0;
1371         uint16 unk_1 = 0x0;
1372         uint32 ace_perms = 0x304; /* access control permissions */
1373         uint32 status = STATUS_MORE_ENTRIES;
1374
1375         sid_copy(&sid1, &info->dom.level5_sid);
1376         sid_to_string(sid, &sid1);
1377         fstrcpy(domain, info->dom.level5_dom);
1378
1379         info->dom.sam = NULL;
1380         info->dom.num_sam_entries = 0;
1381
1382         if (sid1.num_auths == 0)
1383         {
1384                 report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
1385                 return 0;
1386         }
1387
1388
1389         fstrcpy(srv_name, "\\\\");
1390         fstrcat(srv_name, info->dest_host);
1391         strupper(srv_name);
1392
1393         string_to_sid(&sid_1_5_20, "S-1-5-32");
1394
1395         report(out_hnd, "SAM Enumerate Users\n");
1396         report(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
1397                           info->myhostname, srv_name, domain, sid);
1398
1399         DEBUG(5,("Number of entries:%d unk_0:%04x acb_mask:%04x unk_1:%04x\n",
1400                   start_idx, unk_0, acb_mask, unk_1));
1401
1402         /* open SAMR session.  negotiate credentials */
1403         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
1404
1405         /* establish a connection. */
1406         res = res ? samr_connect(smb_cli, fnum, 
1407                                 srv_name, 0x02000000,
1408                                 &info->dom.samr_pol_connect) : False;
1409
1410         /* connect to the domain */
1411         res1 = res ? samr_open_domain(smb_cli, fnum, 
1412                     &info->dom.samr_pol_connect, ace_perms, &sid1,
1413                     &info->dom.samr_pol_open_domain) : False;
1414
1415 #if 0
1416         /* connect to the S-1-5-20 domain */
1417         res1 = res ? samr_open_domain(smb_cli, fnum, 
1418                     &info->dom.samr_pol_connect, ace_perms, &sid_1_5_20,
1419                     &info->dom.samr_pol_open_builtindom) : False;
1420 #endif
1421
1422         /* read some users */
1423         while (res1 && status == STATUS_MORE_ENTRIES)
1424         {
1425                 status = samr_enum_dom_users(smb_cli, fnum, 
1426                      &info->dom.samr_pol_open_domain,
1427                      &start_idx, acb_mask, unk_1, 0x01,
1428                      &info->dom.sam, &info->dom.num_sam_entries);
1429         }
1430                         
1431
1432         if (res1 && info->dom.num_sam_entries == 0)
1433         {
1434                 report(out_hnd, "No users\n");
1435         }
1436
1437         if (res1)
1438         {
1439                 /* query all the users */
1440                 for (user_idx = 0; res && user_idx <
1441                               info->dom.num_sam_entries; user_idx++)
1442                 {
1443                         uint32 user_rid = info->dom.sam[user_idx].rid;
1444
1445                         report(out_hnd, "User RID: %8x  User Name: %s\n",
1446                                 user_rid,
1447                                 info->dom.sam[user_idx].acct_name);
1448
1449                         if (request_group_info)
1450                         {
1451                                 req_group_info(info, fnum, user_rid);
1452                         }
1453
1454                         if (request_user_info)
1455                         {
1456                                 req_user_info(info, fnum, user_rid);
1457                         }
1458
1459                         if (request_alias_info)
1460                         {
1461                                 req_alias_info(info, fnum, &sid1, user_rid);
1462                         }
1463                 }
1464         }
1465
1466 #if 0
1467         res1 = res1 ? samr_close(smb_cli, fnum,
1468                     &info->dom.samr_pol_open_builtindom) : False;
1469 #endif
1470
1471         res = res ? samr_close(smb_cli, fnum,
1472                     &info->dom.samr_pol_open_domain) : False;
1473
1474         res = res ? samr_close(smb_cli, fnum,
1475                     &info->dom.samr_pol_connect) : False;
1476
1477         /* close the session */
1478         cli_nt_session_close(smb_cli, fnum);
1479
1480         if (res)
1481         {
1482                 DEBUG(5,("msrpc_sam_enum_users: succeeded\n"));
1483         }
1484         else
1485         {
1486                 DEBUG(5,("msrpc_sam_enum_users: failed\n"));
1487         }
1488
1489         return info->dom.num_sam_entries;
1490 }
1491
1492
1493 /****************************************************************************
1494 experimental SAM users enum.
1495 ****************************************************************************/
1496 void cmd_sam_enum_users(struct client_info *info)
1497 {
1498         BOOL request_user_info  = False;
1499         BOOL request_group_info = False;
1500         BOOL request_alias_info = False;
1501         fstring tmp;
1502         int i;
1503
1504         for (i = 0; i < 3; i++)
1505         {
1506                 /* a bad way to do token parsing... */
1507                 if (next_token(NULL, tmp, NULL, sizeof(tmp)))
1508                 {
1509                         request_user_info  |= strequal(tmp, "-u");
1510                         request_group_info |= strequal(tmp, "-g");
1511                         request_alias_info |= strequal(tmp, "-a");
1512                 }
1513                 else
1514                 {
1515                         break;
1516                 }
1517         }
1518
1519         msrpc_sam_enum_users(info,
1520                              request_user_info,
1521                              request_group_info,
1522                              request_alias_info);
1523
1524         if (info->dom.sam != NULL)
1525         {
1526                 free(info->dom.sam);
1527         }
1528 }
1529
1530
1531 /****************************************************************************
1532 experimental SAM user query.
1533 ****************************************************************************/
1534 void cmd_sam_query_user(struct client_info *info)
1535 {
1536         uint16 fnum;
1537         fstring srv_name;
1538         fstring domain;
1539         fstring sid_str;
1540         DOM_SID sid;
1541         BOOL res = True;
1542         BOOL res1 = True;
1543
1544         fstring user_name;
1545         char *names[1];
1546         uint32 num_rids;
1547         uint32 rid[MAX_LOOKUP_SIDS];
1548         uint32 type[MAX_LOOKUP_SIDS];
1549         uint32 info_level = 0x15;
1550         SAM_USER_INFO_21 usr;
1551
1552         fstrcpy(domain, info->dom.level5_dom);
1553         sid_copy(&sid, &info->dom.level5_sid);
1554
1555         if (sid.num_auths == 0)
1556         {
1557                 report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
1558                 return;
1559         }
1560
1561         if (!next_token(NULL, user_name, NULL, sizeof(user_name)))
1562         {
1563                 report(out_hnd, "samuser <name>\n");
1564                 return;
1565         }
1566
1567         fstrcpy(srv_name, "\\\\");
1568         fstrcat(srv_name, info->dest_host);
1569         strupper(srv_name);
1570
1571         sid_to_string(sid_str, &sid);
1572
1573         report(out_hnd, "SAM Query User: %s\n", user_name);
1574         report(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
1575                           info->myhostname, srv_name, domain, sid_str);
1576
1577         /* open SAMR session.  negotiate credentials */
1578         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
1579
1580         /* establish a connection. */
1581         res = res ? samr_connect(smb_cli, fnum,
1582                                 srv_name, 0x02000000,
1583                                 &info->dom.samr_pol_connect) : False;
1584
1585         /* connect to the domain */
1586         res = res ? samr_open_domain(smb_cli, fnum,
1587                     &info->dom.samr_pol_connect, 0x304, &sid,
1588                     &info->dom.samr_pol_open_domain) : False;
1589
1590         /* look up user rid */
1591         names[0] = user_name;
1592         res1 = res ? samr_query_lookup_names(smb_cli, fnum,
1593                                         &info->dom.samr_pol_open_domain, 0x3e8,
1594                                         1, names,
1595                                         &num_rids, rid, type) : False;
1596
1597         /* send user info query */
1598         res1 = (res1 && num_rids == 1) ? get_samr_query_userinfo(smb_cli, fnum,
1599                                          &info->dom.samr_pol_open_domain,
1600                                          info_level, rid[0], &usr) : False;
1601
1602         res = res ? samr_close(smb_cli, fnum,
1603                     &info->dom.samr_pol_connect) : False;
1604
1605         res = res ? samr_close(smb_cli, fnum,
1606                     &info->dom.samr_pol_open_domain) : False;
1607
1608         /* close the session */
1609         cli_nt_session_close(smb_cli, fnum);
1610
1611         if (res1)
1612         {
1613                 display_sam_user_info_21(out_hnd, ACTION_HEADER   , &usr);
1614                 display_sam_user_info_21(out_hnd, ACTION_ENUMERATE, &usr);
1615                 display_sam_user_info_21(out_hnd, ACTION_FOOTER   , &usr);
1616
1617                 DEBUG(5,("cmd_sam_query_user: succeeded\n"));
1618         }
1619         else
1620         {
1621                 DEBUG(5,("cmd_sam_query_user: failed\n"));
1622         }
1623 }
1624
1625
1626 /****************************************************************************
1627 experimental SAM query display info.
1628 ****************************************************************************/
1629 void cmd_sam_query_dispinfo(struct client_info *info)
1630 {
1631         uint16 fnum;
1632         fstring srv_name;
1633         fstring domain;
1634         fstring sid;
1635         DOM_SID sid1;
1636         BOOL res = True;
1637         fstring info_str;
1638         uint16 switch_value = 1;
1639         uint32 ace_perms = 0x304; /* absolutely no idea. */
1640         SAM_DISPINFO_CTR ctr;
1641         SAM_DISPINFO_1 inf1;
1642         uint32 num_entries;
1643
1644         sid_to_string(sid, &info->dom.level5_sid);
1645         fstrcpy(domain, info->dom.level5_dom);
1646
1647         if (strlen(sid) == 0)
1648         {
1649                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
1650                 return;
1651         }
1652
1653         string_to_sid(&sid1, sid);
1654
1655         fstrcpy(srv_name, "\\\\");
1656         fstrcat(srv_name, info->dest_host);
1657         strupper(srv_name);
1658
1659         if (next_token(NULL, info_str, NULL, sizeof(info_str)))
1660         {
1661                 switch_value = strtoul(info_str, (char**)NULL, 10);
1662         }
1663
1664         fprintf(out_hnd, "SAM Query Domain Info: info level %d\n", switch_value);
1665         fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
1666                           info->myhostname, srv_name, domain, sid);
1667
1668         /* open SAMR session.  negotiate credentials */
1669         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
1670
1671         /* establish a connection. */
1672         res = res ? samr_connect(smb_cli, fnum, 
1673                                 srv_name, 0x02000000,
1674                                 &info->dom.samr_pol_connect) : False;
1675
1676         /* connect to the domain */
1677         res = res ? samr_open_domain(smb_cli, fnum, 
1678                     &info->dom.samr_pol_connect, ace_perms, &sid1,
1679                     &info->dom.samr_pol_open_domain) : False;
1680
1681         ctr.sam.info1 = &inf1;
1682
1683         /* send a samr query_disp_info command */
1684         res = res ? samr_query_dispinfo(smb_cli, fnum,
1685                     &info->dom.samr_pol_open_domain, switch_value, 
1686                     &num_entries, &ctr) : False;
1687
1688         res = res ? samr_close(smb_cli, fnum,
1689                     &info->dom.samr_pol_connect) : False;
1690
1691         res = res ? samr_close(smb_cli, fnum, 
1692                     &info->dom.samr_pol_open_domain) : False;
1693
1694         /* close the session */
1695         cli_nt_session_close(smb_cli, fnum);
1696
1697         if (res)
1698         {
1699                 DEBUG(5,("cmd_sam_query_dispinfo: succeeded\n"));
1700 #if 0
1701                 display_sam_disp_info_ctr(out_hnd, ACTION_HEADER   , switch_value, &ctr);
1702                 display_sam_disp_info_ctr(out_hnd, ACTION_ENUMERATE, switch_value, &ctr);
1703                 display_sam_disp_info_ctr(out_hnd, ACTION_FOOTER   , switch_value, &ctr);
1704 #endif
1705         }
1706         else
1707         {
1708                 DEBUG(5,("cmd_sam_query_dispinfo: failed\n"));
1709         }
1710 }
1711
1712
1713 /****************************************************************************
1714 experimental SAM domain info query.
1715 ****************************************************************************/
1716 BOOL sam_query_dominfo(struct client_info *info, DOM_SID *sid1,
1717                                 uint32 switch_value, SAM_UNK_CTR *ctr)
1718 {
1719         uint16 fnum;
1720         fstring srv_name;
1721         BOOL res = True;
1722         BOOL res1 = True;
1723         BOOL res2 = True;
1724         uint32 ace_perms = 0x02000000; /* absolutely no idea. */
1725
1726         fstrcpy(srv_name, "\\\\");
1727         fstrcat(srv_name, info->dest_host);
1728         strupper(srv_name);
1729
1730         /* open SAMR session.  negotiate credentials */
1731         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
1732
1733         /* establish a connection. */
1734         res = res ? samr_connect(smb_cli, fnum, 
1735                                 srv_name, 0x02000000,
1736                                 &info->dom.samr_pol_connect) : False;
1737
1738         /* connect to the domain */
1739         res1 = res ? samr_open_domain(smb_cli, fnum, 
1740                     &info->dom.samr_pol_connect, ace_perms, sid1,
1741                     &info->dom.samr_pol_open_domain) : False;
1742
1743         /* send a samr 0x8 command */
1744         res2 = res ? samr_query_dom_info(smb_cli, fnum,
1745                     &info->dom.samr_pol_open_domain, switch_value, ctr) : False;
1746
1747         res1 = res1 ? samr_close(smb_cli, fnum,
1748                     &info->dom.samr_pol_connect) : False;
1749
1750         res = res ? samr_close(smb_cli, fnum, 
1751                     &info->dom.samr_pol_open_domain) : False;
1752
1753         /* close the session */
1754         cli_nt_session_close(smb_cli, fnum);
1755
1756         if (res2)
1757         {
1758                 DEBUG(5,("sam_query_dominfo: succeeded\n"));
1759         }
1760         else
1761         {
1762                 DEBUG(5,("sam_query_dominfo: failed\n"));
1763         }
1764
1765         return res2;
1766 }
1767
1768
1769 /****************************************************************************
1770 experimental SAM domain info query.
1771 ****************************************************************************/
1772 void cmd_sam_query_dominfo(struct client_info *info)
1773 {
1774         fstring domain;
1775         fstring sid;
1776         DOM_SID sid1;
1777         fstring info_str;
1778         uint32 switch_value = 2;
1779         SAM_UNK_CTR ctr;
1780
1781         sid_to_string(sid, &info->dom.level5_sid);
1782         fstrcpy(domain, info->dom.level5_dom);
1783
1784         if (strlen(sid) == 0)
1785         {
1786                 report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
1787                 return;
1788         }
1789
1790         string_to_sid(&sid1, sid);
1791
1792         if (next_token(NULL, info_str, NULL, sizeof(info_str)))
1793         {
1794                 switch_value = strtoul(info_str, (char**)NULL, 10);
1795         }
1796
1797         report(out_hnd, "SAM Query Domain Info: info level %d\n", switch_value);
1798         report(out_hnd, "From: %s Domain: %s SID: %s\n",
1799                           info->myhostname, domain, sid);
1800
1801         if (sam_query_dominfo(info, &sid1, switch_value, &ctr))
1802         {
1803                 DEBUG(5,("cmd_sam_query_dominfo: succeeded\n"));
1804                 display_sam_unk_ctr(out_hnd, ACTION_HEADER   , switch_value, &ctr);
1805                 display_sam_unk_ctr(out_hnd, ACTION_ENUMERATE, switch_value, &ctr);
1806                 display_sam_unk_ctr(out_hnd, ACTION_FOOTER   , switch_value, &ctr);
1807         }
1808         else
1809         {
1810                 DEBUG(5,("cmd_sam_query_dominfo: failed\n"));
1811         }
1812 }
1813
1814
1815 /****************************************************************************
1816 SAM aliases query.
1817 ****************************************************************************/
1818 void cmd_sam_enum_aliases(struct client_info *info)
1819 {
1820         uint16 fnum;
1821         fstring srv_name;
1822         fstring domain;
1823         fstring sid;
1824         DOM_SID sid1;
1825         BOOL res = True;
1826         BOOL request_member_info = False;
1827         uint32 ace_perms = 0x02000000; /* access control permissions */
1828         fstring tmp;
1829         uint32 alias_idx;
1830
1831         sid_to_string(sid, &info->dom.level5_sid);
1832         fstrcpy(domain, info->dom.level5_dom);
1833 #if 0
1834         fstrcpy(sid   , "S-1-5-20");
1835 #endif
1836         if (strlen(sid) == 0)
1837         {
1838                 report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
1839                 return;
1840         }
1841
1842         string_to_sid(&sid1, sid);
1843
1844         fstrcpy(srv_name, "\\\\");
1845         fstrcat(srv_name, info->dest_host);
1846         strupper(srv_name);
1847
1848         /* a bad way to do token parsing... */
1849         if (next_token(NULL, tmp, NULL, sizeof(tmp)))
1850         {
1851                 request_member_info |= strequal(tmp, "-m");
1852         }
1853
1854         report(out_hnd, "SAM Enumerate Aliases\n");
1855         report(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
1856                           info->myhostname, srv_name, domain, sid);
1857
1858         /* open SAMR session.  negotiate credentials */
1859         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
1860
1861         /* establish a connection. */
1862         res = res ? samr_connect(smb_cli, fnum,
1863                                 srv_name, 0x02000000,
1864                                 &info->dom.samr_pol_connect) : False;
1865
1866         /* connect to the domain */
1867         res = res ? samr_open_domain(smb_cli, fnum,
1868                     &info->dom.samr_pol_connect, ace_perms, &sid1,
1869                     &info->dom.samr_pol_open_domain) : False;
1870
1871         info->dom.sam = NULL;
1872
1873         /* read some aliases */
1874         res = res ? samr_enum_dom_aliases(smb_cli, fnum,
1875                                 &info->dom.samr_pol_open_domain,
1876                                 0x0, 0xffff,
1877                                 &info->dom.sam, &info->dom.num_sam_entries) : False;
1878
1879         if (res && info->dom.num_sam_entries == 0)
1880         {
1881                 report(out_hnd, "No aliases\n");
1882         }
1883
1884         if (res)
1885         {
1886         for (alias_idx = 0; alias_idx < info->dom.num_sam_entries; alias_idx++)
1887         {
1888                 uint32 alias_rid = info->dom.sam[alias_idx].rid;
1889
1890                 report(out_hnd, "Alias RID: %8x  Group Name: %s\n",
1891                                   alias_rid,
1892                                   info->dom.sam[alias_idx].acct_name);
1893
1894                 if (request_member_info)
1895                 {
1896                         uint32 num_aliases;
1897                         DOM_SID2 sid_mem[MAX_LOOKUP_SIDS];
1898
1899                         /* send user aliases query */
1900                         if (get_samr_query_aliasmem(smb_cli, fnum, 
1901                                 &info->dom.samr_pol_open_domain,
1902                                                 alias_rid, &num_aliases, sid_mem))
1903                         {
1904                                 uint16 fnum_lsa;
1905                                 BOOL res3 = True;
1906                                 BOOL res4 = True;
1907                                 char **names = NULL;
1908                                 int num_names = 0;
1909                                 DOM_SID **sids = NULL;
1910                                 int i;
1911
1912                                 if (num_aliases != 0)
1913                                 {
1914                                         sids = malloc(num_aliases * sizeof(DOM_SID*));
1915                                 }
1916
1917                                 res3 = sids != NULL;
1918                                 if (res3)
1919                                 {
1920                                         for (i = 0; i < num_aliases; i++)
1921                                         {
1922                                                 sids[i] = &sid_mem[i].sid;
1923                                         }
1924                                 }
1925
1926                                 /* open LSARPC session. */
1927                                 res3 = res3 ? cli_nt_session_open(smb_cli, PIPE_LSARPC, &fnum_lsa) : False;
1928
1929                                 /* lookup domain controller; receive a policy handle */
1930                                 res3 = res3 ? lsa_open_policy(smb_cli, fnum_lsa,
1931                                                         srv_name,
1932                                                         &info->dom.lsa_info_pol, True) : False;
1933
1934                                 /* send lsa lookup sids call */
1935                                 res4 = res3 ? lsa_lookup_sids(smb_cli, fnum_lsa, 
1936                                                                &info->dom.lsa_info_pol,
1937                                                                num_aliases, sids, 
1938                                                                &names, NULL, &num_names) : False;
1939
1940                                 res3 = res3 ? lsa_close(smb_cli, fnum_lsa, &info->dom.lsa_info_pol) : False;
1941
1942                                 cli_nt_session_close(smb_cli, fnum_lsa);
1943
1944                                 if (res4 && names != NULL)
1945                                 {
1946                                         display_alias_members(out_hnd, ACTION_HEADER   , num_names, names);
1947                                         display_alias_members(out_hnd, ACTION_ENUMERATE, num_names, names);
1948                                         display_alias_members(out_hnd, ACTION_FOOTER   , num_names, names);
1949                                 }
1950                                 free_char_array(num_names, names);
1951                                 if (sids != NULL)
1952                                 {
1953                                         free(sids);
1954                                 }
1955                         }
1956                 }
1957         }
1958         }
1959
1960         res = res ? samr_close(smb_cli, fnum, 
1961                     &info->dom.samr_pol_connect) : False;
1962
1963         res = res ? samr_close(smb_cli, fnum,
1964                     &info->dom.samr_pol_open_domain) : False;
1965
1966         /* close the session */
1967         cli_nt_session_close(smb_cli, fnum);
1968
1969         if (info->dom.sam != NULL)
1970         {
1971                 free(info->dom.sam);
1972         }
1973
1974         if (res)
1975         {
1976                 DEBUG(5,("cmd_sam_enum_aliases: succeeded\n"));
1977         }
1978         else
1979         {
1980                 DEBUG(5,("cmd_sam_enum_aliases: failed\n"));
1981         }
1982 }
1983
1984 static void req_groupmem_info(struct client_info *info, uint16 fnum,
1985                                 uint32 group_rid)
1986 {
1987         uint32 num_mem;
1988         uint32 *rid_mem = NULL;
1989         uint32 *attr_mem = NULL;
1990
1991         /* get group members */
1992         if (get_samr_query_groupmem(smb_cli, fnum, 
1993                 &info->dom.samr_pol_open_domain,
1994                 group_rid, &num_mem, &rid_mem, &attr_mem))
1995         {
1996                 BOOL res3 = True;
1997                 int num_names = 0;
1998                 char **name = NULL;
1999                 uint32 *type = NULL;
2000
2001                 res3 = samr_query_lookup_rids(smb_cli, fnum,
2002                                    &info->dom.samr_pol_open_domain, 1000,
2003                                    num_mem, rid_mem, &num_names, &name, &type);
2004
2005                 if (res3)
2006                 {
2007                         display_group_members(out_hnd, ACTION_HEADER   , num_names, name, type);
2008                         display_group_members(out_hnd, ACTION_ENUMERATE, num_names, name, type);
2009                         display_group_members(out_hnd, ACTION_FOOTER   , num_names, name, type);
2010                 }
2011
2012                 free_char_array(num_names, name);
2013                 if (type != NULL)
2014                 {
2015                         free(type);
2016                 }
2017         }
2018
2019         if (attr_mem != NULL)
2020         {
2021                 free(attr_mem);
2022         }
2023         if (rid_mem != NULL)
2024         {
2025                 free(rid_mem);
2026         }
2027 }
2028
2029 /****************************************************************************
2030 SAM groups query.
2031 ****************************************************************************/
2032 void cmd_sam_enum_groups(struct client_info *info)
2033 {
2034         uint16 fnum;
2035         fstring srv_name;
2036         fstring domain;
2037         fstring sid;
2038         DOM_SID sid1;
2039         BOOL res = True;
2040         BOOL request_member_info = False;
2041         BOOL request_group_info = False;
2042         uint32 ace_perms = 0x02000000; /* access control permissions. */
2043         fstring tmp;
2044         uint32 group_idx;
2045         int i;
2046
2047         sid_copy(&sid1, &info->dom.level5_sid);
2048
2049         if (sid1.num_auths == 0)
2050         {
2051                 report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
2052                 return;
2053         }
2054
2055         sid_to_string(sid, &sid1);
2056         fstrcpy(domain, info->dom.level3_dom);
2057
2058         fstrcpy(srv_name, "\\\\");
2059         fstrcat(srv_name, info->dest_host);
2060         strupper(srv_name);
2061
2062         /* a bad way to do token parsing... */
2063         for (i = 0; i < 2; i++)
2064         {
2065                 /* a bad way to do token parsing... */
2066                 if (next_token(NULL, tmp, NULL, sizeof(tmp)))
2067                 {
2068                         request_member_info |= strequal(tmp, "-m");
2069                         request_group_info  |= strequal(tmp, "-g");
2070                 }
2071                 else
2072                 {
2073                         break;
2074                 }
2075         }
2076
2077         report(out_hnd, "SAM Enumerate Groups\n");
2078         report(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
2079                           info->myhostname, srv_name, domain, sid);
2080
2081         /* open SAMR session.  negotiate credentials */
2082         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
2083
2084         /* establish a connection. */
2085         res = res ? samr_connect(smb_cli, fnum,
2086                                 srv_name, 0x02000000,
2087                                 &info->dom.samr_pol_connect) : False;
2088
2089         /* connect to the domain */
2090         res = res ? samr_open_domain(smb_cli, fnum,
2091                     &info->dom.samr_pol_connect, ace_perms, &sid1,
2092                     &info->dom.samr_pol_open_domain) : False;
2093
2094         info->dom.sam = NULL;
2095
2096         /* read some groups */
2097         res = res ? samr_enum_dom_groups(smb_cli, fnum,
2098                                 &info->dom.samr_pol_open_domain,
2099                                 0x0, 0x03,
2100                                 &info->dom.sam, &info->dom.num_sam_entries) : False;
2101
2102         if (res && info->dom.num_sam_entries == 0)
2103         {
2104                 report(out_hnd, "No groups\n");
2105         }
2106
2107         if (res)
2108         {
2109                 for (group_idx = 0; group_idx < info->dom.num_sam_entries; group_idx++)
2110                 {
2111                         uint32 group_rid = info->dom.sam[group_idx].rid;
2112
2113                         report(out_hnd, "Group RID: %8x  Group Name: %s\n",
2114                                           group_rid,
2115                                           info->dom.sam[group_idx].acct_name);
2116
2117                         if (request_group_info)
2118                         {
2119                                 query_groupinfo(info, fnum, group_rid);
2120                         }
2121                         if (request_member_info)
2122                         {
2123                                 req_groupmem_info(info, fnum, group_rid);
2124                         }
2125                 }
2126         }
2127
2128         res = res ? samr_close(smb_cli, fnum,
2129                     &info->dom.samr_pol_open_domain) : False;
2130
2131         res = res ? samr_close(smb_cli, fnum, 
2132                     &info->dom.samr_pol_connect) : False;
2133
2134         /* close the session */
2135         cli_nt_session_close(smb_cli, fnum);
2136
2137         if (info->dom.sam != NULL)
2138         {
2139                 free(info->dom.sam);
2140         }
2141
2142         if (res)
2143         {
2144                 DEBUG(5,("cmd_sam_enum_groups: succeeded\n"));
2145         }
2146         else
2147         {
2148                 DEBUG(5,("cmd_sam_enum_groups: failed\n"));
2149         }
2150 }