the next dialog: user-groups. it's not very sensible what appears, but hey:
[samba.git] / source3 / rpc_server / srv_samr.c
1
2 /* 
3  *  Unix SMB/Netbios implementation.
4  *  Version 1.9.
5  *  RPC Pipe client / server routines
6  *  Copyright (C) Andrew Tridgell              1992-1997,
7  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
8  *  Copyright (C) Paul Ashton                       1997.
9  *  
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *  
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *  
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24
25
26 #include "includes.h"
27 #include "nterr.h"
28
29 extern int DEBUGLEVEL;
30
31 extern BOOL sam_logon_in_ssb;
32 extern pstring samlogon_user;
33 extern pstring global_myworkgroup;
34 extern pstring global_myname;
35 extern DOM_SID global_machine_sid;
36
37 extern rid_name domain_group_rids[];
38 extern rid_name domain_alias_rids[];
39
40 /*******************************************************************
41   This next function should be replaced with something that
42   dynamically returns the correct user info..... JRA.
43  ********************************************************************/
44
45 static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf,
46                                 int start_idx,
47                                 int *total_entries, int *num_entries,
48                                 int max_num_entries,
49                                 uint16 acb_mask)
50 {
51         void *vp = NULL;
52         struct sam_passwd *pwd = NULL;
53
54         (*num_entries) = 0;
55         (*total_entries) = 0;
56
57         if (pw_buf == NULL) return False;
58
59         vp = startsmbpwent(False);
60         if (!vp)
61         {
62                 DEBUG(0, ("get_sampwd_entries: Unable to open SMB password database.\n"));
63                 return False;
64         }
65
66         while (((pwd = getsam21pwent(vp)) != NULL) && (*num_entries) < max_num_entries)
67         {
68                 int user_name_len;
69
70                 if (start_idx > 0)
71                 {
72                         /* skip the requested number of entries.
73                            not very efficient, but hey...
74                          */
75                         start_idx--;
76                         continue;
77                 }
78
79                 user_name_len = strlen(pwd->smb_name);
80                 make_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->smb_name, user_name_len-1);
81                 make_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len-1, 
82                                user_name_len-1, 1);
83                 pw_buf[(*num_entries)].user_rid = pwd->user_rid;
84                 bzero( pw_buf[(*num_entries)].nt_pwd , 16);
85
86                 /* Now check if the NT compatible password is available. */
87                 if (pwd->smb_nt_passwd != NULL)
88                 {
89                         memcpy( pw_buf[(*num_entries)].nt_pwd , pwd->smb_nt_passwd, 16);
90                 }
91
92                 pw_buf[(*num_entries)].acb_info = (uint16)pwd->acct_ctrl;
93
94                 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
95                           (*num_entries), pwd->smb_name,
96                           pwd->user_rid, pwd->acct_ctrl));
97
98                 if (acb_mask == 0 || IS_BITS_SET_SOME(pwd->acct_ctrl, acb_mask))
99                 {
100                         DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
101                         (*num_entries)++;
102                 }
103                 else
104                 {
105                         DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
106                 }
107
108                 (*total_entries)++;
109         }
110
111         endsmbpwent(vp);
112
113         return (*num_entries) > 0;
114 }
115
116 /*******************************************************************
117  samr_reply_unknown_1
118  ********************************************************************/
119 static void samr_reply_close_hnd(SAMR_Q_CLOSE_HND *q_u,
120                                 prs_struct *rdata)
121 {
122         SAMR_R_CLOSE_HND r_u;
123
124         /* set up the SAMR unknown_1 response */
125         bzero(r_u.pol.data, POL_HND_SIZE);
126
127         /* close the policy handle */
128         if (close_lsa_policy_hnd(&(q_u->pol)))
129         {
130                 r_u.status = 0;
131         }
132         else
133         {
134                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_INVALID;
135         }
136
137         DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
138
139         /* store the response in the SMB stream */
140         samr_io_r_close_hnd("", &r_u, rdata, 0);
141
142         DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
143
144 }
145
146 /*******************************************************************
147  api_samr_close_hnd
148  ********************************************************************/
149 static void api_samr_close_hnd( uint16 vuid, prs_struct *data, prs_struct *rdata)
150 {
151         SAMR_Q_CLOSE_HND q_u;
152
153         /* grab the samr unknown 1 */
154         samr_io_q_close_hnd("", &q_u, data, 0);
155
156         /* construct reply.  always indicate success */
157         samr_reply_close_hnd(&q_u, rdata);
158 }
159
160
161 /*******************************************************************
162  samr_reply_open_domain
163  ********************************************************************/
164 static void samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
165                                 prs_struct *rdata)
166 {
167         SAMR_R_OPEN_DOMAIN r_u;
168         BOOL pol_open = False;
169
170         r_u.status = 0x0;
171
172         /* find the connection policy handle. */
173         if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->connect_pol)) == -1))
174         {
175                 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
176         }
177
178         /* get a (unique) handle.  open a policy on it. */
179         if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.domain_pol))))
180         {
181                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
182         }
183
184         /* associate the domain SID with the (unique) handle. */
185         if (r_u.status == 0x0 && !set_lsa_policy_samr_sid(&(r_u.domain_pol), &(q_u->dom_sid.sid)))
186         {
187                 /* oh, whoops.  don't know what error message to return, here */
188                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
189         }
190
191         if (r_u.status != 0 && pol_open)
192         {
193                 close_lsa_policy_hnd(&(r_u.domain_pol));
194         }
195
196         DEBUG(5,("samr_open_domain: %d\n", __LINE__));
197
198         /* store the response in the SMB stream */
199         samr_io_r_open_domain("", &r_u, rdata, 0);
200
201         DEBUG(5,("samr_open_domain: %d\n", __LINE__));
202
203 }
204
205 /*******************************************************************
206  api_samr_open_domain
207  ********************************************************************/
208 static void api_samr_open_domain( uint16 vuid, prs_struct *data, prs_struct *rdata)
209 {
210         SAMR_Q_OPEN_DOMAIN q_u;
211
212         /* grab the samr open */
213         samr_io_q_open_domain("", &q_u, data, 0);
214
215         /* construct reply.  always indicate success */
216         samr_reply_open_domain(&q_u, rdata);
217 }
218
219
220 /*******************************************************************
221  samr_reply_unknown_2c
222  ********************************************************************/
223 static void samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u,
224                                 prs_struct *rdata)
225 {
226         SAMR_R_UNKNOWN_2C r_u;
227         uint32 status = 0x0;
228         uint32 rid;
229
230         /* find the policy handle.  open a policy on it. */
231         if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
232         {
233                 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
234         }
235
236         /* find the user's rid */
237         if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->user_pol))) == 0xffffffff)
238         {
239                 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
240         }
241
242         make_samr_r_unknown_2c(&r_u, status);
243
244         DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
245
246         /* store the response in the SMB stream */
247         samr_io_r_unknown_2c("", &r_u, rdata, 0);
248
249         DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
250
251 }
252
253 /*******************************************************************
254  api_samr_unknown_2c
255  ********************************************************************/
256 static void api_samr_unknown_2c( uint16 vuid, prs_struct *data, prs_struct *rdata)
257 {
258         SAMR_Q_UNKNOWN_2C q_u;
259
260         /* grab the samr open */
261         samr_io_q_unknown_2c("", &q_u, data, 0);
262
263         /* construct reply.  always indicate success */
264         samr_reply_unknown_2c(&q_u, rdata);
265 }
266
267
268 /*******************************************************************
269  samr_reply_unknown_3
270  ********************************************************************/
271 static void samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
272                                 prs_struct *rdata)
273 {
274         SAMR_R_UNKNOWN_3 r_u;
275         DOM_SID3 sid[MAX_SAM_SIDS];
276         uint32 rid;
277         uint32 status;
278
279         status = 0x0;
280
281         /* find the policy handle.  open a policy on it. */
282         if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
283         {
284                 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
285         }
286
287         /* find the user's rid */
288         if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->user_pol))) == 0xffffffff)
289         {
290                 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
291         }
292
293         if (status == 0x0)
294         {
295                 DOM_SID user_sid;
296                 DOM_SID everyone_sid;
297
298                 user_sid = global_machine_sid;
299
300                 SMB_ASSERT_ARRAY(user_sid.sub_auths, user_sid.num_auths+1);
301
302                 /*
303                  * Add the user RID.
304                  */
305                 user_sid.sub_auths[user_sid.num_auths++] = rid;
306                 
307                         string_to_sid(&everyone_sid, "S-1-1");
308
309                         /* maybe need another 1 or 2 (S-1-5-20-0x220 and S-1-5-20-0x224) */
310                         /* these two are DOMAIN_ADMIN and DOMAIN_ACCT_OP group RIDs */
311                         make_dom_sid3(&(sid[0]), 0x035b, 0x0002, &everyone_sid);
312                         make_dom_sid3(&(sid[1]), 0x0044, 0x0002, &user_sid);
313         }
314
315         make_samr_r_unknown_3(&r_u,
316                                 0x0001, 0x8004,
317                                 0x00000014, 0x0002, 0x0070,
318                                 2, sid, status);
319
320         DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
321
322         /* store the response in the SMB stream */
323         samr_io_r_unknown_3("", &r_u, rdata, 0);
324
325         DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
326
327 }
328
329 /*******************************************************************
330  api_samr_unknown_3
331  ********************************************************************/
332 static void api_samr_unknown_3( uint16 vuid, prs_struct *data, prs_struct *rdata)
333 {
334         SAMR_Q_UNKNOWN_3 q_u;
335
336         /* grab the samr open */
337         samr_io_q_unknown_3("", &q_u, data, 0);
338
339         /* construct reply.  always indicate success */
340         samr_reply_unknown_3(&q_u, rdata);
341 }
342
343
344 /*******************************************************************
345  samr_reply_enum_dom_users
346  ********************************************************************/
347 static void samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
348                                 prs_struct *rdata)
349 {
350         SAMR_R_ENUM_DOM_USERS r_e;
351         SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
352         int num_entries;
353         int total_entries;
354
355         r_e.status = 0x0;
356         r_e.total_num_entries = 0;
357
358         /* find the policy handle.  open a policy on it. */
359         if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
360         {
361                 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
362         }
363
364         DEBUG(5,("samr_reply_enum_dom_users: %d\n", __LINE__));
365
366         become_root(True);
367         get_sampwd_entries(pass, 0, &total_entries, &num_entries, MAX_SAM_ENTRIES, q_u->acb_mask);
368         unbecome_root(True);
369
370         make_samr_r_enum_dom_users(&r_e, total_entries,
371                                    q_u->unknown_0, num_entries,
372                                    pass, r_e.status);
373
374         /* store the response in the SMB stream */
375         samr_io_r_enum_dom_users("", &r_e, rdata, 0);
376
377         DEBUG(5,("samr_enum_dom_users: %d\n", __LINE__));
378
379 }
380
381 /*******************************************************************
382  api_samr_enum_dom_users
383  ********************************************************************/
384 static void api_samr_enum_dom_users( uint16 vuid, prs_struct *data, prs_struct *rdata)
385 {
386         SAMR_Q_ENUM_DOM_USERS q_e;
387
388         /* grab the samr open */
389         samr_io_q_enum_dom_users("", &q_e, data, 0);
390
391         /* construct reply. */
392         samr_reply_enum_dom_users(&q_e, rdata);
393 }
394
395
396 /*******************************************************************
397  samr_reply_enum_dom_groups
398  ********************************************************************/
399 static void samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u,
400                                 prs_struct *rdata)
401 {
402         SAMR_R_ENUM_DOM_GROUPS r_e;
403         SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
404         int num_entries;
405         BOOL got_grps;
406         char *dummy_group = "Domain Admins";
407
408         r_e.status = 0x0;
409         r_e.num_entries = 0;
410
411         /* find the policy handle.  open a policy on it. */
412         if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
413         {
414                 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
415         }
416
417         DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
418
419         got_grps = True;
420         num_entries = 1;
421         make_unistr2(&(pass[0].uni_user_name), dummy_group, strlen(dummy_group));
422         pass[0].user_rid = DOMAIN_GROUP_RID_ADMINS;
423
424         if (r_e.status == 0 && got_grps)
425         {
426                 make_samr_r_enum_dom_groups(&r_e, q_u->start_idx, num_entries, pass, r_e.status);
427         }
428
429         /* store the response in the SMB stream */
430         samr_io_r_enum_dom_groups("", &r_e, rdata, 0);
431
432         DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
433
434 }
435
436 /*******************************************************************
437  api_samr_enum_dom_groups
438  ********************************************************************/
439 static void api_samr_enum_dom_groups( uint16 vuid, prs_struct *data, prs_struct *rdata)
440 {
441         SAMR_Q_ENUM_DOM_GROUPS q_e;
442
443         /* grab the samr open */
444         samr_io_q_enum_dom_groups("", &q_e, data, 0);
445
446         /* construct reply. */
447         samr_reply_enum_dom_groups(&q_e, rdata);
448 }
449
450
451 /*******************************************************************
452  samr_reply_enum_dom_aliases
453  ********************************************************************/
454 static void samr_reply_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_u,
455                                 prs_struct *rdata)
456 {
457         SAMR_R_ENUM_DOM_ALIASES r_e;
458         SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
459         int num_entries;
460         BOOL got_aliases;
461         char *dummy_alias = "admins";
462
463         r_e.status = 0x0;
464         r_e.num_entries = 0;
465
466         /* find the policy handle.  open a policy on it. */
467         if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
468         {
469                 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
470         }
471
472         DEBUG(5,("samr_reply_enum_dom_aliases: %d\n", __LINE__));
473
474         got_aliases = True;
475         num_entries = 1;
476         make_unistr2(&(pass[0].uni_user_name), dummy_alias, strlen(dummy_alias));
477         pass[0].user_rid = BUILTIN_ALIAS_RID_ADMINS;
478
479         if (r_e.status == 0 && got_aliases)
480         {
481                 make_samr_r_enum_dom_aliases(&r_e, num_entries, pass, r_e.status);
482         }
483
484         /* store the response in the SMB stream */
485         samr_io_r_enum_dom_aliases("", &r_e, rdata, 0);
486
487         DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
488
489 }
490
491 /*******************************************************************
492  api_samr_enum_dom_aliases
493  ********************************************************************/
494 static void api_samr_enum_dom_aliases( uint16 vuid, prs_struct *data, prs_struct *rdata)
495 {
496         SAMR_Q_ENUM_DOM_ALIASES q_e;
497
498         /* grab the samr open */
499         samr_io_q_enum_dom_aliases("", &q_e, data, 0);
500
501         /* construct reply. */
502         samr_reply_enum_dom_aliases(&q_e, rdata);
503 }
504
505
506 /*******************************************************************
507  samr_reply_query_dispinfo
508  ********************************************************************/
509 static void samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u,
510                                 prs_struct *rdata)
511 {
512         SAMR_R_QUERY_DISPINFO r_e;
513         SAM_INFO_CTR ctr;
514         SAM_INFO_1 info1;
515         SAM_INFO_2 info2;
516         SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
517         int num_entries = 0;
518         int total_entries = 0;
519         BOOL got_pwds;
520         uint16 switch_level = 0x0;
521
522         ZERO_STRUCT(r_e);
523
524         r_e.status = 0x0;
525
526         DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
527
528         /* find the policy handle.  open a policy on it. */
529         if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
530         {
531                 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
532                 DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n"));
533         }
534
535         if (r_e.status == 0x0)
536         {
537                 become_root(True);
538                 got_pwds = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, MAX_SAM_ENTRIES, 0);
539                 unbecome_root(True);
540
541                 switch (q_u->switch_level)
542                 {
543                         case 0x1:
544                         {
545                         
546                                 /* query disp info is for users */
547                                 switch_level = 0x1;
548                                 make_sam_info_1(&info1, ACB_NORMAL,
549                                         q_u->start_idx, num_entries, pass);
550
551                                 ctr.sam.info1 = &info1;
552
553                                 break;
554                         }
555                         case 0x2:
556                         {
557                                 /* query disp info is for servers */
558                                 switch_level = 0x2;
559                                 make_sam_info_2(&info2, ACB_WSTRUST,
560                                         q_u->start_idx, num_entries, pass);
561
562                                 ctr.sam.info2 = &info2;
563
564                                 break;
565                         }
566                 }
567         }
568
569         if (r_e.status == 0 && got_pwds)
570         {
571                 make_samr_r_query_dispinfo(&r_e, switch_level, &ctr, r_e.status);
572         }
573
574         /* store the response in the SMB stream */
575         samr_io_r_query_dispinfo("", &r_e, rdata, 0);
576
577         DEBUG(5,("samr_query_dispinfo: %d\n", __LINE__));
578
579 }
580
581 /*******************************************************************
582  api_samr_query_dispinfo
583  ********************************************************************/
584 static void api_samr_query_dispinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
585 {
586         SAMR_Q_QUERY_DISPINFO q_e;
587
588         /* grab the samr open */
589         samr_io_q_query_dispinfo("", &q_e, data, 0);
590
591         /* construct reply. */
592         samr_reply_query_dispinfo(&q_e, rdata);
593 }
594
595
596 /*******************************************************************
597  samr_reply_query_aliasinfo
598  ********************************************************************/
599 static void samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
600                                 prs_struct *rdata)
601 {
602         SAMR_R_QUERY_ALIASINFO r_e;
603
604         r_e.status = 0x0;
605         r_e.ptr = 0;
606
607         /* find the policy handle.  open a policy on it. */
608         if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
609         {
610                 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
611         }
612
613         DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__));
614
615         if (r_e.status == 0x0)
616         {
617                 if (q_u->switch_level != 3)
618                 {
619                         r_e.status = NT_STATUS_INVALID_INFO_CLASS;
620                 }
621         }
622
623         make_samr_r_query_aliasinfo(&r_e, q_u->switch_level,
624                             "<account description>",
625                                 r_e.status);
626
627         /* store the response in the SMB stream */
628         samr_io_r_query_aliasinfo("", &r_e, rdata, 0);
629
630         DEBUG(5,("samr_query_aliasinfo: %d\n", __LINE__));
631
632 }
633
634 /*******************************************************************
635  api_samr_query_aliasinfo
636  ********************************************************************/
637 static void api_samr_query_aliasinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
638 {
639         SAMR_Q_QUERY_ALIASINFO q_e;
640
641         /* grab the samr open */
642         samr_io_q_query_aliasinfo("", &q_e, data, 0);
643
644         /* construct reply. */
645         samr_reply_query_aliasinfo(&q_e, rdata);
646 }
647
648
649 /*******************************************************************
650  samr_reply_lookup_ids
651  ********************************************************************/
652 static void samr_reply_lookup_ids(SAMR_Q_LOOKUP_IDS *q_u,
653                                 prs_struct *rdata)
654 {
655         uint32 rid[MAX_SAM_ENTRIES];
656         uint32 status     = 0;
657         int num_rids = q_u->num_sids1;
658
659         SAMR_R_LOOKUP_IDS r_u;
660
661         DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
662
663         if (num_rids > MAX_SAM_ENTRIES)
664         {
665                 num_rids = MAX_SAM_ENTRIES;
666                 DEBUG(5,("samr_lookup_ids: truncating entries to %d\n", num_rids));
667         }
668
669 #if 0
670         int i;
671         SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
672
673         for (i = 0; i < num_rids && status == 0; i++)
674         {
675                 struct sam_passwd *sam_pass;
676                 fstring user_name;
677
678
679                 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
680                                             q_u->uni_user_name[i].uni_str_len));
681
682                 /* find the user account */
683                 become_root(True);
684                 sam_pass = get_smb21pwd_entry(user_name, 0);
685                 unbecome_root(True);
686
687                 if (sam_pass == NULL)
688                 {
689                         status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
690                         rid[i] = 0;
691                 }
692                 else
693                 {
694                         rid[i] = sam_pass->user_rid;
695                 }
696         }
697 #endif
698
699         num_rids = 1;
700         rid[0] = BUILTIN_ALIAS_RID_USERS;
701
702         make_samr_r_lookup_ids(&r_u, num_rids, rid, status);
703
704         /* store the response in the SMB stream */
705         samr_io_r_lookup_ids("", &r_u, rdata, 0);
706
707         DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
708
709 }
710
711 /*******************************************************************
712  api_samr_lookup_ids
713  ********************************************************************/
714 static void api_samr_lookup_ids( uint16 vuid, prs_struct *data, prs_struct *rdata)
715 {
716         SAMR_Q_LOOKUP_IDS q_u;
717
718         /* grab the samr 0x10 */
719         samr_io_q_lookup_ids("", &q_u, data, 0);
720
721         /* construct reply.  always indicate success */
722         samr_reply_lookup_ids(&q_u, rdata);
723 }
724
725 /*******************************************************************
726  samr_reply_lookup_names
727  ********************************************************************/
728 static void samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
729                                 prs_struct *rdata)
730 {
731         uint32 rid[MAX_SAM_ENTRIES];
732         uint32 status     = 0;
733         int i;
734         int num_rids = q_u->num_rids1;
735
736         SAMR_R_LOOKUP_NAMES r_u;
737
738         DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
739
740         if (num_rids > MAX_SAM_ENTRIES)
741         {
742                 num_rids = MAX_SAM_ENTRIES;
743                 DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
744         }
745
746         SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
747
748         for (i = 0; i < num_rids && status == 0; i++)
749         {
750                 fstring name;
751
752                 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
753
754                 fstrcpy(name, unistrn2(q_u->uni_user_name[i].buffer, q_u->uni_user_name[i].uni_str_len));
755
756                 status = (status != 0x0) ? lookup_user_rid (name, &(rid[i])) : status;
757                 status = (status != 0x0) ? lookup_group_rid(name, &(rid[i])) : status;
758                 status = (status != 0x0) ? lookup_alias_rid(name, &(rid[i])) : status;
759         }
760
761         make_samr_r_lookup_names(&r_u, num_rids, rid, status);
762
763         /* store the response in the SMB stream */
764         samr_io_r_lookup_names("", &r_u, rdata, 0);
765
766         DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
767
768 }
769
770 /*******************************************************************
771  api_samr_lookup_names
772  ********************************************************************/
773 static void api_samr_lookup_names( uint16 vuid, prs_struct *data, prs_struct *rdata)
774 {
775         SAMR_Q_LOOKUP_NAMES q_u;
776
777         /* grab the samr lookup names */
778         samr_io_q_lookup_names("", &q_u, data, 0);
779
780         /* construct reply.  always indicate success */
781         samr_reply_lookup_names(&q_u, rdata);
782 }
783
784 /*******************************************************************
785  samr_reply_chgpasswd_user
786  ********************************************************************/
787 static void samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
788                                 prs_struct *rdata)
789 {
790         SAMR_R_CHGPASSWD_USER r_u;
791         uint32 status = 0x0;
792         fstring user_name;
793         fstring wks;
794
795         fstrcpy(user_name, unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len));
796         fstrcpy(wks      , unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len));
797
798         DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
799
800         if (!pass_oem_change(user_name,
801                              q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
802                              q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
803         {
804                 status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
805         }
806
807         make_samr_r_chgpasswd_user(&r_u, status);
808
809         /* store the response in the SMB stream */
810         samr_io_r_chgpasswd_user("", &r_u, rdata, 0);
811
812         DEBUG(5,("samr_chgpasswd_user: %d\n", __LINE__));
813 }
814
815 /*******************************************************************
816  api_samr_chgpasswd_user
817  ********************************************************************/
818 static void api_samr_chgpasswd_user( uint16 vuid, prs_struct *data, prs_struct *rdata)
819 {
820         SAMR_Q_CHGPASSWD_USER q_u;
821
822         /* unknown 38 command */
823         samr_io_q_chgpasswd_user("", &q_u, data, 0);
824
825         /* construct reply. */
826         samr_reply_chgpasswd_user(&q_u, rdata);
827 }
828
829
830 /*******************************************************************
831  samr_reply_unknown_38
832  ********************************************************************/
833 static void samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u,
834                                 prs_struct *rdata)
835 {
836         SAMR_R_UNKNOWN_38 r_u;
837
838         DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
839
840         make_samr_r_unknown_38(&r_u);
841
842         /* store the response in the SMB stream */
843         samr_io_r_unknown_38("", &r_u, rdata, 0);
844
845         DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
846 }
847
848 /*******************************************************************
849  api_samr_unknown_38
850  ********************************************************************/
851 static void api_samr_unknown_38( uint16 vuid, prs_struct *data, prs_struct *rdata)
852 {
853         SAMR_Q_UNKNOWN_38 q_u;
854
855         /* unknown 38 command */
856         samr_io_q_unknown_38("", &q_u, data, 0);
857
858         /* construct reply.  always indicate success */
859         samr_reply_unknown_38(&q_u, rdata);
860 }
861
862
863 /*******************************************************************
864  samr_reply_unknown_12
865  ********************************************************************/
866 static void samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
867                                 prs_struct *rdata)
868 {
869         fstring group_names[MAX_SAM_ENTRIES];
870         uint32  group_attrs[MAX_SAM_ENTRIES];
871         uint32 status     = 0;
872         int num_gids = q_u->num_gids1;
873
874         SAMR_R_UNKNOWN_12 r_u;
875
876         DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
877
878         /* find the policy handle.  open a policy on it. */
879         if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
880         {
881                 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
882         }
883
884         if (status == 0x0)
885         {
886                 int i;
887                 if (num_gids > MAX_SAM_ENTRIES)
888                 {
889                         num_gids = MAX_SAM_ENTRIES;
890                         DEBUG(5,("samr_unknown_12: truncating entries to %d\n", num_gids));
891                 }
892
893                 for (i = 0; i < num_gids && status == 0; i++)
894                 {
895                         fstrcpy(group_names[i], "dummy group");
896                         group_attrs[i] = 0x2;
897                 }
898         }
899
900         make_samr_r_unknown_12(&r_u, num_gids, group_names, group_attrs, status);
901
902         /* store the response in the SMB stream */
903         samr_io_r_unknown_12("", &r_u, rdata, 0);
904
905         DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
906
907 }
908
909 /*******************************************************************
910  api_samr_unknown_12
911  ********************************************************************/
912 static void api_samr_unknown_12( uint16 vuid, prs_struct *data, prs_struct *rdata)
913 {
914         SAMR_Q_UNKNOWN_12 q_u;
915
916         /* grab the samr lookup names */
917         samr_io_q_unknown_12("", &q_u, data, 0);
918
919         /* construct reply.  always indicate success */
920         samr_reply_unknown_12(&q_u, rdata);
921 }
922
923
924 /*******************************************************************
925  samr_reply_open_user
926  ********************************************************************/
927 static void samr_reply_open_user(SAMR_Q_OPEN_USER *q_u,
928                                 prs_struct *rdata,
929                                 int status)
930 {
931         SAMR_R_OPEN_USER r_u;
932         struct sam_passwd *sam_pass;
933         BOOL pol_open = False;
934
935         /* set up the SAMR open_user response */
936         bzero(r_u.user_pol.data, POL_HND_SIZE);
937
938         r_u.status = 0x0;
939
940         /* find the policy handle.  open a policy on it. */
941         if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
942         {
943                 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
944         }
945
946         /* get a (unique) handle.  open a policy on it. */
947         if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.user_pol))))
948         {
949                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
950         }
951
952         become_root(True);
953         sam_pass = getsam21pwrid(q_u->user_rid);
954         unbecome_root(True);
955
956         /* check that the RID exists in our domain. */
957         if (r_u.status == 0x0 && sam_pass == NULL)
958         {
959                 r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
960         }
961
962         /* associate the RID with the (unique) handle. */
963         if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.user_pol), q_u->user_rid))
964         {
965                 /* oh, whoops.  don't know what error message to return, here */
966                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
967         }
968
969         if (r_u.status != 0 && pol_open)
970         {
971                 close_lsa_policy_hnd(&(r_u.user_pol));
972         }
973
974         DEBUG(5,("samr_open_user: %d\n", __LINE__));
975
976         /* store the response in the SMB stream */
977         samr_io_r_open_user("", &r_u, rdata, 0);
978
979         DEBUG(5,("samr_open_user: %d\n", __LINE__));
980
981 }
982
983 /*******************************************************************
984  api_samr_open_user
985  ********************************************************************/
986 static void api_samr_open_user( uint16 vuid, prs_struct *data, prs_struct *rdata)
987 {
988         SAMR_Q_OPEN_USER q_u;
989
990         /* grab the samr unknown 22 */
991         samr_io_q_open_user("", &q_u, data, 0);
992
993         /* construct reply.  always indicate success */
994         samr_reply_open_user(&q_u, rdata, 0x0);
995 }
996
997
998 /*************************************************************************
999  get_user_info_10
1000  *************************************************************************/
1001 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1002 {
1003         struct smb_passwd *smb_pass;
1004
1005         if (!pdb_rid_is_user(user_rid))
1006         {
1007                 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1008                 return False;
1009         }
1010
1011         become_root(True);
1012         smb_pass = getsmbpwrid(user_rid);
1013         unbecome_root(True);
1014
1015         if (smb_pass == NULL)
1016         {
1017                 DEBUG(4,("User 0x%x not found\n", user_rid));
1018                 return False;
1019         }
1020
1021         DEBUG(3,("User:[%s]\n", smb_pass->smb_name));
1022
1023         make_sam_user_info10(id10, smb_pass->acct_ctrl); 
1024
1025         return True;
1026 }
1027
1028 /*************************************************************************
1029  get_user_info_21
1030  *************************************************************************/
1031 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1032 {
1033         NTTIME dummy_time;
1034         struct sam_passwd *sam_pass;
1035         LOGON_HRS hrs;
1036         int i;
1037
1038         if (!pdb_rid_is_user(user_rid))
1039         {
1040                 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1041                 return False;
1042         }
1043
1044         become_root(True);
1045         sam_pass = getsam21pwrid(user_rid);
1046         unbecome_root(True);
1047
1048         if (sam_pass == NULL)
1049         {
1050                 DEBUG(4,("User 0x%x not found\n", user_rid));
1051                 return False;
1052         }
1053
1054         DEBUG(3,("User:[%s]\n", sam_pass->smb_name));
1055
1056         dummy_time.low  = 0xffffffff;
1057         dummy_time.high = 0x7fffffff;
1058
1059         DEBUG(0,("get_user_info_21 - TODO: convert unix times to NTTIMEs\n"));
1060
1061         /* create a LOGON_HRS structure */
1062         hrs.len = sam_pass->hours_len;
1063         SMB_ASSERT_ARRAY(hrs.hours, hrs.len);
1064         for (i = 0; i < hrs.len; i++)
1065         {
1066                 hrs.hours[i] = sam_pass->hours[i];
1067         }
1068
1069         make_sam_user_info21(id21,
1070
1071                            &dummy_time, /* logon_time */
1072                            &dummy_time, /* logoff_time */
1073                            &dummy_time, /* kickoff_time */
1074                            &dummy_time, /* pass_last_set_time */
1075                            &dummy_time, /* pass_can_change_time */
1076                            &dummy_time, /* pass_must_change_time */
1077
1078                            sam_pass->smb_name, /* user_name */
1079                            sam_pass->full_name, /* full_name */
1080                            sam_pass->home_dir, /* home_dir */
1081                            sam_pass->dir_drive, /* dir_drive */
1082                            sam_pass->logon_script, /* logon_script */
1083                            sam_pass->profile_path, /* profile_path */
1084                            sam_pass->acct_desc, /* description */
1085                            sam_pass->workstations, /* workstations user can log in from */
1086                            sam_pass->unknown_str, /* don't know, yet */
1087                            sam_pass->munged_dial, /* dialin info.  contains dialin path and tel no */
1088
1089                            sam_pass->user_rid, /* RID user_id */
1090                            sam_pass->group_rid, /* RID group_id */
1091                        sam_pass->acct_ctrl,
1092
1093                    sam_pass->unknown_3, /* unknown_3 */
1094                        sam_pass->logon_divs, /* divisions per week */
1095                            &hrs, /* logon hours */
1096                        sam_pass->unknown_5,
1097                        sam_pass->unknown_6);
1098
1099         return True;
1100 }
1101
1102 /*******************************************************************
1103  samr_reply_query_userinfo
1104  ********************************************************************/
1105 static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
1106                                 prs_struct *rdata)
1107 {
1108         SAMR_R_QUERY_USERINFO r_u;
1109 #if 0
1110         SAM_USER_INFO_11 id11;
1111 #endif
1112         SAM_USER_INFO_10 id10;
1113         SAM_USER_INFO_21 id21;
1114         void *info = NULL;
1115
1116         uint32 status = 0x0;
1117         uint32 rid = 0x0;
1118
1119         DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1120
1121         /* search for the handle */
1122         if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1123         {
1124                 status = NT_STATUS_INVALID_HANDLE;
1125         }
1126
1127         /* find the user's rid */
1128         if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1129         {
1130                 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1131         }
1132
1133         DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
1134
1135         /* ok!  user info levels (there are lots: see MSDEV help), off we go... */
1136         if (status == 0x0)
1137         {
1138                 switch (q_u->switch_value)
1139                 {
1140                         case 0x10:
1141                         {
1142                                 info = (void*)&id10;
1143                                 status = get_user_info_10(&id10, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1144                                 break;
1145                         }
1146 #if 0
1147 /* whoops - got this wrong.  i think.  or don't understand what's happening. */
1148                         case 0x11:
1149                         {
1150                                 NTTIME expire;
1151                                 info = (void*)&id11;
1152                                 
1153                                 expire.low  = 0xffffffff;
1154                                 expire.high = 0x7fffffff;
1155
1156                                 make_sam_user_info11(&id11, &expire, "BROOKFIELDS$", 0x03ef, 0x201, 0x0080);
1157
1158                                 break;
1159                         }
1160 #endif
1161                         case 21:
1162                         {
1163                                 info = (void*)&id21;
1164                                 status = get_user_info_21(&id21, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1165                                 break;
1166                         }
1167
1168                         default:
1169                         {
1170                                 status = NT_STATUS_INVALID_INFO_CLASS;
1171
1172                                 break;
1173                         }
1174                 }
1175         }
1176
1177         make_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
1178
1179         /* store the response in the SMB stream */
1180         samr_io_r_query_userinfo("", &r_u, rdata, 0);
1181
1182         DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1183
1184 }
1185
1186 /*******************************************************************
1187  api_samr_query_userinfo
1188  ********************************************************************/
1189 static void api_samr_query_userinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
1190 {
1191         SAMR_Q_QUERY_USERINFO q_u;
1192
1193         /* grab the samr unknown 24 */
1194         samr_io_q_query_userinfo("", &q_u, data, 0);
1195
1196         /* construct reply.  always indicate success */
1197         samr_reply_query_userinfo(&q_u, rdata);
1198 }
1199
1200
1201 /*******************************************************************
1202  samr_reply_query_usergroups
1203  ********************************************************************/
1204 static void samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
1205                                 prs_struct *rdata)
1206 {
1207         SAMR_R_QUERY_USERGROUPS r_u;
1208         uint32 status = 0x0;
1209
1210         struct sam_passwd *sam_pass;
1211         DOM_GID *gids = NULL;
1212         int num_groups = 0;
1213         uint32 rid;
1214
1215         DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1216
1217         /* find the policy handle.  open a policy on it. */
1218         if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1219         {
1220                 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1221         }
1222
1223         /* find the user's rid */
1224         if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1225         {
1226                 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1227         }
1228
1229         if (status == 0x0)
1230         {
1231                 become_root(True);
1232                 sam_pass = getsam21pwrid(rid);
1233                 unbecome_root(True);
1234
1235                 if (sam_pass == NULL)
1236                 {
1237                         status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1238                 }
1239         }
1240
1241         if (status == 0x0)
1242         {
1243                 pstring groups;
1244                 get_domain_user_groups(groups, sam_pass->smb_name);
1245                 gids = NULL;
1246                 num_groups = make_dom_gids(groups, &gids);
1247         }
1248
1249         /* construct the response.  lkclXXXX: gids are not copied! */
1250         make_samr_r_query_usergroups(&r_u, num_groups, gids, status);
1251
1252         /* store the response in the SMB stream */
1253         samr_io_r_query_usergroups("", &r_u, rdata, 0);
1254
1255         if (gids)
1256         {
1257                 free((char *)gids);
1258         }
1259
1260         DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1261
1262 }
1263
1264 /*******************************************************************
1265  api_samr_query_usergroups
1266  ********************************************************************/
1267 static void api_samr_query_usergroups( uint16 vuid, prs_struct *data, prs_struct *rdata)
1268 {
1269         SAMR_Q_QUERY_USERGROUPS q_u;
1270         /* grab the samr unknown 32 */
1271         samr_io_q_query_usergroups("", &q_u, data, 0);
1272
1273         /* construct reply. */
1274         samr_reply_query_usergroups(&q_u, rdata);
1275 }
1276
1277
1278 /*******************************************************************
1279  samr_reply_unknown_8
1280  ********************************************************************/
1281 static void samr_reply_unknown_8(SAMR_Q_UNKNOWN_8 *q_u,
1282                                 prs_struct *rdata)
1283 {
1284         SAMR_R_UNKNOWN_8 r_u;
1285         SAM_UNK_CTR ctr;
1286         uint16 switch_value = 0x0;
1287         uint32 status = 0x0;
1288
1289         ZERO_STRUCT(r_u);
1290         ZERO_STRUCT(ctr);
1291
1292         r_u.ctr = &ctr;
1293
1294         DEBUG(5,("samr_reply_unknown_8: %d\n", __LINE__));
1295
1296         /* find the policy handle.  open a policy on it. */
1297         if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
1298         {
1299                 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1300                 DEBUG(5,("samr_reply_unknown_8: invalid handle\n"));
1301         }
1302
1303         if (status == 0x0)
1304         {
1305                 switch (q_u->switch_value)
1306                 {
1307                         case 0x02:
1308                         {
1309                                 switch_value = 0x2;
1310                                 make_unk_info2(&ctr.info.inf2, global_myworkgroup, global_myname);
1311
1312                                 break;
1313                         }
1314                         default:
1315                         {
1316                                 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
1317                                 break;
1318                         }
1319                 }
1320         }
1321
1322         make_samr_r_unknown_8(&r_u, switch_value, &ctr, status);
1323
1324         /* store the response in the SMB stream */
1325         samr_io_r_unknown_8("", &r_u, rdata, 0);
1326
1327         DEBUG(5,("samr_unknown_8: %d\n", __LINE__));
1328
1329 }
1330
1331 /*******************************************************************
1332  api_samr_unknown_8
1333  ********************************************************************/
1334 static void api_samr_unknown_8( uint16 vuid, prs_struct *data, prs_struct *rdata)
1335 {
1336         SAMR_Q_UNKNOWN_8 q_e;
1337
1338         /* grab the samr unknown 8 command */
1339         samr_io_q_unknown_8("", &q_e, data, 0);
1340
1341         /* construct reply. */
1342         samr_reply_unknown_8(&q_e, rdata);
1343 }
1344
1345
1346
1347 /*******************************************************************
1348  samr_reply_unknown_32
1349  ********************************************************************/
1350 static void samr_reply_unknown_32(SAMR_Q_UNKNOWN_32 *q_u,
1351                                 prs_struct *rdata,
1352                                 int status)
1353 {
1354         int i;
1355         SAMR_R_UNKNOWN_32 r_u;
1356
1357         /* set up the SAMR unknown_32 response */
1358         bzero(r_u.pol.data, POL_HND_SIZE);
1359         if (status == 0)
1360         {
1361                 for (i = 4; i < POL_HND_SIZE; i++)
1362                 {
1363                         r_u.pol.data[i] = i+1;
1364                 }
1365         }
1366
1367         make_dom_rid4(&(r_u.rid4), 0x0030, 0, 0);
1368         r_u.status    = status;
1369
1370         DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
1371
1372         /* store the response in the SMB stream */
1373         samr_io_r_unknown_32("", &r_u, rdata, 0);
1374
1375         DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
1376
1377 }
1378
1379 /*******************************************************************
1380  api_samr_unknown_32
1381  ********************************************************************/
1382 static void api_samr_unknown_32( uint16 vuid, prs_struct *data, prs_struct *rdata)
1383 {
1384         uint32 status = 0;
1385         struct sam_passwd *sam_pass;
1386         fstring mach_acct;
1387
1388         SAMR_Q_UNKNOWN_32 q_u;
1389
1390         /* grab the samr unknown 32 */
1391         samr_io_q_unknown_32("", &q_u, data, 0);
1392
1393         /* find the machine account: tell the caller if it exists.
1394            lkclXXXX i have *no* idea if this is a problem or not
1395            or even if you are supposed to construct a different
1396            reply if the account already exists...
1397          */
1398
1399         fstrcpy(mach_acct, unistrn2(q_u.uni_mach_acct.buffer,
1400                                     q_u.uni_mach_acct.uni_str_len));
1401
1402         become_root(True);
1403         sam_pass = getsam21pwnam(mach_acct);
1404         unbecome_root(True);
1405
1406         if (sam_pass != NULL)
1407         {
1408                 /* machine account exists: say so */
1409                 status = 0xC0000000 | NT_STATUS_USER_EXISTS;
1410         }
1411         else
1412         {
1413                 /* this could cause trouble... */
1414                 DEBUG(0,("trouble!\n"));
1415                 status = 0;
1416         }
1417
1418         /* construct reply. */
1419         samr_reply_unknown_32(&q_u, rdata, status);
1420 }
1421
1422
1423 /*******************************************************************
1424  samr_reply_connect_anon
1425  ********************************************************************/
1426 static void samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u,
1427                                 prs_struct *rdata)
1428 {
1429         SAMR_R_CONNECT_ANON r_u;
1430         BOOL pol_open = False;
1431
1432         /* set up the SAMR connect_anon response */
1433
1434         r_u.status = 0x0;
1435         /* get a (unique) handle.  open a policy on it. */
1436         if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1437         {
1438                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1439         }
1440
1441         /* associate the domain SID with the (unique) handle. */
1442         if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1443         {
1444                 /* oh, whoops.  don't know what error message to return, here */
1445                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1446         }
1447
1448         if (r_u.status != 0 && pol_open)
1449         {
1450                 close_lsa_policy_hnd(&(r_u.connect_pol));
1451         }
1452
1453         DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1454
1455         /* store the response in the SMB stream */
1456         samr_io_r_connect_anon("", &r_u, rdata, 0);
1457
1458         DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1459
1460 }
1461
1462 /*******************************************************************
1463  api_samr_connect_anon
1464  ********************************************************************/
1465 static void api_samr_connect_anon( uint16 vuid, prs_struct *data, prs_struct *rdata)
1466 {
1467         SAMR_Q_CONNECT_ANON q_u;
1468
1469         /* grab the samr open policy */
1470         samr_io_q_connect_anon("", &q_u, data, 0);
1471
1472         /* construct reply.  always indicate success */
1473         samr_reply_connect_anon(&q_u, rdata);
1474 }
1475
1476 /*******************************************************************
1477  samr_reply_connect
1478  ********************************************************************/
1479 static void samr_reply_connect(SAMR_Q_CONNECT *q_u,
1480                                 prs_struct *rdata)
1481 {
1482         SAMR_R_CONNECT r_u;
1483         BOOL pol_open = False;
1484
1485         /* set up the SAMR connect response */
1486
1487         r_u.status = 0x0;
1488         /* get a (unique) handle.  open a policy on it. */
1489         if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1490         {
1491                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1492         }
1493
1494         /* associate the domain SID with the (unique) handle. */
1495         if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1496         {
1497                 /* oh, whoops.  don't know what error message to return, here */
1498                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1499         }
1500
1501         if (r_u.status != 0 && pol_open)
1502         {
1503                 close_lsa_policy_hnd(&(r_u.connect_pol));
1504         }
1505
1506         DEBUG(5,("samr_connect: %d\n", __LINE__));
1507
1508         /* store the response in the SMB stream */
1509         samr_io_r_connect("", &r_u, rdata, 0);
1510
1511         DEBUG(5,("samr_connect: %d\n", __LINE__));
1512
1513 }
1514
1515 /*******************************************************************
1516  api_samr_connect
1517  ********************************************************************/
1518 static void api_samr_connect( uint16 vuid, prs_struct *data, prs_struct *rdata)
1519 {
1520         SAMR_Q_CONNECT q_u;
1521
1522         /* grab the samr open policy */
1523         samr_io_q_connect("", &q_u, data, 0);
1524
1525         /* construct reply.  always indicate success */
1526         samr_reply_connect(&q_u, rdata);
1527 }
1528
1529 /*******************************************************************
1530  samr_reply_open_alias
1531  ********************************************************************/
1532 static void samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
1533                                 prs_struct *rdata)
1534 {
1535         SAMR_R_OPEN_ALIAS r_u;
1536         BOOL pol_open = False;
1537
1538         /* set up the SAMR open_alias response */
1539
1540         r_u.status = 0x0;
1541         /* get a (unique) handle.  open a policy on it. */
1542         if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.pol))))
1543         {
1544                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1545         }
1546
1547         /* associate a RID with the (unique) handle. */
1548         if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.pol), q_u->rid_alias))
1549         {
1550                 /* oh, whoops.  don't know what error message to return, here */
1551                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1552         }
1553
1554         if (r_u.status != 0 && pol_open)
1555         {
1556                 close_lsa_policy_hnd(&(r_u.pol));
1557         }
1558
1559         DEBUG(5,("samr_open_alias: %d\n", __LINE__));
1560
1561         /* store the response in the SMB stream */
1562         samr_io_r_open_alias("", &r_u, rdata, 0);
1563
1564         DEBUG(5,("samr_open_alias: %d\n", __LINE__));
1565
1566 }
1567
1568 /*******************************************************************
1569  api_samr_open_alias
1570  ********************************************************************/
1571 static void api_samr_open_alias( uint16 vuid, prs_struct *data, prs_struct *rdata)
1572                                 
1573 {
1574         SAMR_Q_OPEN_ALIAS q_u;
1575
1576         /* grab the samr open policy */
1577         samr_io_q_open_alias("", &q_u, data, 0);
1578
1579         /* construct reply.  always indicate success */
1580         samr_reply_open_alias(&q_u, rdata);
1581 }
1582
1583 /*******************************************************************
1584  array of \PIPE\samr operations
1585  ********************************************************************/
1586 static struct api_struct api_samr_cmds [] =
1587 {
1588         { "SAMR_CLOSE_HND"        , SAMR_CLOSE_HND        , api_samr_close_hnd        },
1589         { "SAMR_CONNECT"          , SAMR_CONNECT          , api_samr_connect          },
1590         { "SAMR_CONNECT_ANON"     , SAMR_CONNECT_ANON     , api_samr_connect_anon     },
1591         { "SAMR_ENUM_DOM_USERS"   , SAMR_ENUM_DOM_USERS   , api_samr_enum_dom_users   },
1592         { "SAMR_ENUM_DOM_GROUPS"  , SAMR_ENUM_DOM_GROUPS  , api_samr_enum_dom_groups  },
1593         { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
1594         { "SAMR_LOOKUP_IDS"       , SAMR_LOOKUP_IDS       , api_samr_lookup_ids       },
1595         { "SAMR_LOOKUP_NAMES"     , SAMR_LOOKUP_NAMES     , api_samr_lookup_names     },
1596         { "SAMR_OPEN_USER"        , SAMR_OPEN_USER        , api_samr_open_user        },
1597         { "SAMR_QUERY_USERINFO"   , SAMR_QUERY_USERINFO   , api_samr_query_userinfo   },
1598         { "SAMR_UNKNOWN_8"        , SAMR_UNKNOWN_8        , api_samr_unknown_8        },
1599         { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
1600         { "SAMR_QUERY_DISPINFO"   , SAMR_QUERY_DISPINFO   , api_samr_query_dispinfo   },
1601         { "SAMR_QUERY_ALIASINFO"  , SAMR_QUERY_ALIASINFO  , api_samr_query_aliasinfo  },
1602         { "SAMR_0x32"             , 0x32                  , api_samr_unknown_32       },
1603         { "SAMR_UNKNOWN_12"       , SAMR_UNKNOWN_12       , api_samr_unknown_12       },
1604         { "SAMR_UNKNOWN_38"       , SAMR_UNKNOWN_38       , api_samr_unknown_38       },
1605         { "SAMR_CHGPASSWD_USER"   , SAMR_CHGPASSWD_USER   , api_samr_chgpasswd_user   },
1606         { "SAMR_OPEN_ALIAS"       , SAMR_OPEN_ALIAS       , api_samr_open_alias       },
1607         { "SAMR_OPEN_DOMAIN"      , SAMR_OPEN_DOMAIN      , api_samr_open_domain      },
1608         { "SAMR_UNKNOWN_3"        , SAMR_UNKNOWN_3        , api_samr_unknown_3        },
1609         { "SAMR_UNKNOWN_2C"       , SAMR_UNKNOWN_2C       , api_samr_unknown_2c       },
1610         { NULL                    , 0                     , NULL                      }
1611 };
1612
1613 /*******************************************************************
1614  receives a samr pipe and responds.
1615  ********************************************************************/
1616 BOOL api_samr_rpc(pipes_struct *p, prs_struct *data)
1617 {
1618     return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds, data);
1619 }
1620