ed66962a821d71c1deec1d0813387c6df5bbd557
[samba.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         fprintf(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                 fprintf(out_hnd, "NT Password changed OK\n");
111         }
112         else
113         {
114                 fprintf(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                 fprintf(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         fprintf(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                 fprintf(out_hnd, "lookupdomain: <name>\n");
195                 return;
196         }
197
198         fprintf(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, 0x00000020,
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                 fprintf(out_hnd, "%s SID: %s\n", domain, str_sid);
223                 fprintf(out_hnd, "Lookup Domain: OK\n");
224         }
225         else
226         {
227                 DEBUG(5,("cmd_sam_lookup_domain: failed\n"));
228                 fprintf(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 flags = 0x200003f3; /* 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                 fprintf(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                 fprintf(out_hnd, "delaliasmem: <alias rid> [member sid1] [member sid2] ...\n");
268                 return;
269         }
270         alias_rid = get_number(tmp);
271
272         fprintf(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, 0x00000020,
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, flags, &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                         fprintf(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                 fprintf(out_hnd, "Delete Domain Alias Member: OK\n");
315         }
316         else
317         {
318                 DEBUG(5,("cmd_sam_del_aliasmem: failed\n"));
319                 fprintf(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 flags = 0x200003f3; /* absolutely no idea. */
339         uint32 alias_rid = 0;
340         const 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                 fprintf(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                 fprintf(out_hnd, "delalias <alias name>\n");
362                 return;
363         }
364
365         fprintf(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, 0x00000020,
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, flags, &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                 fprintf(out_hnd, "Delete Domain Alias: OK\n");
410         }
411         else
412         {
413                 DEBUG(5,("cmd_sam_delete_dom_alias: failed\n"));
414                 fprintf(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 flags = 0x200003f3; /* absolutely no idea. */
437         uint32 alias_rid;
438         const 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                 fprintf(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                 fprintf(out_hnd, "addaliasmem <group name> [member name1] [member name2] ...\n");
473                 return;
474         }
475         
476         fprintf(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, 0x00000020,
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, flags, &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                         fprintf(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         if (names != NULL)
561         {
562                 for (i = 0; i < num_names; i++)
563                 {
564                         if (names[i] != NULL)
565                         {
566                                 free(((char**)(names))[i]);
567                         }
568                 }
569                 free(names);
570         }
571         
572         if (res && res1 && res2)
573         {
574                 DEBUG(5,("cmd_sam_add_aliasmem: succeeded\n"));
575                 fprintf(out_hnd, "Add Domain Alias Member: OK\n");
576         }
577         else
578         {
579                 DEBUG(5,("cmd_sam_add_aliasmem: failed\n"));
580                 fprintf(out_hnd, "Add Domain Alias Member: FAILED\n");
581         }
582 }
583
584
585 /****************************************************************************
586 SAM create domain alias.
587 ****************************************************************************/
588 void cmd_sam_create_dom_alias(struct client_info *info)
589 {
590         uint16 fnum;
591         fstring srv_name;
592         fstring domain;
593         fstring acct_name;
594         fstring acct_desc;
595         fstring sid;
596         DOM_SID sid1;
597         BOOL res = True;
598         BOOL res1 = True;
599         uint32 flags = 0x200003f3; /* absolutely no idea. */
600         uint32 alias_rid; 
601
602         sid_copy(&sid1, &info->dom.level5_sid);
603         sid_to_string(sid, &sid1);
604         fstrcpy(domain, info->dom.level5_dom);
605
606         if (sid1.num_auths == 0)
607         {
608                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
609                 return;
610         }
611
612
613         fstrcpy(srv_name, "\\\\");
614         fstrcat(srv_name, info->dest_host);
615         strupper(srv_name);
616
617         if (!next_token(NULL, acct_name, NULL, sizeof(acct_name)))
618         {
619                 fprintf(out_hnd, "createalias: <acct name> [acct description]\n");
620         }
621
622         if (!next_token(NULL, acct_desc, NULL, sizeof(acct_desc)))
623         {
624                 acct_desc[0] = 0;
625         }
626
627
628         fprintf(out_hnd, "SAM Create Domain Alias\n");
629         fprintf(out_hnd, "Domain: %s Name: %s Description: %s\n",
630                           domain, acct_name, acct_desc);
631
632         /* open SAMR session.  negotiate credentials */
633         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
634
635         /* establish a connection. */
636         res = res ? samr_connect(smb_cli, fnum, 
637                                 srv_name, 0x00000020,
638                                 &info->dom.samr_pol_connect) : False;
639
640         /* connect to the domain */
641         res = res ? samr_open_domain(smb_cli, fnum, 
642                     &info->dom.samr_pol_connect, flags, &sid1,
643                     &info->dom.samr_pol_open_domain) : False;
644
645         /* create a domain alias */
646         res1 = res ? create_samr_domain_alias(smb_cli, fnum, 
647                                 &info->dom.samr_pol_open_domain,
648                                 acct_name, acct_desc, &alias_rid) : False;
649
650         res = res ? samr_close(smb_cli, fnum,
651                     &info->dom.samr_pol_open_domain) : False;
652
653         res = res ? samr_close(smb_cli, fnum,
654                     &info->dom.samr_pol_connect) : False;
655
656         /* close the session */
657         cli_nt_session_close(smb_cli, fnum);
658
659         if (res && res1)
660         {
661                 DEBUG(5,("cmd_sam_create_dom_alias: succeeded\n"));
662                 fprintf(out_hnd, "Create Domain Alias: OK\n");
663         }
664         else
665         {
666                 DEBUG(5,("cmd_sam_create_dom_alias: failed\n"));
667                 fprintf(out_hnd, "Create Domain Alias: FAILED\n");
668         }
669 }
670
671
672 /****************************************************************************
673 SAM delete group member.
674 ****************************************************************************/
675 void cmd_sam_del_groupmem(struct client_info *info)
676 {
677         uint16 fnum;
678         fstring srv_name;
679         fstring domain;
680         fstring tmp;
681         fstring sid;
682         DOM_SID sid1;
683         POLICY_HND group_pol;
684         BOOL res = True;
685         BOOL res1 = True;
686         BOOL res2 = True;
687         uint32 flags = 0x200003f3; /* absolutely no idea. */
688         uint32 member_rid; 
689         uint32 group_rid;
690
691         sid_copy(&sid1, &info->dom.level5_sid);
692         sid_to_string(sid, &sid1);
693         fstrcpy(domain, info->dom.level5_dom);
694
695         if (sid1.num_auths == 0)
696         {
697                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
698                 return;
699         }
700
701         fstrcpy(srv_name, "\\\\");
702         fstrcat(srv_name, info->dest_host);
703         strupper(srv_name);
704
705         if (!next_token(NULL, tmp, NULL, sizeof(tmp)))
706         {
707                 fprintf(out_hnd, "delgroupmem: <group rid> [member rid1] [member rid2] ...\n");
708                 return;
709         }
710         group_rid = get_number(tmp);
711
712         fprintf(out_hnd, "SAM Add Domain Group member\n");
713
714         /* open SAMR session.  negotiate credentials */
715         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
716
717         /* establish a connection. */
718         res = res ? samr_connect(smb_cli, fnum, 
719                                 srv_name, 0x00000020,
720                                 &info->dom.samr_pol_connect) : False;
721
722         /* connect to the domain */
723         res = res ? samr_open_domain(smb_cli, fnum, 
724                     &info->dom.samr_pol_connect, flags, &sid1,
725                     &info->dom.samr_pol_open_domain) : False;
726
727         /* connect to the domain */
728         res1 = res ? samr_open_group(smb_cli, fnum,
729                     &info->dom.samr_pol_open_domain,
730                     0x0000001f, group_rid, &group_pol) : False;
731
732         while (next_token(NULL, tmp, NULL, sizeof(tmp)) && res2 && res1)
733         {
734                 /* get a rid, delete a member from the group */
735                 member_rid = get_number(tmp);
736                 res2 = res2 ? samr_del_groupmem(smb_cli, fnum, &group_pol, member_rid) : False;
737
738                 if (res2)
739                 {
740                         fprintf(out_hnd, "RID deleted from Group 0x%x: 0x%x\n", group_rid, member_rid);
741                 }
742         }
743
744         res1 = res1 ? samr_close(smb_cli, fnum, &group_pol) : False;
745         res  = res  ? samr_close(smb_cli, fnum, &info->dom.samr_pol_open_domain) : False;
746         res  = res  ? samr_close(smb_cli, fnum, &info->dom.samr_pol_connect) : False;
747
748         /* close the session */
749         cli_nt_session_close(smb_cli, fnum);
750
751         if (res && res1 && res2)
752         {
753                 DEBUG(5,("cmd_sam_del_groupmem: succeeded\n"));
754                 fprintf(out_hnd, "Add Domain Group Member: OK\n");
755         }
756         else
757         {
758                 DEBUG(5,("cmd_sam_del_groupmem: failed\n"));
759                 fprintf(out_hnd, "Add Domain Group Member: FAILED\n");
760         }
761 }
762
763
764 /****************************************************************************
765 SAM delete group.
766 ****************************************************************************/
767 void cmd_sam_delete_dom_group(struct client_info *info)
768 {
769         uint16 fnum;
770         fstring srv_name;
771         fstring domain;
772         fstring name;
773         fstring sid;
774         DOM_SID sid1;
775         POLICY_HND group_pol;
776         BOOL res = True;
777         BOOL res1 = True;
778         BOOL res2 = True;
779         uint32 flags = 0x200003f3; /* absolutely no idea. */
780         uint32 group_rid = 0;
781         const char *names[1];
782         uint32 rid [MAX_LOOKUP_SIDS];
783         uint32 type[MAX_LOOKUP_SIDS];
784         uint32 num_rids;
785
786         sid_copy(&sid1, &info->dom.level5_sid);
787         sid_to_string(sid, &sid1);
788         fstrcpy(domain, info->dom.level5_dom);
789
790         if (sid1.num_auths == 0)
791         {
792                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
793                 return;
794         }
795
796         fstrcpy(srv_name, "\\\\");
797         fstrcat(srv_name, info->dest_host);
798         strupper(srv_name);
799
800         if (!next_token(NULL, name, NULL, sizeof(name)))
801         {
802                 fprintf(out_hnd, "delgroup <group name>\n");
803                 return;
804         }
805
806         fprintf(out_hnd, "SAM Delete Domain Group\n");
807
808         /* open SAMR session.  negotiate credentials */
809         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
810
811         /* establish a connection. */
812         res = res ? samr_connect(smb_cli, fnum, 
813                                 srv_name, 0x00000020,
814                                 &info->dom.samr_pol_connect) : False;
815
816         /* connect to the domain */
817         res = res ? samr_open_domain(smb_cli, fnum, 
818                     &info->dom.samr_pol_connect, flags, &sid1,
819                     &info->dom.samr_pol_open_domain) : False;
820
821         names[0] = name;
822
823         res1 = res ? samr_query_lookup_names(smb_cli, fnum,
824                     &info->dom.samr_pol_open_domain, 0x000003e8,
825                     1, names,
826                     &num_rids, rid, type) : False;
827
828         if (res1 && num_rids == 1)
829         {
830                 group_rid = rid[0];
831         }
832
833         /* connect to the domain */
834         res1 = res1 ? samr_open_group(smb_cli, fnum,
835                     &info->dom.samr_pol_open_domain,
836                     0x0000001f, group_rid, &group_pol) : False;
837
838         res2 = res1 ? samr_delete_dom_group(smb_cli, fnum, &group_pol) : False;
839
840         res1 = res1 ? samr_close(smb_cli, fnum, &group_pol) : False;
841         res  = res  ? samr_close(smb_cli, fnum, &info->dom.samr_pol_open_domain) : False;
842         res  = res  ? samr_close(smb_cli, fnum, &info->dom.samr_pol_connect) : False;
843
844         /* close the session */
845         cli_nt_session_close(smb_cli, fnum);
846
847         if (res && res1 && res2)
848         {
849                 DEBUG(5,("cmd_sam_delete_dom_group: succeeded\n"));
850                 fprintf(out_hnd, "Delete Domain Group: OK\n");
851         }
852         else
853         {
854                 DEBUG(5,("cmd_sam_delete_dom_group: failed\n"));
855                 fprintf(out_hnd, "Delete Domain Group: FAILED\n");
856         }
857 }
858
859
860 /****************************************************************************
861 SAM add group member.
862 ****************************************************************************/
863 void cmd_sam_add_groupmem(struct client_info *info)
864 {
865         uint16 fnum;
866         fstring srv_name;
867         fstring domain;
868         fstring tmp;
869         fstring sid;
870         DOM_SID sid1;
871         POLICY_HND group_pol;
872         BOOL res = True;
873         BOOL res1 = True;
874         BOOL res2 = True;
875         uint32 flags = 0x200003f3; /* absolutely no idea. */
876         uint32 group_rid = 0;
877         const char **names = NULL;
878         uint32 num_names = 0;
879         uint32 rid [MAX_LOOKUP_SIDS];
880         uint32 type[MAX_LOOKUP_SIDS];
881         uint32 num_rids;
882         int i;
883
884         sid_copy(&sid1, &info->dom.level5_sid);
885         sid_to_string(sid, &sid1);
886         fstrcpy(domain, info->dom.level5_dom);
887
888         if (sid1.num_auths == 0)
889         {
890                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
891                 return;
892         }
893
894         fstrcpy(srv_name, "\\\\");
895         fstrcat(srv_name, info->dest_host);
896         strupper(srv_name);
897
898         while (next_token(NULL, tmp, NULL, sizeof(tmp)))
899         {
900                 num_names++;
901                 names = Realloc(names, num_names * sizeof(char*));
902                 if (names == NULL)
903                 {
904                         DEBUG(0,("Realloc returned NULL\n"));
905                         return;
906                 }
907                 names[num_names-1] = strdup(tmp);
908         }
909
910         if (num_names < 2)
911         {
912                 fprintf(out_hnd, "addgroupmem <group name> [member name1] [member name2] ...\n");
913                 return;
914         }
915         
916         fprintf(out_hnd, "SAM Add Domain Group member\n");
917
918         /* open SAMR session.  negotiate credentials */
919         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
920
921         /* establish a connection. */
922         res = res ? samr_connect(smb_cli, fnum, 
923                                 srv_name, 0x00000020,
924                                 &info->dom.samr_pol_connect) : False;
925
926         /* connect to the domain */
927         res = res ? samr_open_domain(smb_cli, fnum, 
928                     &info->dom.samr_pol_connect, flags, &sid1,
929                     &info->dom.samr_pol_open_domain) : False;
930
931         res1 = res ? samr_query_lookup_names(smb_cli, fnum,
932                     &info->dom.samr_pol_open_domain, 0x000003e8,
933                     num_names, names,
934                     &num_rids, rid, type) : False;
935
936         if (res1 && num_rids != 0)
937         {
938                 group_rid = rid[0];
939         }
940
941         /* connect to the domain */
942         res1 = res1 ? samr_open_group(smb_cli, fnum,
943                     &info->dom.samr_pol_open_domain,
944                     0x0000001f, group_rid, &group_pol) : False;
945
946         for (i = 1; i < num_rids && res2 && res1; i++)
947         {
948                 res2 = res2 ? samr_add_groupmem(smb_cli, fnum, &group_pol, rid[i]) : False;
949
950                 if (res2)
951                 {
952                         fprintf(out_hnd, "RID added to Group 0x%x: 0x%x\n", group_rid, rid[i]);
953                 }
954         }
955
956         res1 = res1 ? samr_close(smb_cli, fnum, &group_pol) : False;
957         res  = res  ? samr_close(smb_cli, fnum, &info->dom.samr_pol_open_domain) : False;
958         res  = res  ? samr_close(smb_cli, fnum, &info->dom.samr_pol_connect) : False;
959
960         /* close the session */
961         cli_nt_session_close(smb_cli, fnum);
962
963         if (names != NULL)
964         {
965                 for (i = 0; i < num_names; i++)
966                 {
967                         if (names[i] != NULL)
968                         {
969                                 free(((char**)(names))[i]);
970                         }
971                 }
972                 free(names);
973         }
974         
975         if (res && res1 && res2)
976         {
977                 DEBUG(5,("cmd_sam_add_groupmem: succeeded\n"));
978                 fprintf(out_hnd, "Add Domain Group Member: OK\n");
979         }
980         else
981         {
982                 DEBUG(5,("cmd_sam_add_groupmem: failed\n"));
983                 fprintf(out_hnd, "Add Domain Group Member: FAILED\n");
984         }
985 }
986
987
988 /****************************************************************************
989 SAM create domain group.
990 ****************************************************************************/
991 void cmd_sam_create_dom_group(struct client_info *info)
992 {
993         uint16 fnum;
994         fstring srv_name;
995         fstring domain;
996         fstring acct_name;
997         fstring acct_desc;
998         fstring sid;
999         DOM_SID sid1;
1000         BOOL res = True;
1001         BOOL res1 = True;
1002         uint32 flags = 0x220; /* absolutely no idea. */
1003         uint32 group_rid; 
1004
1005         sid_copy(&sid1, &info->dom.level5_sid);
1006         sid_to_string(sid, &sid1);
1007         fstrcpy(domain, info->dom.level5_dom);
1008
1009         if (sid1.num_auths == 0)
1010         {
1011                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
1012                 return;
1013         }
1014
1015
1016         fstrcpy(srv_name, "\\\\");
1017         fstrcat(srv_name, info->dest_host);
1018         strupper(srv_name);
1019
1020         if (!next_token(NULL, acct_name, NULL, sizeof(acct_name)))
1021         {
1022                 fprintf(out_hnd, "creategroup: <acct name> [acct description]\n");
1023         }
1024
1025         if (!next_token(NULL, acct_desc, NULL, sizeof(acct_desc)))
1026         {
1027                 acct_desc[0] = 0;
1028         }
1029
1030
1031         fprintf(out_hnd, "SAM Create Domain Group\n");
1032         fprintf(out_hnd, "Domain: %s Name: %s Description: %s\n",
1033                           domain, acct_name, acct_desc);
1034
1035         /* open SAMR session.  negotiate credentials */
1036         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
1037
1038         /* establish a connection. */
1039         res = res ? samr_connect(smb_cli, fnum, 
1040                                 srv_name, 0x00000020,
1041                                 &info->dom.samr_pol_connect) : False;
1042
1043         /* connect to the domain */
1044         res = res ? samr_open_domain(smb_cli, fnum, 
1045                     &info->dom.samr_pol_connect, flags, &sid1,
1046                     &info->dom.samr_pol_open_domain) : False;
1047
1048         /* read some users */
1049         res1 = res ? create_samr_domain_group(smb_cli, fnum, 
1050                                 &info->dom.samr_pol_open_domain,
1051                                 acct_name, acct_desc, &group_rid) : False;
1052
1053         res = res ? samr_close(smb_cli, fnum,
1054                     &info->dom.samr_pol_open_domain) : False;
1055
1056         res = res ? samr_close(smb_cli, fnum,
1057                     &info->dom.samr_pol_connect) : False;
1058
1059         /* close the session */
1060         cli_nt_session_close(smb_cli, fnum);
1061
1062         if (res && res1)
1063         {
1064                 DEBUG(5,("cmd_sam_create_dom_group: succeeded\n"));
1065                 fprintf(out_hnd, "Create Domain Group: OK\n");
1066         }
1067         else
1068         {
1069                 DEBUG(5,("cmd_sam_create_dom_group: failed\n"));
1070                 fprintf(out_hnd, "Create Domain Group: FAILED\n");
1071         }
1072 }
1073
1074 static void req_user_info(struct client_info *info, uint16 fnum,
1075                                 uint32 user_rid)
1076 {
1077         SAM_USER_INFO_21 usr;
1078         /* send user info query, level 0x15 */
1079         if (get_samr_query_userinfo(smb_cli, fnum,
1080                                     &info->dom.samr_pol_open_domain,
1081                                     0x15, user_rid, &usr))
1082         {
1083                 display_sam_user_info_21(out_hnd, ACTION_HEADER   , &usr);
1084                 display_sam_user_info_21(out_hnd, ACTION_ENUMERATE, &usr);
1085                 display_sam_user_info_21(out_hnd, ACTION_FOOTER   , &usr);
1086         }
1087 }
1088
1089 static void req_group_info(struct client_info *info, uint16 fnum,
1090                                 uint32 user_rid)
1091 {
1092         uint32 num_groups;
1093         DOM_GID gid[LSA_MAX_GROUPS];
1094
1095         /* send user group query */
1096         if (get_samr_query_usergroups(smb_cli, fnum,
1097                                       &info->dom.samr_pol_open_domain,
1098                                       user_rid, &num_groups, gid))
1099         {
1100                 int i;
1101                 uint32 num_names;
1102                 uint32  rid_mem[MAX_LOOKUP_SIDS];
1103                 fstring name   [MAX_LOOKUP_SIDS];
1104                 uint32  type   [MAX_LOOKUP_SIDS];
1105
1106                 for (i = 0; i < num_groups; i++)
1107                 {
1108                         rid_mem[i] = gid[i].g_rid;
1109                 }
1110
1111                 if (samr_query_lookup_rids(smb_cli, fnum, 
1112                                 &info->dom.samr_pol_open_domain, 0x3e8,
1113                                 num_groups, rid_mem, 
1114                                 &num_names, name, type))
1115                 {
1116                         display_group_members(out_hnd, ACTION_HEADER   , num_names, name, type);
1117                         display_group_members(out_hnd, ACTION_ENUMERATE, num_names, name, type);
1118                         display_group_members(out_hnd, ACTION_FOOTER   , num_names, name, type);
1119                 }
1120         }
1121 }
1122
1123 static void req_alias_info(struct client_info *info, uint16 fnum,
1124                                 DOM_SID *sid1, uint32 user_rid)
1125 {
1126         uint32 num_aliases;
1127         uint32 rid[LSA_MAX_GROUPS];
1128         DOM_SID als_sid;
1129
1130         sid_copy(&als_sid, sid1);
1131         sid_append_rid(&als_sid, user_rid);
1132
1133         /* send user alias query */
1134         if (samr_query_useraliases(smb_cli, fnum,
1135                                 &info->dom.samr_pol_open_domain,
1136                                 &als_sid, &num_aliases, rid))
1137         {
1138                 uint32 num_names;
1139                 fstring name   [MAX_LOOKUP_SIDS];
1140                 uint32  type   [MAX_LOOKUP_SIDS];
1141
1142                 if (samr_query_lookup_rids(smb_cli, fnum, 
1143                                 &info->dom.samr_pol_open_domain, 0x3e8,
1144                                 num_aliases, rid, 
1145                                 &num_names, name, type))
1146                 {
1147                         display_group_members(out_hnd, ACTION_HEADER   , num_names, name, type);
1148                         display_group_members(out_hnd, ACTION_ENUMERATE, num_names, name, type);
1149                         display_group_members(out_hnd, ACTION_FOOTER   , num_names, name, type);
1150                 }
1151         }
1152
1153         /* send user alias query */
1154         if (samr_query_useraliases(smb_cli, fnum,
1155                                 &info->dom.samr_pol_open_builtindom,
1156                                 &als_sid, &num_aliases, rid))
1157         {
1158                 uint32 num_names;
1159                 fstring name   [MAX_LOOKUP_SIDS];
1160                 uint32  type   [MAX_LOOKUP_SIDS];
1161
1162                 if (samr_query_lookup_rids(smb_cli, fnum, 
1163                                 &info->dom.samr_pol_open_builtindom, 0x3e8,
1164                                 num_aliases, rid, 
1165                                 &num_names, name, type))
1166                 {
1167                         display_group_members(out_hnd, ACTION_HEADER   , num_names, name, type);
1168                         display_group_members(out_hnd, ACTION_ENUMERATE, num_names, name, type);
1169                         display_group_members(out_hnd, ACTION_FOOTER   , num_names, name, type);
1170                 }
1171         }
1172 }
1173
1174 /****************************************************************************
1175 experimental SAM users enum.
1176 ****************************************************************************/
1177 void cmd_sam_enum_users(struct client_info *info)
1178 {
1179         uint16 fnum;
1180         fstring srv_name;
1181         fstring domain;
1182         fstring sid;
1183         DOM_SID sid1;
1184         DOM_SID sid_1_5_20;
1185         int user_idx;
1186         BOOL res = True;
1187         BOOL res1 = True;
1188         BOOL request_user_info  = False;
1189         BOOL request_group_info = False;
1190         BOOL request_alias_info = False;
1191         uint16 start_idx = 0x0;
1192         uint16 unk_0 = 0x0;
1193         uint16 acb_mask = 0;
1194         uint16 unk_1 = 0x0;
1195         uint32 flags = 0x304; /* access control permissions */
1196         fstring tmp;
1197         int i;
1198
1199         sid_copy(&sid1, &info->dom.level5_sid);
1200         sid_to_string(sid, &sid1);
1201         fstrcpy(domain, info->dom.level5_dom);
1202
1203         if (sid1.num_auths == 0)
1204         {
1205                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
1206                 return;
1207         }
1208
1209
1210         fstrcpy(srv_name, "\\\\");
1211         fstrcat(srv_name, info->dest_host);
1212         strupper(srv_name);
1213
1214         for (i = 0; i < 3; i++)
1215         {
1216                 /* a bad way to do token parsing... */
1217                 if (next_token(NULL, tmp, NULL, sizeof(tmp)))
1218                 {
1219                         request_user_info  |= strequal(tmp, "-u");
1220                         request_group_info |= strequal(tmp, "-g");
1221                         request_alias_info |= strequal(tmp, "-a");
1222                 }
1223                 else
1224                 {
1225                         break;
1226                 }
1227         }
1228
1229 #ifdef DEBUG_TESTING
1230         if (next_token(NULL, tmp, NULL, sizeof(tmp)))
1231         {
1232                 start_idx = (uint32)strtol(tmp, (char**)NULL, 10);
1233         }
1234
1235         if (next_token(NULL, tmp, NULL, sizeof(tmp)))
1236         {
1237                 unk_0 = (uint16)strtol(tmp, (char**)NULL, 16);
1238         }
1239
1240         if (next_token(NULL, tmp, NULL, sizeof(tmp)))
1241         {
1242                 acb_mask = (uint16)strtol(tmp, (char**)NULL, 16);
1243         }
1244
1245         if (next_token(NULL, tmp, NULL, sizeof(tmp)))
1246         {
1247                 unk_1 = (uint16)strtol(tmp, (char**)NULL, 16);
1248         }
1249 #endif
1250
1251         string_to_sid(&sid_1_5_20, "S-1-5-32");
1252
1253         fprintf(out_hnd, "SAM Enumerate Users\n");
1254         fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
1255                           info->myhostname, srv_name, domain, sid);
1256
1257 #ifdef DEBUG_TESTING
1258         DEBUG(5,("Number of entries:%d unk_0:%04x acb_mask:%04x unk_1:%04x\n",
1259                   start_idx, unk_0, acb_mask, unk_1));
1260 #endif
1261
1262         /* open SAMR session.  negotiate credentials */
1263         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
1264
1265         /* establish a connection. */
1266         res = res ? samr_connect(smb_cli, fnum, 
1267                                 srv_name, 0x00000020,
1268                                 &info->dom.samr_pol_connect) : False;
1269
1270         /* connect to the domain */
1271         res = res ? samr_open_domain(smb_cli, fnum, 
1272                     &info->dom.samr_pol_connect, flags, &sid1,
1273                     &info->dom.samr_pol_open_domain) : False;
1274
1275         /* connect to the S-1-5-20 domain */
1276         res1 = res ? samr_open_domain(smb_cli, fnum, 
1277                     &info->dom.samr_pol_connect, flags, &sid_1_5_20,
1278                     &info->dom.samr_pol_open_builtindom) : False;
1279
1280         info->dom.sam = NULL;
1281
1282         /* read some users */
1283         res = res ? samr_enum_dom_users(smb_cli, fnum, 
1284                      &info->dom.samr_pol_open_domain,
1285                      start_idx, acb_mask, unk_1, 0x8000,
1286                      &info->dom.sam, &info->dom.num_sam_entries) : False;
1287
1288         if (res && info->dom.num_sam_entries == 0)
1289         {
1290                 fprintf(out_hnd, "No users\n");
1291         }
1292
1293         if (res)
1294         {
1295                 /* query all the users */
1296                 for (user_idx = 0; res && user_idx < info->dom.num_sam_entries; user_idx++)
1297                 {
1298                         uint32 user_rid = info->dom.sam[user_idx].rid;
1299
1300                         fprintf(out_hnd, "User RID: %8x  User Name: %s\n",
1301                                 user_rid,
1302                                 info->dom.sam[user_idx].acct_name);
1303
1304                         if (request_user_info)
1305                         {
1306                                 req_user_info(info, fnum, user_rid);
1307                         }
1308
1309                         if (request_group_info)
1310                         {
1311                                 req_group_info(info, fnum, user_rid);
1312                         }
1313
1314                         if (request_alias_info)
1315                         {
1316                                 req_alias_info(info, fnum, &sid1, user_rid);
1317                         }
1318                 }
1319         }
1320
1321         res1 = res1 ? samr_close(smb_cli, fnum,
1322                     &info->dom.samr_pol_open_builtindom) : False;
1323
1324         res = res ? samr_close(smb_cli, fnum,
1325                     &info->dom.samr_pol_open_domain) : False;
1326
1327         res = res ? samr_close(smb_cli, fnum,
1328                     &info->dom.samr_pol_connect) : False;
1329
1330         /* close the session */
1331         cli_nt_session_close(smb_cli, fnum);
1332
1333         if (info->dom.sam != NULL)
1334         {
1335                 free(info->dom.sam);
1336         }
1337
1338         if (res)
1339         {
1340                 DEBUG(5,("cmd_sam_enum_users: succeeded\n"));
1341         }
1342         else
1343         {
1344                 DEBUG(5,("cmd_sam_enum_users: failed\n"));
1345         }
1346 }
1347
1348
1349 /****************************************************************************
1350 experimental SAM user query.
1351 ****************************************************************************/
1352 void cmd_sam_query_user(struct client_info *info)
1353 {
1354         uint16 fnum;
1355         fstring srv_name;
1356         fstring domain;
1357         fstring sid;
1358         DOM_SID sid1;
1359         int user_idx = 0;  /* FIXME maybe ... */
1360         BOOL res = True;
1361         uint32 flags = 0x304; /* absolutely no idea. */
1362         fstring rid_str ;
1363         fstring info_str;
1364         uint32 user_rid = 0;
1365         uint32 info_level = 0x15;
1366
1367         SAM_USER_INFO_21 usr;
1368
1369         sid_to_string(sid, &info->dom.level5_sid);
1370         fstrcpy(domain, info->dom.level5_dom);
1371
1372         if (strlen(sid) == 0)
1373         {
1374                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
1375                 return;
1376         }
1377
1378         string_to_sid(&sid1, sid);
1379
1380         fstrcpy(srv_name, "\\\\");
1381         fstrcat(srv_name, info->dest_host);
1382         strupper(srv_name);
1383
1384         if (next_token(NULL, rid_str , NULL, sizeof(rid_str )) &&
1385             next_token(NULL, info_str, NULL, sizeof(info_str)))
1386         {
1387                 user_rid   = strtoul(rid_str , (char**)NULL, 16);
1388                 info_level = strtoul(info_str, (char**)NULL, 10);
1389         }
1390
1391         fprintf(out_hnd, "SAM Query User: rid %x info level %d\n",
1392                           user_rid, info_level);
1393         fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
1394                           info->myhostname, srv_name, domain, sid);
1395
1396         /* open SAMR session.  negotiate credentials */
1397         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
1398
1399         /* establish a connection. */
1400         res = res ? samr_connect(smb_cli, fnum,
1401                                 srv_name, 0x00000020,
1402                                 &info->dom.samr_pol_connect) : False;
1403
1404         /* connect to the domain */
1405         res = res ? samr_open_domain(smb_cli, fnum,
1406                     &info->dom.samr_pol_connect, flags, &sid1,
1407                     &info->dom.samr_pol_open_domain) : False;
1408
1409         fprintf(out_hnd, "User RID: %8x  User Name: %s\n",
1410                           user_rid,
1411                           info->dom.sam[user_idx].acct_name);
1412
1413         /* send user info query, level */
1414         if (get_samr_query_userinfo(smb_cli, fnum,
1415                                         &info->dom.samr_pol_open_domain,
1416                                         info_level, user_rid, &usr))
1417         {
1418                 if (info_level == 0x15)
1419                 {
1420                         display_sam_user_info_21(out_hnd, ACTION_HEADER   , &usr);
1421                         display_sam_user_info_21(out_hnd, ACTION_ENUMERATE, &usr);
1422                         display_sam_user_info_21(out_hnd, ACTION_FOOTER   , &usr);
1423                 }
1424         }
1425
1426         res = res ? samr_close(smb_cli, fnum,
1427                     &info->dom.samr_pol_connect) : False;
1428
1429         res = res ? samr_close(smb_cli, fnum,
1430                     &info->dom.samr_pol_open_domain) : False;
1431
1432         /* close the session */
1433         cli_nt_session_close(smb_cli, fnum);
1434
1435         if (res)
1436         {
1437                 DEBUG(5,("cmd_sam_query_user: succeeded\n"));
1438         }
1439         else
1440         {
1441                 DEBUG(5,("cmd_sam_query_user: failed\n"));
1442         }
1443 }
1444
1445
1446 /****************************************************************************
1447 experimental SAM domain info query.
1448 ****************************************************************************/
1449 void cmd_sam_query_dominfo(struct client_info *info)
1450 {
1451         uint16 fnum;
1452         fstring srv_name;
1453         fstring domain;
1454         fstring sid;
1455         DOM_SID sid1;
1456         BOOL res = True;
1457         fstring info_str;
1458         uint32 switch_value = 2;
1459         uint32 flags = 0x304; /* absolutely no idea. */
1460
1461         sid_to_string(sid, &info->dom.level5_sid);
1462         fstrcpy(domain, info->dom.level5_dom);
1463
1464         if (strlen(sid) == 0)
1465         {
1466                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
1467                 return;
1468         }
1469
1470         string_to_sid(&sid1, sid);
1471
1472         fstrcpy(srv_name, "\\\\");
1473         fstrcat(srv_name, info->dest_host);
1474         strupper(srv_name);
1475
1476         if (next_token(NULL, info_str, NULL, sizeof(info_str)))
1477         {
1478                 switch_value = strtoul(info_str, (char**)NULL, 10);
1479         }
1480
1481         fprintf(out_hnd, "SAM Query Domain Info: info level %d\n", switch_value);
1482         fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
1483                           info->myhostname, srv_name, domain, sid);
1484
1485         /* open SAMR session.  negotiate credentials */
1486         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
1487
1488         /* establish a connection. */
1489         res = res ? samr_connect(smb_cli, fnum, 
1490                                 srv_name, 0x00000020,
1491                                 &info->dom.samr_pol_connect) : False;
1492
1493         /* connect to the domain */
1494         res = res ? samr_open_domain(smb_cli, fnum, 
1495                     &info->dom.samr_pol_connect, flags, &sid1,
1496                     &info->dom.samr_pol_open_domain) : False;
1497
1498         /* send a samr 0x8 command */
1499         res = res ? samr_query_dom_info(smb_cli, fnum,
1500                     &info->dom.samr_pol_open_domain, switch_value) : False;
1501
1502         res = res ? samr_close(smb_cli, fnum,
1503                     &info->dom.samr_pol_connect) : False;
1504
1505         res = res ? samr_close(smb_cli, fnum, 
1506                     &info->dom.samr_pol_open_domain) : False;
1507
1508         /* close the session */
1509         cli_nt_session_close(smb_cli, fnum);
1510
1511         if (res)
1512         {
1513                 DEBUG(5,("cmd_sam_query_dominfo: succeeded\n"));
1514         }
1515         else
1516         {
1517                 DEBUG(5,("cmd_sam_query_dominfo: failed\n"));
1518         }
1519 }
1520
1521
1522 /****************************************************************************
1523 SAM aliases query.
1524 ****************************************************************************/
1525 void cmd_sam_enum_aliases(struct client_info *info)
1526 {
1527         uint16 fnum;
1528         fstring srv_name;
1529         fstring domain;
1530         fstring sid;
1531         DOM_SID sid1;
1532         BOOL res = True;
1533         BOOL request_member_info = False;
1534         uint32 flags = 0x200003f3; /* access control permissions */
1535         fstring tmp;
1536         uint32 alias_idx;
1537
1538         sid_to_string(sid, &info->dom.level5_sid);
1539         fstrcpy(domain, info->dom.level5_dom);
1540 #if 0
1541         fstrcpy(sid   , "S-1-5-20");
1542 #endif
1543         if (strlen(sid) == 0)
1544         {
1545                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
1546                 return;
1547         }
1548
1549         string_to_sid(&sid1, sid);
1550
1551         fstrcpy(srv_name, "\\\\");
1552         fstrcat(srv_name, info->dest_host);
1553         strupper(srv_name);
1554
1555         /* a bad way to do token parsing... */
1556         if (next_token(NULL, tmp, NULL, sizeof(tmp)))
1557         {
1558                 request_member_info |= strequal(tmp, "-m");
1559         }
1560
1561         fprintf(out_hnd, "SAM Enumerate Aliases\n");
1562         fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
1563                           info->myhostname, srv_name, domain, sid);
1564
1565         /* open SAMR session.  negotiate credentials */
1566         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
1567
1568         /* establish a connection. */
1569         res = res ? samr_connect(smb_cli, fnum,
1570                                 srv_name, 0x00000020,
1571                                 &info->dom.samr_pol_connect) : False;
1572
1573         /* connect to the domain */
1574         res = res ? samr_open_domain(smb_cli, fnum,
1575                     &info->dom.samr_pol_connect, flags, &sid1,
1576                     &info->dom.samr_pol_open_domain) : False;
1577
1578         info->dom.sam = NULL;
1579
1580         /* read some aliases */
1581         res = res ? samr_enum_dom_aliases(smb_cli, fnum,
1582                                 &info->dom.samr_pol_open_domain,
1583                                 0xffff,
1584                                 &info->dom.sam, &info->dom.num_sam_entries) : False;
1585
1586         if (res && info->dom.num_sam_entries == 0)
1587         {
1588                 fprintf(out_hnd, "No aliases\n");
1589         }
1590
1591         if (res)
1592         {
1593         for (alias_idx = 0; alias_idx < info->dom.num_sam_entries; alias_idx++)
1594         {
1595                 uint32 alias_rid = info->dom.sam[alias_idx].rid;
1596
1597                 fprintf(out_hnd, "Alias RID: %8x  Group Name: %s\n",
1598                                   alias_rid,
1599                                   info->dom.sam[alias_idx].acct_name);
1600
1601                 if (request_member_info)
1602                 {
1603                         uint32 num_aliases;
1604                         DOM_SID2 sid_mem[MAX_LOOKUP_SIDS];
1605
1606                         /* send user aliases query */
1607                         if (get_samr_query_aliasmem(smb_cli, fnum, 
1608                                 &info->dom.samr_pol_open_domain,
1609                                                 alias_rid, &num_aliases, sid_mem))
1610                         {
1611                                 uint16 fnum_lsa;
1612                                 BOOL res3 = True;
1613                                 BOOL res4 = True;
1614                                 char **names = NULL;
1615                                 int num_names = 0;
1616                                 DOM_SID **sids = NULL;
1617                                 int i;
1618
1619                                 if (num_aliases != 0)
1620                                 {
1621                                         sids = malloc(num_aliases * sizeof(DOM_SID*));
1622                                 }
1623
1624                                 res3 = sids != NULL;
1625                                 if (res3)
1626                                 {
1627                                         for (i = 0; i < num_aliases; i++)
1628                                         {
1629                                                 sids[i] = &sid_mem[i].sid;
1630                                         }
1631                                 }
1632
1633                                 /* open LSARPC session. */
1634                                 res3 = res3 ? cli_nt_session_open(smb_cli, PIPE_LSARPC, &fnum_lsa) : False;
1635
1636                                 /* lookup domain controller; receive a policy handle */
1637                                 res3 = res3 ? lsa_open_policy(smb_cli, fnum_lsa,
1638                                                         srv_name,
1639                                                         &info->dom.lsa_info_pol, True) : False;
1640
1641                                 /* send lsa lookup sids call */
1642                                 res4 = res3 ? lsa_lookup_sids(smb_cli, fnum_lsa, 
1643                                                                &info->dom.lsa_info_pol,
1644                                                                num_aliases, sids, 
1645                                                                &names, NULL, &num_names) : False;
1646
1647                                 res3 = res3 ? lsa_close(smb_cli, fnum_lsa, &info->dom.lsa_info_pol) : False;
1648
1649                                 cli_nt_session_close(smb_cli, fnum_lsa);
1650
1651                                 if (res4 && names != NULL)
1652                                 {
1653                                         display_alias_members(out_hnd, ACTION_HEADER   , num_names, names);
1654                                         display_alias_members(out_hnd, ACTION_ENUMERATE, num_names, names);
1655                                         display_alias_members(out_hnd, ACTION_FOOTER   , num_names, names);
1656                                 }
1657                                 if (names != NULL)
1658                                 {
1659                                         for (i = 0; i < num_names; i++)
1660                                         {
1661                                                 if (names[i] != NULL)
1662                                                 {
1663                                                         free(names[i]);
1664                                                 }
1665                                         }
1666                                         free(names);
1667                                 }
1668                                 if (sids != NULL)
1669                                 {
1670                                         free(sids);
1671                                 }
1672                         }
1673                 }
1674         }
1675         }
1676
1677         res = res ? samr_close(smb_cli, fnum, 
1678                     &info->dom.samr_pol_connect) : False;
1679
1680         res = res ? samr_close(smb_cli, fnum,
1681                     &info->dom.samr_pol_open_domain) : False;
1682
1683         /* close the session */
1684         cli_nt_session_close(smb_cli, fnum);
1685
1686         if (info->dom.sam != NULL)
1687         {
1688                 free(info->dom.sam);
1689         }
1690
1691         if (res)
1692         {
1693                 DEBUG(5,("cmd_sam_enum_aliases: succeeded\n"));
1694         }
1695         else
1696         {
1697                 DEBUG(5,("cmd_sam_enum_aliases: failed\n"));
1698         }
1699 }
1700
1701 static void req_groupmem_info(struct client_info *info, uint16 fnum,
1702                                 uint32 group_rid)
1703 {
1704         uint32 num_mem;
1705         uint32 rid_mem[MAX_LOOKUP_SIDS];
1706         uint32 attr_mem[MAX_LOOKUP_SIDS];
1707
1708         /* get group members */
1709         if (get_samr_query_groupmem(smb_cli, fnum, 
1710                 &info->dom.samr_pol_open_domain,
1711                 group_rid, &num_mem, rid_mem, attr_mem))
1712         {
1713                 BOOL res3 = True;
1714                 int num_names = 0;
1715                 fstring names[MAX_LOOKUP_SIDS];
1716                 uint32 types[MAX_LOOKUP_SIDS];
1717
1718                 res3 = samr_query_lookup_rids(smb_cli, fnum,
1719                                    &info->dom.samr_pol_open_domain, 1000,
1720                                    num_mem, rid_mem, &num_names, names, types);
1721
1722                 if (res3)
1723                 {
1724                         display_group_members(out_hnd, ACTION_HEADER   , num_names, names, types);
1725                         display_group_members(out_hnd, ACTION_ENUMERATE, num_names, names, types);
1726                         display_group_members(out_hnd, ACTION_FOOTER   , num_names, names, types);
1727                 }
1728         }
1729 }
1730
1731 /****************************************************************************
1732 SAM groups query.
1733 ****************************************************************************/
1734 void cmd_sam_enum_groups(struct client_info *info)
1735 {
1736         uint16 fnum;
1737         fstring srv_name;
1738         fstring domain;
1739         fstring sid;
1740         DOM_SID sid1;
1741         BOOL res = True;
1742         BOOL request_member_info = False;
1743         uint32 flags = 0x200003f3; /* access control permissions. */
1744         fstring tmp;
1745         uint32 group_idx;
1746
1747         sid_copy(&sid1, &info->dom.level5_sid);
1748
1749         if (sid1.num_auths == 0)
1750         {
1751                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
1752                 return;
1753         }
1754
1755         sid_to_string(sid, &sid1);
1756         fstrcpy(domain, info->dom.level3_dom);
1757
1758         fstrcpy(srv_name, "\\\\");
1759         fstrcat(srv_name, info->dest_host);
1760         strupper(srv_name);
1761
1762         /* a bad way to do token parsing... */
1763         if (next_token(NULL, tmp, NULL, sizeof(tmp)))
1764         {
1765                 request_member_info |= strequal(tmp, "-m");
1766         }
1767
1768         fprintf(out_hnd, "SAM Enumerate Groups\n");
1769         fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
1770                           info->myhostname, srv_name, domain, sid);
1771
1772         /* open SAMR session.  negotiate credentials */
1773         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
1774
1775         /* establish a connection. */
1776         res = res ? samr_connect(smb_cli, fnum,
1777                                 srv_name, 0x00000020,
1778                                 &info->dom.samr_pol_connect) : False;
1779
1780         /* connect to the domain */
1781         res = res ? samr_open_domain(smb_cli, fnum,
1782                     &info->dom.samr_pol_connect, flags, &sid1,
1783                     &info->dom.samr_pol_open_domain) : False;
1784
1785         info->dom.sam = NULL;
1786
1787         /* read some groups */
1788         res = res ? samr_enum_dom_groups(smb_cli, fnum,
1789                                 &info->dom.samr_pol_open_domain,
1790                                 0xffff,
1791                                 &info->dom.sam, &info->dom.num_sam_entries) : False;
1792
1793         if (res && info->dom.num_sam_entries == 0)
1794         {
1795                 fprintf(out_hnd, "No groups\n");
1796         }
1797
1798         if (res)
1799         {
1800                 for (group_idx = 0; group_idx < info->dom.num_sam_entries; group_idx++)
1801                 {
1802                         uint32 group_rid = info->dom.sam[group_idx].rid;
1803
1804                         fprintf(out_hnd, "Group RID: %8x  Group Name: %s\n",
1805                                           group_rid,
1806                                           info->dom.sam[group_idx].acct_name);
1807
1808                         if (request_member_info)
1809                         {
1810                                 req_groupmem_info(info, fnum, group_rid);
1811                         }
1812                 }
1813         }
1814
1815         res = res ? samr_close(smb_cli, fnum,
1816                     &info->dom.samr_pol_open_domain) : False;
1817
1818         res = res ? samr_close(smb_cli, fnum, 
1819                     &info->dom.samr_pol_connect) : False;
1820
1821         /* close the session */
1822         cli_nt_session_close(smb_cli, fnum);
1823
1824         if (info->dom.sam != NULL)
1825         {
1826                 free(info->dom.sam);
1827         }
1828
1829         if (res)
1830         {
1831                 DEBUG(5,("cmd_sam_enum_groups: succeeded\n"));
1832         }
1833         else
1834         {
1835                 DEBUG(5,("cmd_sam_enum_groups: failed\n"));
1836         }
1837 }