877abce66ee11b5df75c77da3c40414e0707e5c6
[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         fstring srv_name;
47         fstring domain;
48         fstring sid;
49         char *new_passwd;
50         BOOL res = True;
51         uchar nt_newpass[516];
52         uchar nt_hshhash[16];
53         uchar nt_newhash[16];
54         uchar nt_oldhash[16];
55         uchar lm_newpass[516];
56         uchar lm_newhash[16];
57         uchar lm_hshhash[16];
58         uchar lm_oldhash[16];
59
60         fstrcpy(sid   , info->dom.level5_sid);
61         fstrcpy(domain, info->dom.level5_dom);
62
63         fstrcpy(srv_name, "\\\\");
64         fstrcat(srv_name, info->dest_host);
65         strupper(srv_name);
66
67         fprintf(out_hnd, "SAM NT Password Change\n");
68
69 #if 0
70         struct pwd_info new_pwd;
71         pwd_read(&new_pwd, "New Password (ONCE: this is test code!):", True);
72 #endif
73         new_passwd = (char*)getpass("New Password (ONCE ONLY - get it right :-)");
74
75         nt_lm_owf_gen(new_passwd, lm_newhash, nt_newhash);
76         pwd_get_lm_nt_16(&(smb_cli->pwd), lm_oldhash, nt_oldhash );
77         make_oem_passwd_hash(nt_newpass, new_passwd, nt_oldhash, True);
78         make_oem_passwd_hash(lm_newpass, new_passwd, lm_oldhash, True);
79         E_old_pw_hash(lm_newhash, lm_oldhash, lm_hshhash);
80         E_old_pw_hash(lm_newhash, nt_oldhash, nt_hshhash);
81
82         cli_nt_set_ntlmssp_flgs(smb_cli,
83                                     NTLMSSP_NEGOTIATE_UNICODE |
84                                     NTLMSSP_NEGOTIATE_OEM |
85                                     NTLMSSP_NEGOTIATE_SIGN |
86                                     NTLMSSP_NEGOTIATE_SEAL |
87                                     NTLMSSP_NEGOTIATE_LM_KEY |
88                                     NTLMSSP_NEGOTIATE_NTLM |
89                                     NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
90                                     NTLMSSP_NEGOTIATE_00001000 |
91                                     NTLMSSP_NEGOTIATE_00002000);
92
93         /* open SAMR session.  */
94         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
95
96         /* establish a connection. */
97         res = res ? do_samr_unknown_38(smb_cli, srv_name) : False;
98
99         /* establish a connection. */
100         res = res ? do_samr_chgpasswd_user(smb_cli,
101                                            srv_name, smb_cli->user_name,
102                                            nt_newpass, nt_hshhash,
103                                            lm_newpass, lm_hshhash) : False;
104         /* close the session */
105         cli_nt_session_close(smb_cli);
106
107         if (res)
108         {
109                 DEBUG(5,("cmd_sam_ntpasswd_chg: succeeded\n"));
110         }
111         else
112         {
113                 DEBUG(5,("cmd_sam_ntpasswd_chg: failed\n"));
114         }
115 }
116
117
118 /****************************************************************************
119 experimental SAM encryted rpc test connection
120 ****************************************************************************/
121 void cmd_sam_test(struct client_info *info)
122 {
123         fstring srv_name;
124         fstring domain;
125         fstring sid;
126         BOOL res = True;
127
128         fstrcpy(sid   , info->dom.level5_sid);
129         fstrcpy(domain, info->dom.level5_dom);
130
131 /*
132         if (strlen(sid) == 0)
133         {
134                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
135                 return;
136         }
137 */
138         fstrcpy(srv_name, "\\\\");
139         fstrcat(srv_name, info->dest_host);
140         strupper(srv_name);
141
142         fprintf(out_hnd, "SAM Encryption Test\n");
143
144         /* open SAMR session.  */
145         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
146
147         /* establish a connection. */
148         res = res ? do_samr_unknown_38(smb_cli, srv_name) : False;
149
150         /* close the session */
151         cli_nt_session_close(smb_cli);
152
153         if (res)
154         {
155                 DEBUG(5,("cmd_sam_test: succeeded\n"));
156         }
157         else
158         {
159                 DEBUG(5,("cmd_sam_test: failed\n"));
160         }
161 }
162
163
164 /****************************************************************************
165 experimental SAM users enum.
166 ****************************************************************************/
167 void cmd_sam_enum_users(struct client_info *info)
168 {
169         fstring srv_name;
170         fstring domain;
171         fstring sid;
172         DOM_SID sid1;
173         int user_idx;
174         BOOL res = True;
175         BOOL request_user_info  = False;
176         BOOL request_group_info = False;
177         uint16 num_entries = 0;
178         uint16 unk_0 = 0x0;
179         uint16 acb_mask = 0;
180         uint16 unk_1 = 0x0;
181         uint32 admin_rid = 0x304; /* absolutely no idea. */
182         fstring tmp;
183
184         fstrcpy(sid   , info->dom.level5_sid);
185         fstrcpy(domain, info->dom.level5_dom);
186
187         if (strlen(sid) == 0)
188         {
189                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
190                 return;
191         }
192
193         make_dom_sid(&sid1, sid);
194
195         fstrcpy(srv_name, "\\\\");
196         fstrcat(srv_name, info->dest_host);
197         strupper(srv_name);
198
199         /* a bad way to do token parsing... */
200         if (next_token(NULL, tmp, NULL, sizeof(tmp)))
201         {
202                 request_user_info  |= strequal(tmp, "-u");
203                 request_group_info |= strequal(tmp, "-g");
204         }
205
206         if (next_token(NULL, tmp, NULL, sizeof(tmp)))
207         {
208                 request_user_info  |= strequal(tmp, "-u");
209                 request_group_info |= strequal(tmp, "-g");
210         }
211
212 #ifdef DEBUG_TESTING
213         if (next_token(NULL, tmp, NULL, sizeof(tmp)))
214         {
215                 num_entries = (uint16)strtol(tmp, (char**)NULL, 16);
216         }
217
218         if (next_token(NULL, tmp, NULL, sizeof(tmp)))
219         {
220                 unk_0 = (uint16)strtol(tmp, (char**)NULL, 16);
221         }
222
223         if (next_token(NULL, tmp, NULL, sizeof(tmp)))
224         {
225                 acb_mask = (uint16)strtol(tmp, (char**)NULL, 16);
226         }
227
228         if (next_token(NULL, tmp, NULL, sizeof(tmp)))
229         {
230                 unk_1 = (uint16)strtol(tmp, (char**)NULL, 16);
231         }
232 #endif
233
234         fprintf(out_hnd, "SAM Enumerate Users\n");
235         fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
236                           info->myhostname, srv_name, domain, sid);
237
238 #ifdef DEBUG_TESTING
239         DEBUG(5,("Number of entries:%d unk_0:%04x acb_mask:%04x unk_1:%04x\n",
240                   num_entries, unk_0, acb_mask, unk_1));
241 #endif
242
243         /* open SAMR session.  negotiate credentials */
244         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
245
246         /* establish a connection. */
247         res = res ? do_samr_connect(smb_cli, 
248                                 srv_name, 0x00000020,
249                                 &info->dom.samr_pol_connect) : False;
250
251         /* connect to the domain */
252         res = res ? do_samr_open_domain(smb_cli, 
253                     &info->dom.samr_pol_connect, admin_rid, &sid1,
254                     &info->dom.samr_pol_open_domain) : False;
255
256         /* read some users */
257         res = res ? do_samr_enum_dom_users(smb_cli, 
258                                 &info->dom.samr_pol_open_domain,
259                     num_entries, unk_0, acb_mask, unk_1, 0xffff,
260                                 &info->dom.sam, &info->dom.num_sam_entries) : False;
261
262         if (res && info->dom.num_sam_entries == 0)
263         {
264                 fprintf(out_hnd, "No users\n");
265         }
266
267         if (request_user_info || request_group_info)
268         {
269                 /* query all the users */
270                 user_idx = 0;
271
272                 while (res && user_idx < info->dom.num_sam_entries)
273                 {
274                         uint32 user_rid = info->dom.sam[user_idx].smb_userid;
275                         SAM_USER_INFO_21 usr;
276
277                         fprintf(out_hnd, "User RID: %8x  User Name: %s\n",
278                                           user_rid,
279                                           info->dom.sam[user_idx].acct_name);
280
281                         if (request_user_info)
282                         {
283                                 /* send user info query, level 0x15 */
284                                 if (get_samr_query_userinfo(smb_cli,
285                                                         &info->dom.samr_pol_open_domain,
286                                                         0x15, user_rid, &usr))
287                                 {
288                                         display_sam_user_info_21(out_hnd, ACTION_HEADER   , &usr);
289                                         display_sam_user_info_21(out_hnd, ACTION_ENUMERATE, &usr);
290                                         display_sam_user_info_21(out_hnd, ACTION_FOOTER   , &usr);
291                                 }
292                         }
293
294                         if (request_group_info)
295                         {
296                                 uint32 num_groups;
297                                 DOM_GID gid[LSA_MAX_GROUPS];
298
299                                 /* send user group query */
300                                 if (get_samr_query_usergroups(smb_cli,
301                                                         &info->dom.samr_pol_open_domain,
302                                                         user_rid, &num_groups, gid))
303                                 {
304                                         display_group_rid_info(out_hnd, ACTION_HEADER   , num_groups, gid);
305                                         display_group_rid_info(out_hnd, ACTION_ENUMERATE, num_groups, gid);
306                                         display_group_rid_info(out_hnd, ACTION_FOOTER   , num_groups, gid);
307                                 }
308                         }
309
310                         user_idx++;
311                 }
312         }
313
314         res = res ? do_samr_close(smb_cli,
315                     &info->dom.samr_pol_open_domain) : False;
316
317         res = res ? do_samr_close(smb_cli,
318                     &info->dom.samr_pol_connect) : False;
319
320         /* close the session */
321         cli_nt_session_close(smb_cli);
322
323         if (info->dom.sam != NULL)
324         {
325                 free(info->dom.sam);
326         }
327
328         if (res)
329         {
330                 DEBUG(5,("cmd_sam_enum_users: succeeded\n"));
331         }
332         else
333         {
334                 DEBUG(5,("cmd_sam_enum_users: failed\n"));
335         }
336 }
337
338
339 /****************************************************************************
340 experimental SAM user query.
341 ****************************************************************************/
342 void cmd_sam_query_user(struct client_info *info)
343 {
344         fstring srv_name;
345         fstring domain;
346         fstring sid;
347         DOM_SID sid1;
348         int user_idx = 0;  /* FIXME maybe ... */
349         BOOL res = True;
350         uint32 admin_rid = 0x304; /* absolutely no idea. */
351         fstring rid_str ;
352         fstring info_str;
353         uint32 user_rid = 0;
354         uint32 info_level = 0x15;
355
356         SAM_USER_INFO_21 usr;
357
358         fstrcpy(sid   , info->dom.level5_sid);
359         fstrcpy(domain, info->dom.level5_dom);
360
361         if (strlen(sid) == 0)
362         {
363                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
364                 return;
365         }
366
367         make_dom_sid(&sid1, sid);
368
369         fstrcpy(srv_name, "\\\\");
370         fstrcat(srv_name, info->dest_host);
371         strupper(srv_name);
372
373         if (next_token(NULL, rid_str , NULL, sizeof(rid_str )) &&
374             next_token(NULL, info_str, NULL, sizeof(info_str)))
375         {
376                 user_rid   = (uint32)strtol(rid_str , (char**)NULL, 16);
377                 info_level = (uint32)strtol(info_str, (char**)NULL, 10);
378         }
379
380         fprintf(out_hnd, "SAM Query User: rid %x info level %d\n",
381                           user_rid, info_level);
382         fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
383                           info->myhostname, srv_name, domain, sid);
384
385         /* open SAMR session.  negotiate credentials */
386         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
387
388         /* establish a connection. */
389         res = res ? do_samr_connect(smb_cli,
390                                 srv_name, 0x00000020,
391                                 &info->dom.samr_pol_connect) : False;
392
393         /* connect to the domain */
394         res = res ? do_samr_open_domain(smb_cli,
395                     &info->dom.samr_pol_connect, admin_rid, &sid1,
396                     &info->dom.samr_pol_open_domain) : False;
397
398         fprintf(out_hnd, "User RID: %8x  User Name: %s\n",
399                           user_rid,
400                           info->dom.sam[user_idx].acct_name);
401
402         /* send user info query, level */
403         if (get_samr_query_userinfo(smb_cli,
404                                         &info->dom.samr_pol_open_domain,
405                                         info_level, user_rid, &usr))
406         {
407                 if (info_level == 0x15)
408                 {
409                         display_sam_user_info_21(out_hnd, ACTION_HEADER   , &usr);
410                         display_sam_user_info_21(out_hnd, ACTION_ENUMERATE, &usr);
411                         display_sam_user_info_21(out_hnd, ACTION_FOOTER   , &usr);
412                 }
413         }
414
415         res = res ? do_samr_close(smb_cli,
416                     &info->dom.samr_pol_connect) : False;
417
418         res = res ? do_samr_close(smb_cli,
419                     &info->dom.samr_pol_open_domain) : False;
420
421         /* close the session */
422         cli_nt_session_close(smb_cli);
423
424         if (res)
425         {
426                 DEBUG(5,("cmd_sam_query_user: succeeded\n"));
427         }
428         else
429         {
430                 DEBUG(5,("cmd_sam_query_user: failed\n"));
431         }
432 }
433
434
435 /****************************************************************************
436 experimental SAM groups query.
437 ****************************************************************************/
438 void cmd_sam_query_groups(struct client_info *info)
439 {
440         fstring srv_name;
441         fstring domain;
442         fstring sid;
443         DOM_SID sid1;
444         BOOL res = True;
445         fstring info_str;
446         uint32 switch_value = 2;
447         uint32 admin_rid = 0x304; /* absolutely no idea. */
448
449         fstrcpy(sid   , info->dom.level5_sid);
450         fstrcpy(domain, info->dom.level5_dom);
451
452         if (strlen(sid) == 0)
453         {
454                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
455                 return;
456         }
457
458         make_dom_sid(&sid1, sid);
459
460         fstrcpy(srv_name, "\\\\");
461         fstrcat(srv_name, info->dest_host);
462         strupper(srv_name);
463
464         if (next_token(NULL, info_str, NULL, sizeof(info_str)))
465         {
466                 switch_value = (uint32)strtol(info_str, (char**)NULL, 10);
467         }
468
469         fprintf(out_hnd, "SAM Query Groups: info level %d\n", switch_value);
470         fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
471                           info->myhostname, srv_name, domain, sid);
472
473         /* open SAMR session.  negotiate credentials */
474         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
475
476         /* establish a connection. */
477         res = res ? do_samr_connect(smb_cli, 
478                                 srv_name, 0x00000020,
479                                 &info->dom.samr_pol_connect) : False;
480
481         /* connect to the domain */
482         res = res ? do_samr_open_domain(smb_cli, 
483                     &info->dom.samr_pol_connect, admin_rid, &sid1,
484                     &info->dom.samr_pol_open_domain) : False;
485
486         /* send a samr 0x8 command */
487         res = res ? do_samr_unknown_8(smb_cli,
488                     &info->dom.samr_pol_open_domain, switch_value) : False;
489
490         res = res ? do_samr_close(smb_cli,
491                     &info->dom.samr_pol_connect) : False;
492
493         res = res ? do_samr_close(smb_cli, 
494                     &info->dom.samr_pol_open_domain) : False;
495
496         /* close the session */
497         cli_nt_session_close(smb_cli);
498
499         if (res)
500         {
501                 DEBUG(5,("cmd_sam_query_groups: succeeded\n"));
502         }
503         else
504         {
505                 DEBUG(5,("cmd_sam_query_groups: failed\n"));
506         }
507 }
508
509
510 /****************************************************************************
511 experimental SAM aliases query.
512 ****************************************************************************/
513 void cmd_sam_enum_aliases(struct client_info *info)
514 {
515         fstring srv_name;
516         fstring domain;
517         fstring sid;
518         DOM_SID sid1;
519         BOOL res = True;
520         BOOL request_user_info  = False;
521         BOOL request_alias_info = False;
522         uint32 admin_rid = 0x304; /* absolutely no idea. */
523         fstring tmp;
524
525         uint32 num_aliases = 3;
526         uint32 alias_rid[3] = { DOMAIN_GROUP_RID_ADMINS, DOMAIN_GROUP_RID_USERS, DOMAIN_GROUP_RID_GUESTS };
527         fstring alias_names [3];
528         uint32  num_als_usrs[3];
529
530         fstrcpy(sid   , info->dom.level5_sid);
531         fstrcpy(domain, info->dom.level5_dom);
532
533         if (strlen(sid) == 0)
534         {
535                 fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
536                 return;
537         }
538
539         make_dom_sid(&sid1, sid);
540
541         fstrcpy(srv_name, "\\\\");
542         fstrcat(srv_name, info->dest_host);
543         strupper(srv_name);
544
545         /* a bad way to do token parsing... */
546         if (next_token(NULL, tmp, NULL, sizeof(tmp)))
547         {
548                 request_user_info  |= strequal(tmp, "-u");
549                 request_alias_info |= strequal(tmp, "-g");
550         }
551
552         if (next_token(NULL, tmp, NULL, sizeof(tmp)))
553         {
554                 request_user_info  |= strequal(tmp, "-u");
555                 request_alias_info |= strequal(tmp, "-g");
556         }
557
558         fprintf(out_hnd, "SAM Enumerate Aliases\n");
559         fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
560                           info->myhostname, srv_name, domain, sid);
561
562         /* open SAMR session.  negotiate credentials */
563         res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
564
565         /* establish a connection. */
566         res = res ? do_samr_connect(smb_cli,
567                                 srv_name, 0x00000020,
568                                 &info->dom.samr_pol_connect) : False;
569
570         /* connect to the domain */
571         res = res ? do_samr_open_domain(smb_cli,
572                     &info->dom.samr_pol_connect, admin_rid, &sid1,
573                     &info->dom.samr_pol_open_domain) : False;
574
575         /* send a query on the aliase */
576         res = res ? do_samr_query_unknown_12(smb_cli,
577                     &info->dom.samr_pol_open_domain, admin_rid, num_aliases, alias_rid,
578                     &num_aliases, alias_names, num_als_usrs) : False;
579
580         if (res)
581         {
582                 display_alias_name_info(out_hnd, ACTION_HEADER   , num_aliases, alias_names, num_als_usrs);
583                 display_alias_name_info(out_hnd, ACTION_ENUMERATE, num_aliases, alias_names, num_als_usrs);
584                 display_alias_name_info(out_hnd, ACTION_FOOTER   , num_aliases, alias_names, num_als_usrs);
585         }
586
587 #if 0
588
589         /* read some users */
590         res = res ? do_samr_enum_dom_users(smb_cli,
591                                 &info->dom.samr_pol_open_domain,
592                     num_entries, unk_0, acb_mask, unk_1, 0xffff,
593                                 info->dom.sam, &info->dom.num_sam_entries) : False;
594
595         if (res && info->dom.num_sam_entries == 0)
596         {
597                 fprintf(out_hnd, "No users\n");
598         }
599
600         if (request_user_info || request_alias_info)
601         {
602                 /* query all the users */
603                 user_idx = 0;
604
605                 while (res && user_idx < info->dom.num_sam_entries)
606                 {
607                         uint32 user_rid = info->dom.sam[user_idx].smb_userid;
608                         SAM_USER_INFO_21 usr;
609
610                         fprintf(out_hnd, "User RID: %8x  User Name: %s\n",
611                                           user_rid,
612                                           info->dom.sam[user_idx].acct_name);
613
614                         if (request_user_info)
615                         {
616                                 /* send user info query, level 0x15 */
617                                 if (get_samr_query_userinfo(smb_cli,
618                                                         &info->dom.samr_pol_open_domain,
619                                                         0x15, user_rid, &usr))
620                                 {
621                                         display_sam_user_info_21(out_hnd, ACTION_HEADER   , &usr);
622                                         display_sam_user_info_21(out_hnd, ACTION_ENUMERATE, &usr);
623                                         display_sam_user_info_21(out_hnd, ACTION_FOOTER   , &usr);
624                                 }
625                         }
626
627                         if (request_alias_info)
628                         {
629                                 uint32 num_aliases;
630                                 DOM_GID gid[LSA_MAX_GROUPS];
631
632                                 /* send user aliase query */
633                                 if (get_samr_query_useraliases(smb_cli, 
634                                                         &info->dom.samr_pol_open_domain,
635                                                         user_rid, &num_aliases, gid))
636                                 {
637                                         display_alias_info(out_hnd, ACTION_HEADER   , num_aliases, gid);
638                                         display_alias_info(out_hnd, ACTION_ENUMERATE, num_aliases, gid);
639                                         display_alias_info(out_hnd, ACTION_FOOTER   , num_aliases, gid);
640                                 }
641                         }
642
643                         user_idx++;
644                 }
645         }
646 #endif
647
648         res = res ? do_samr_close(smb_cli, 
649                     &info->dom.samr_pol_connect) : False;
650
651         res = res ? do_samr_close(smb_cli,
652                     &info->dom.samr_pol_open_domain) : False;
653
654         /* close the session */
655         cli_nt_session_close(smb_cli);
656
657         if (res)
658         {
659                 DEBUG(5,("cmd_sam_enum_users: succeeded\n"));
660         }
661         else
662         {
663                 DEBUG(5,("cmd_sam_enum_users: failed\n"));
664         }
665 }
666
667