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