This is a security audit change of the main source.
[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 rid_name domain_group_rids[];
34 extern rid_name domain_alias_rids[];
35
36 /*******************************************************************
37   This next function should be replaced with something that
38   dynamically returns the correct user info..... JRA.
39  ********************************************************************/
40
41 static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf,
42                                 int *total_entries, int *num_entries,
43                                 int max_num_entries,
44                                 uint16 acb_mask)
45 {
46         void *vp = NULL;
47         struct smb_passwd *pwd = NULL;
48
49         (*num_entries) = 0;
50         (*total_entries) = 0;
51
52         if (pw_buf == NULL) return False;
53
54         vp = startsampwent(False);
55         if (!vp)
56         {
57                 DEBUG(0, ("get_sampwd_entries: Unable to open SMB password file.\n"));
58                 return False;
59         }
60
61         while (((pwd = getsampwent(vp)) != NULL) && (*num_entries) < max_num_entries)
62         {
63                 int user_name_len = strlen(pwd->smb_name);
64                 make_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->smb_name, user_name_len-1);
65                 make_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len-1, 
66                                user_name_len-1, 1);
67                 pw_buf[(*num_entries)].user_rid = pwd->smb_userid;
68                 bzero( pw_buf[(*num_entries)].nt_pwd , 16);
69
70                 /* Now check if the NT compatible password is available. */
71                 if (pwd->smb_nt_passwd != NULL)
72                 {
73                         memcpy( pw_buf[(*num_entries)].nt_pwd , pwd->smb_nt_passwd, 16);
74                 }
75
76                 pw_buf[(*num_entries)].acb_info = (uint16)pwd->acct_ctrl;
77
78                 DEBUG(5, ("get_sampwd_entries: idx: %d user %s, uid %d, acb %x",
79                 (*num_entries), pwd->smb_name, pwd->smb_userid, pwd->acct_ctrl));
80
81                 if (acb_mask == 0 || IS_BITS_SET_SOME(pwd->acct_ctrl, acb_mask))
82                 {
83                         DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
84                         (*num_entries)++;
85                 }
86                 else
87                 {
88                         DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
89                 }
90
91                 (*total_entries)++;
92         }
93
94         endsampwent(vp);
95
96         return (*num_entries) > 0;
97 }
98
99 /*******************************************************************
100  samr_reply_unknown_1
101  ********************************************************************/
102 static void samr_reply_close_hnd(SAMR_Q_CLOSE_HND *q_u,
103                                 prs_struct *rdata)
104 {
105         SAMR_R_CLOSE_HND r_u;
106
107         /* set up the SAMR unknown_1 response */
108         bzero(&(r_u.pol.data), POL_HND_SIZE);
109
110         /* close the policy handle */
111         if (close_lsa_policy_hnd(&(q_u->pol)))
112         {
113                 r_u.status = 0;
114         }
115         else
116         {
117                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_INVALID;
118         }
119
120         DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
121
122         /* store the response in the SMB stream */
123         samr_io_r_close_hnd("", &r_u, rdata, 0);
124
125         DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
126
127 }
128
129 /*******************************************************************
130  api_samr_close_hnd
131  ********************************************************************/
132 static void api_samr_close_hnd( int uid, prs_struct *data, prs_struct *rdata)
133 {
134         SAMR_Q_CLOSE_HND q_u;
135
136         /* grab the samr unknown 1 */
137         samr_io_q_close_hnd("", &q_u, data, 0);
138
139         /* construct reply.  always indicate success */
140         samr_reply_close_hnd(&q_u, rdata);
141 }
142
143
144 /*******************************************************************
145  samr_reply_open_domain
146  ********************************************************************/
147 static void samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
148                                 prs_struct *rdata)
149 {
150         SAMR_R_OPEN_DOMAIN r_u;
151         BOOL pol_open = False;
152         int pol_idx;
153
154         r_u.status = 0x0;
155
156         /* find the connection policy handle. */
157         if (r_u.status == 0x0 && ((pol_idx = find_lsa_policy_by_hnd(&(q_u->connect_pol))) == -1))
158         {
159                 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
160         }
161
162         /* get a (unique) handle.  open a policy on it. */
163         if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.domain_pol))))
164         {
165                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
166         }
167
168         /* associate the domain SID with the (unique) handle. */
169         if (r_u.status == 0x0 && !set_lsa_policy_samr_sid(&(r_u.domain_pol), &(q_u->dom_sid.sid)))
170         {
171                 /* oh, whoops.  don't know what error message to return, here */
172                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
173         }
174
175         if (r_u.status != 0 && pol_open)
176         {
177                 close_lsa_policy_hnd(&(r_u.domain_pol));
178         }
179
180         DEBUG(5,("samr_open_domain: %d\n", __LINE__));
181
182         /* store the response in the SMB stream */
183         samr_io_r_open_domain("", &r_u, rdata, 0);
184
185         DEBUG(5,("samr_open_domain: %d\n", __LINE__));
186
187 }
188
189 /*******************************************************************
190  api_samr_open_domain
191  ********************************************************************/
192 static void api_samr_open_domain( int uid, prs_struct *data, prs_struct *rdata)
193 {
194         SAMR_Q_OPEN_DOMAIN q_u;
195
196         /* grab the samr open */
197         samr_io_q_open_domain("", &q_u, data, 0);
198
199         /* construct reply.  always indicate success */
200         samr_reply_open_domain(&q_u, rdata);
201 }
202
203
204 /*******************************************************************
205  samr_reply_unknown_3
206  ********************************************************************/
207 static void samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
208                                 prs_struct *rdata)
209 {
210         SAMR_R_UNKNOWN_3 r_u;
211         DOM_SID3 sid[MAX_SAM_SIDS];
212         fstring user_sid;
213         fstring user_rid;
214         int pol_idx;
215         uint32 rid;
216         uint32 status;
217
218         status = 0x0;
219
220         /* find the policy handle.  open a policy on it. */
221         if (status == 0x0 && ((pol_idx = find_lsa_policy_by_hnd(&(q_u->user_pol))) == -1))
222         {
223                 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
224         }
225
226         /* find the user's rid */
227         if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->user_pol))) == 0xffffffff)
228         {
229                 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
230         }
231
232         if (status == 0x0)
233         {
234                 fstrcpy(user_sid, lp_domain_sid());
235                 slprintf(user_rid, sizeof(user_rid) - 1, "-%x", rid);
236                 fstrcat(user_sid, user_rid);
237
238                 /* maybe need another 1 or 2 (S-1-5-20-0x220 and S-1-5-20-0x224) */
239                 /* these two are DOMAIN_ADMIN and DOMAIN_ACCT_OP group RIDs */
240                 make_dom_sid3(&(sid[0]), 0x035b, 0x0002, "S-1-1");
241                 make_dom_sid3(&(sid[1]), 0x0044, 0x0002, user_sid);
242         }
243
244         make_samr_r_unknown_3(&r_u,
245                                 0x0001, 0x8004,
246                                 0x00000014, 0x0002, 0x0070,
247                                 2, sid, status);
248
249         DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
250
251         /* store the response in the SMB stream */
252         samr_io_r_unknown_3("", &r_u, rdata, 0);
253
254         DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
255
256 }
257
258 /*******************************************************************
259  api_samr_unknown_3
260  ********************************************************************/
261 static void api_samr_unknown_3( int uid, prs_struct *data, prs_struct *rdata)
262 {
263         SAMR_Q_UNKNOWN_3 q_u;
264
265         /* grab the samr open */
266         samr_io_q_unknown_3("", &q_u, data, 0);
267
268         /* construct reply.  always indicate success */
269         samr_reply_unknown_3(&q_u, rdata);
270 }
271
272
273 /*******************************************************************
274  samr_reply_enum_dom_users
275  ********************************************************************/
276 static void samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
277                                 prs_struct *rdata)
278 {
279         SAMR_R_ENUM_DOM_USERS r_e;
280         SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
281         int num_entries;
282         int total_entries;
283         int pol_idx;
284         BOOL got_pwds;
285
286         r_e.status = 0x0;
287         r_e.total_num_entries = 0;
288
289         /* find the policy handle.  open a policy on it. */
290         if (r_e.status == 0x0 && ((pol_idx = find_lsa_policy_by_hnd(&(q_u->pol))) == -1))
291         {
292                 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
293         }
294
295         DEBUG(5,("samr_reply_enum_dom_users: %d\n", __LINE__));
296
297         become_root(True);
298         got_pwds = get_sampwd_entries(pass, &total_entries, &num_entries, MAX_SAM_ENTRIES, q_u->acb_mask);
299         unbecome_root(True);
300
301         make_samr_r_enum_dom_users(&r_e, total_entries,
302                                    q_u->unknown_0, num_entries,
303                                    pass, r_e.status);
304
305         /* store the response in the SMB stream */
306         samr_io_r_enum_dom_users("", &r_e, rdata, 0);
307
308         DEBUG(5,("samr_enum_dom_users: %d\n", __LINE__));
309
310 }
311
312 /*******************************************************************
313  api_samr_enum_dom_users
314  ********************************************************************/
315 static void api_samr_enum_dom_users( int uid, prs_struct *data, prs_struct *rdata)
316 {
317         SAMR_Q_ENUM_DOM_USERS q_e;
318
319         /* grab the samr open */
320         samr_io_q_enum_dom_users("", &q_e, data, 0);
321
322         /* construct reply. */
323         samr_reply_enum_dom_users(&q_e, rdata);
324 }
325
326
327 /*******************************************************************
328  samr_reply_enum_dom_groups
329  ********************************************************************/
330 static void samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u,
331                                 prs_struct *rdata)
332 {
333         SAMR_R_ENUM_DOM_GROUPS r_e;
334         SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
335         int num_entries;
336         int pol_idx;
337         BOOL got_grps;
338         char *dummy_group = "Domain Admins";
339
340         r_e.status = 0x0;
341         r_e.num_entries = 0;
342
343         /* find the policy handle.  open a policy on it. */
344         if (r_e.status == 0x0 && ((pol_idx = find_lsa_policy_by_hnd(&(q_u->pol))) == -1))
345         {
346                 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
347         }
348
349         DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
350
351         got_grps = True;
352         num_entries = 1;
353         make_unistr2(&(pass[0].uni_user_name), dummy_group, strlen(dummy_group));
354         pass[0].user_rid = DOMAIN_GROUP_RID_ADMINS;
355
356         if (r_e.status == 0 && got_grps)
357         {
358                 make_samr_r_enum_dom_groups(&r_e, q_u->start_idx, num_entries, pass, r_e.status);
359         }
360
361         /* store the response in the SMB stream */
362         samr_io_r_enum_dom_groups("", &r_e, rdata, 0);
363
364         DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
365
366 }
367
368 /*******************************************************************
369  api_samr_enum_dom_groups
370  ********************************************************************/
371 static void api_samr_enum_dom_groups( int uid, prs_struct *data, prs_struct *rdata)
372 {
373         SAMR_Q_ENUM_DOM_GROUPS q_e;
374
375         /* grab the samr open */
376         samr_io_q_enum_dom_groups("", &q_e, data, 0);
377
378         /* construct reply. */
379         samr_reply_enum_dom_groups(&q_e, rdata);
380 }
381
382
383 /*******************************************************************
384  samr_reply_enum_dom_aliases
385  ********************************************************************/
386 static void samr_reply_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_u,
387                                 prs_struct *rdata)
388 {
389         SAMR_R_ENUM_DOM_ALIASES r_e;
390         SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
391         int num_entries;
392         int pol_idx;
393         BOOL got_aliases;
394         char *dummy_alias = "admins";
395
396         r_e.status = 0x0;
397         r_e.num_entries = 0;
398
399         /* find the policy handle.  open a policy on it. */
400         if (r_e.status == 0x0 && ((pol_idx = find_lsa_policy_by_hnd(&(q_u->pol))) == -1))
401         {
402                 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
403         }
404
405         DEBUG(5,("samr_reply_enum_dom_aliases: %d\n", __LINE__));
406
407         got_aliases = True;
408         num_entries = 1;
409         make_unistr2(&(pass[0].uni_user_name), dummy_alias, strlen(dummy_alias));
410         pass[0].user_rid = DOMAIN_ALIAS_RID_ADMINS;
411
412         if (r_e.status == 0 && got_aliases)
413         {
414                 make_samr_r_enum_dom_aliases(&r_e, num_entries, pass, r_e.status);
415         }
416
417         /* store the response in the SMB stream */
418         samr_io_r_enum_dom_aliases("", &r_e, rdata, 0);
419
420         DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
421
422 }
423
424 /*******************************************************************
425  api_samr_enum_dom_aliases
426  ********************************************************************/
427 static void api_samr_enum_dom_aliases( int uid, prs_struct *data, prs_struct *rdata)
428 {
429         SAMR_Q_ENUM_DOM_ALIASES q_e;
430
431         /* grab the samr open */
432         samr_io_q_enum_dom_aliases("", &q_e, data, 0);
433
434         /* construct reply. */
435         samr_reply_enum_dom_aliases(&q_e, rdata);
436 }
437
438
439 /*******************************************************************
440  samr_reply_query_dispinfo
441  ********************************************************************/
442 static void samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u,
443                                 prs_struct *rdata)
444 {
445         SAMR_R_QUERY_DISPINFO r_e;
446         SAM_INFO_CTR ctr;
447         SAM_INFO_1 info1;
448         SAM_INFO_2 info2;
449         SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
450         int num_entries;
451         int total_entries;
452         int pol_idx;
453         BOOL got_pwds;
454         uint16 switch_level = 0x0;
455
456         r_e.status = 0x0;
457
458         /* find the policy handle.  open a policy on it. */
459         if (r_e.status == 0x0 && ((pol_idx = find_lsa_policy_by_hnd(&(q_u->pol))) == -1))
460         {
461                 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
462         }
463
464         DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
465
466         become_root(True);
467         got_pwds = get_sampwd_entries(pass, &total_entries, &num_entries, MAX_SAM_ENTRIES, 0);
468         unbecome_root(True);
469
470         switch (q_u->switch_level)
471         {
472                 case 0x1:
473                 {
474                 
475                         /* query disp info is for users */
476                         switch_level = 0x1;
477                         make_sam_info_1(&info1, ACB_NORMAL,
478                                 q_u->start_idx, num_entries, pass);
479
480                         ctr.sam.info1 = &info1;
481
482                         break;
483                 }
484                 case 0x2:
485                 {
486                         /* query disp info is for servers */
487                         switch_level = 0x2;
488                         make_sam_info_2(&info2, ACB_WSTRUST,
489                                 q_u->start_idx, num_entries, pass);
490
491                         ctr.sam.info2 = &info2;
492
493                         break;
494                 }
495         }
496
497         if (r_e.status == 0 && got_pwds)
498         {
499                 make_samr_r_query_dispinfo(&r_e, switch_level, &ctr, r_e.status);
500         }
501
502         /* store the response in the SMB stream */
503         samr_io_r_query_dispinfo("", &r_e, rdata, 0);
504
505         DEBUG(5,("samr_query_dispinfo: %d\n", __LINE__));
506
507 }
508
509 /*******************************************************************
510  api_samr_query_dispinfo
511  ********************************************************************/
512 static void api_samr_query_dispinfo( int uid, prs_struct *data, prs_struct *rdata)
513 {
514         SAMR_Q_QUERY_DISPINFO q_e;
515
516         /* grab the samr open */
517         samr_io_q_query_dispinfo("", &q_e, data, 0);
518
519         /* construct reply. */
520         samr_reply_query_dispinfo(&q_e, rdata);
521 }
522
523
524 /*******************************************************************
525  samr_reply_query_aliasinfo
526  ********************************************************************/
527 static void samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
528                                 prs_struct *rdata)
529 {
530         SAMR_R_QUERY_ALIASINFO r_e;
531         int pol_idx;
532         BOOL got_alias;
533
534         r_e.status = 0x0;
535         r_e.ptr = 0;
536
537         /* find the policy handle.  open a policy on it. */
538         if (r_e.status == 0x0 && ((pol_idx = find_lsa_policy_by_hnd(&(q_u->pol))) == -1))
539         {
540                 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
541         }
542
543         DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__));
544
545         if (r_e.status == 0x0)
546         {
547                 if (q_u->switch_level != 3)
548                 {
549                         r_e.status = NT_STATUS_INVALID_INFO_CLASS;
550                 }
551         }
552
553         if (r_e.status == 0x0)
554         {
555                 got_alias = True;
556         }
557
558         make_samr_r_query_aliasinfo(&r_e, q_u->switch_level,
559                             "<account description>",
560                                 r_e.status);
561
562         /* store the response in the SMB stream */
563         samr_io_r_query_aliasinfo("", &r_e, rdata, 0);
564
565         DEBUG(5,("samr_query_aliasinfo: %d\n", __LINE__));
566
567 }
568
569 /*******************************************************************
570  api_samr_query_aliasinfo
571  ********************************************************************/
572 static void api_samr_query_aliasinfo( int uid, prs_struct *data, prs_struct *rdata)
573 {
574         SAMR_Q_QUERY_ALIASINFO q_e;
575
576         /* grab the samr open */
577         samr_io_q_query_aliasinfo("", &q_e, data, 0);
578
579         /* construct reply. */
580         samr_reply_query_aliasinfo(&q_e, rdata);
581 }
582
583
584 /*******************************************************************
585  samr_reply_lookup_ids
586  ********************************************************************/
587 static void samr_reply_lookup_ids(SAMR_Q_LOOKUP_IDS *q_u,
588                                 prs_struct *rdata)
589 {
590         uint32 rid[MAX_SAM_ENTRIES];
591         uint32 status     = 0;
592         int num_rids = q_u->num_sids1;
593
594         SAMR_R_LOOKUP_IDS r_u;
595
596         DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
597
598         if (num_rids > MAX_SAM_ENTRIES)
599         {
600                 num_rids = MAX_SAM_ENTRIES;
601                 DEBUG(5,("samr_lookup_ids: truncating entries to %d\n", num_rids));
602         }
603
604 #if 0
605         int i;
606         for (i = 0; i < num_rids && status == 0; i++)
607         {
608                 struct smb_passwd *smb_pass;
609                 fstring user_name;
610
611                 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
612                                                                         q_u->uni_user_name[i].uni_str_len));
613
614                 /* find the user account */
615                 become_root(True);
616                 smb_pass = get_sampwd_entry(user_name, 0);
617                 unbecome_root(True);
618
619                 if (smb_pass == NULL)
620                 {
621                         status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
622                         rid[i] = 0;
623                 }
624                 else
625                 {
626                         /* lkclXXXX SHOULD use name_to_rid() here! */
627                         rid[i] = smb_pass->smb_userid;
628                 }
629         }
630 #endif
631
632         num_rids = 1;
633         rid[0] = DOMAIN_ALIAS_RID_USERS;
634
635         make_samr_r_lookup_ids(&r_u, num_rids, rid, status);
636
637         /* store the response in the SMB stream */
638         samr_io_r_lookup_ids("", &r_u, rdata, 0);
639
640         DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
641
642 }
643
644 /*******************************************************************
645  api_samr_lookup_ids
646  ********************************************************************/
647 static void api_samr_lookup_ids( int uid, prs_struct *data, prs_struct *rdata)
648 {
649         SAMR_Q_LOOKUP_IDS q_u;
650
651         /* grab the samr 0x10 */
652         samr_io_q_lookup_ids("", &q_u, data, 0);
653
654         /* construct reply.  always indicate success */
655         samr_reply_lookup_ids(&q_u, rdata);
656 }
657
658 /*******************************************************************
659  samr_reply_lookup_names
660  ********************************************************************/
661 static void samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
662                                 prs_struct *rdata)
663 {
664         uint32 rid[MAX_SAM_ENTRIES];
665         uint32 status     = 0;
666         int i;
667         int num_rids = q_u->num_rids1;
668
669         SAMR_R_LOOKUP_NAMES r_u;
670
671         DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
672
673         if (num_rids > MAX_SAM_ENTRIES)
674         {
675                 num_rids = MAX_SAM_ENTRIES;
676                 DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
677         }
678
679         for (i = 0; i < num_rids && status == 0; i++)
680         {
681                 fstring name;
682
683                 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
684
685                 fstrcpy(name, unistrn2(q_u->uni_user_name[i].buffer, q_u->uni_user_name[i].uni_str_len));
686
687                 status = (status != 0x0) ? lookup_user_rid (name, &(rid[i])) : status;
688                 status = (status != 0x0) ? lookup_group_rid(name, &(rid[i])) : status;
689                 status = (status != 0x0) ? lookup_alias_rid(name, &(rid[i])) : status;
690         }
691
692         make_samr_r_lookup_names(&r_u, num_rids, rid, status);
693
694         /* store the response in the SMB stream */
695         samr_io_r_lookup_names("", &r_u, rdata, 0);
696
697         DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
698
699 }
700
701 /*******************************************************************
702  api_samr_lookup_names
703  ********************************************************************/
704 static void api_samr_lookup_names( int uid, prs_struct *data, prs_struct *rdata)
705 {
706         SAMR_Q_LOOKUP_NAMES q_u;
707
708         /* grab the samr lookup names */
709         samr_io_q_lookup_names("", &q_u, data, 0);
710
711         /* construct reply.  always indicate success */
712         samr_reply_lookup_names(&q_u, rdata);
713 }
714
715
716 /*******************************************************************
717  samr_reply_unknown_12
718  ********************************************************************/
719 static void samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
720                                 prs_struct *rdata)
721 {
722         fstring group_names[MAX_SAM_ENTRIES];
723         uint32  group_attrs[MAX_SAM_ENTRIES];
724         uint32 status     = 0;
725         int num_gids = q_u->num_gids1;
726         uint32 pol_idx;
727
728         SAMR_R_UNKNOWN_12 r_u;
729
730         DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
731
732         /* find the policy handle.  open a policy on it. */
733         if (status == 0x0 && ((pol_idx = find_lsa_policy_by_hnd(&(q_u->pol))) == -1))
734         {
735                 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
736         }
737
738         if (status == 0x0)
739         {
740                 int i;
741                 if (num_gids > MAX_SAM_ENTRIES)
742                 {
743                         num_gids = MAX_SAM_ENTRIES;
744                         DEBUG(5,("samr_unknown_12: truncating entries to %d\n", num_gids));
745                 }
746
747                 for (i = 0; i < num_gids && status == 0; i++)
748                 {
749                         fstrcpy(group_names[i], "dummy group");
750                         group_attrs[i] = 0x2;
751                 }
752         }
753
754         make_samr_r_unknown_12(&r_u, num_gids, group_names, group_attrs, status);
755
756         /* store the response in the SMB stream */
757         samr_io_r_unknown_12("", &r_u, rdata, 0);
758
759         DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
760
761 }
762
763 /*******************************************************************
764  api_samr_unknown_12
765  ********************************************************************/
766 static void api_samr_unknown_12( int uid, prs_struct *data, prs_struct *rdata)
767 {
768         SAMR_Q_UNKNOWN_12 q_u;
769
770         /* grab the samr lookup names */
771         samr_io_q_unknown_12("", &q_u, data, 0);
772
773         /* construct reply.  always indicate success */
774         samr_reply_unknown_12(&q_u, rdata);
775 }
776
777
778 /*******************************************************************
779  samr_reply_open_user
780  ********************************************************************/
781 static void samr_reply_open_user(SAMR_Q_OPEN_USER *q_u,
782                                 prs_struct *rdata,
783                                 int status)
784 {
785         SAMR_R_OPEN_USER r_u;
786         struct smb_passwd *smb_pass;
787         int pol_idx;
788         BOOL pol_open = False;
789
790         /* set up the SAMR open_user response */
791         bzero(&(r_u.user_pol.data), POL_HND_SIZE);
792
793         r_u.status = 0x0;
794
795         /* find the policy handle.  open a policy on it. */
796         if (r_u.status == 0x0 && ((pol_idx = find_lsa_policy_by_hnd(&(q_u->domain_pol))) == -1))
797         {
798                 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
799         }
800
801         /* get a (unique) handle.  open a policy on it. */
802         if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.user_pol))))
803         {
804                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
805         }
806
807         become_root(True);
808         smb_pass = getsampwuid(q_u->user_rid);
809         unbecome_root(True);
810
811         /* check that the RID exists in our domain. */
812         if (r_u.status == 0x0 && smb_pass == NULL)
813         {
814                 r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
815         }
816
817         /* associate the RID with the (unique) handle. */
818         if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.user_pol), q_u->user_rid))
819         {
820                 /* oh, whoops.  don't know what error message to return, here */
821                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
822         }
823
824         if (r_u.status != 0 && pol_open)
825         {
826                 close_lsa_policy_hnd(&(r_u.user_pol));
827         }
828
829         DEBUG(5,("samr_open_user: %d\n", __LINE__));
830
831         /* store the response in the SMB stream */
832         samr_io_r_open_user("", &r_u, rdata, 0);
833
834         DEBUG(5,("samr_open_user: %d\n", __LINE__));
835
836 }
837
838 /*******************************************************************
839  api_samr_open_user
840  ********************************************************************/
841 static void api_samr_open_user( int uid, prs_struct *data, prs_struct *rdata)
842 {
843         SAMR_Q_OPEN_USER q_u;
844
845         /* grab the samr unknown 22 */
846         samr_io_q_open_user("", &q_u, data, 0);
847
848         /* construct reply.  always indicate success */
849         samr_reply_open_user(&q_u, rdata, 0x0);
850 }
851
852
853 /*************************************************************************
854  get_user_info_21
855  *************************************************************************/
856 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 rid)
857 {
858         NTTIME dummy_time;
859         struct sam_passwd *sam_pass;
860
861         LOGON_HRS hrs;
862         int i;
863
864         become_root(True);
865         sam_pass = getsam21pwrid(rid);
866         unbecome_root(True);
867
868         if (sam_pass == NULL)
869         {
870                 return False;
871         }
872
873         DEBUG(3,("User:[%s]\n", sam_pass->smb_name));
874
875         dummy_time.low  = 0xffffffff;
876         dummy_time.high = 0x7fffffff;
877
878         DEBUG(0,("get_user_info_21 - TODO: convert unix times to NTTIMEs\n"));
879
880         /* create a LOGON_HRS structure */
881         hrs.len = sam_pass->hours_len;
882         for (i = 0; i < hrs.len; i++)
883         {
884                 hrs.hours[i] = sam_pass->hours[i];
885         }
886
887         make_sam_user_info21(id21,
888
889                            &dummy_time, /* logon_time */
890                            &dummy_time, /* logoff_time */
891                            &dummy_time, /* kickoff_time */
892                            &dummy_time, /* pass_last_set_time */
893                            &dummy_time, /* pass_can_change_time */
894                            &dummy_time, /* pass_must_change_time */
895
896                            sam_pass->smb_name, /* user_name */
897                            sam_pass->full_name, /* full_name */
898                            sam_pass->home_dir, /* home_dir */
899                            sam_pass->dir_drive, /* dir_drive */
900                            sam_pass->logon_script, /* logon_script */
901                            sam_pass->profile_path, /* profile_path */
902                            sam_pass->acct_desc, /* description */
903                            sam_pass->workstations, /* workstations user can log in from */
904                            sam_pass->unknown_str, /* don't know, yet */
905                            sam_pass->munged_dial, /* dialin info.  contains dialin path and tel no */
906
907                            sam_pass->user_rid, /* RID user_id */
908                            sam_pass->group_rid, /* RID group_id */
909                        sam_pass->acct_ctrl,
910
911                    sam_pass->unknown_3, /* unknown_3 */
912                        sam_pass->logon_divs, /* divisions per week */
913                            &hrs, /* logon hours */
914                        sam_pass->unknown_5,
915                        sam_pass->unknown_6);
916
917         return True;
918 }
919
920 /*******************************************************************
921  samr_reply_query_userinfo
922  ********************************************************************/
923 static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
924                                 prs_struct *rdata)
925 {
926         SAMR_R_QUERY_USERINFO r_u;
927 #if 0
928         SAM_USER_INFO_11 id11;
929 #endif
930         SAM_USER_INFO_21 id21;
931         void *info = NULL;
932
933         uint32 status = 0x0;
934         uint32 rid;
935         int obj_idx;
936
937         DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
938
939         /* search for the handle */
940         if (status == 0x0 && (obj_idx = find_lsa_policy_by_hnd(&(q_u->pol))) == -1)
941         {
942                 status = NT_STATUS_INVALID_HANDLE;
943         }
944
945         /* find the user's rid */
946         if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
947         {
948                 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
949         }
950
951         /* ok!  user info levels (there are lots: see MSDEV help), off we go... */
952         if (status == 0x0)
953         {
954                 switch (q_u->switch_value)
955                 {
956 #if 0
957 /* whoops - got this wrong.  i think.  or don't understand what's happening. */
958                         case 0x11:
959                         {
960                                 NTTIME expire;
961                                 info = (void*)&id11;
962                                 
963                                 expire.low  = 0xffffffff;
964                                 expire.high = 0x7fffffff;
965
966                                 make_sam_user_info11(&id11, &expire, "BROOKFIELDS$", 0x03ef, 0x201, 0x0080);
967
968                                 break;
969                         }
970 #endif
971                         case 21:
972                         {
973                                 info = (void*)&id21;
974                                 status = get_user_info_21(&id21, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
975                                 break;
976                         }
977
978                         default:
979                         {
980                                 status = NT_STATUS_INVALID_INFO_CLASS;
981
982                                 break;
983                         }
984                 }
985         }
986
987         make_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
988
989         /* store the response in the SMB stream */
990         samr_io_r_query_userinfo("", &r_u, rdata, 0);
991
992         DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
993
994 }
995
996 /*******************************************************************
997  api_samr_query_userinfo
998  ********************************************************************/
999 static void api_samr_query_userinfo( int uid, prs_struct *data, prs_struct *rdata)
1000 {
1001         SAMR_Q_QUERY_USERINFO q_u;
1002
1003         /* grab the samr unknown 24 */
1004         samr_io_q_query_userinfo("", &q_u, data, 0);
1005
1006         /* construct reply.  always indicate success */
1007         samr_reply_query_userinfo(&q_u, rdata);
1008 }
1009
1010
1011 /*******************************************************************
1012  samr_reply_query_usergroups
1013  ********************************************************************/
1014 static void samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
1015                                 prs_struct *rdata)
1016 {
1017         SAMR_R_QUERY_USERGROUPS r_u;
1018         uint32 status = 0x0;
1019
1020         struct smb_passwd *smb_pass;
1021         DOM_GID gids[LSA_MAX_GROUPS];
1022         int num_groups = 0;
1023         int pol_idx;
1024         uint32 rid;
1025
1026         DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1027
1028         /* find the policy handle.  open a policy on it. */
1029         if (status == 0x0 && ((pol_idx = find_lsa_policy_by_hnd(&(q_u->pol))) == -1))
1030         {
1031                 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1032         }
1033
1034         /* find the user's rid */
1035         if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1036         {
1037                 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1038         }
1039
1040         if (status == 0x0)
1041         {
1042                 become_root(True);
1043                 smb_pass = getsampwuid(rid);
1044                 unbecome_root(True);
1045
1046                 if (smb_pass == NULL)
1047                 {
1048                         status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1049                 }
1050         }
1051
1052         if (status == 0x0)
1053         {
1054                 pstring groups;
1055                 get_domain_user_groups(groups, smb_pass->smb_name);
1056                 num_groups = make_dom_gids(groups, gids);
1057         }
1058
1059         /* construct the response.  lkclXXXX: gids are not copied! */
1060         make_samr_r_query_usergroups(&r_u, num_groups, gids, status);
1061
1062         /* store the response in the SMB stream */
1063         samr_io_r_query_usergroups("", &r_u, rdata, 0);
1064
1065         DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1066
1067 }
1068
1069 /*******************************************************************
1070  api_samr_query_usergroups
1071  ********************************************************************/
1072 static void api_samr_query_usergroups( int uid, prs_struct *data, prs_struct *rdata)
1073 {
1074         SAMR_Q_QUERY_USERGROUPS q_u;
1075         /* grab the samr unknown 32 */
1076         samr_io_q_query_usergroups("", &q_u, data, 0);
1077
1078         /* construct reply. */
1079         samr_reply_query_usergroups(&q_u, rdata);
1080 }
1081
1082
1083 /*******************************************************************
1084  samr_reply_unknown_32
1085  ********************************************************************/
1086 static void samr_reply_unknown_32(SAMR_Q_UNKNOWN_32 *q_u,
1087                                 prs_struct *rdata,
1088                                 int status)
1089 {
1090         int i;
1091         SAMR_R_UNKNOWN_32 r_u;
1092
1093         /* set up the SAMR unknown_32 response */
1094         bzero(&(r_u.pol.data), POL_HND_SIZE);
1095         if (status == 0)
1096         {
1097                 for (i = 4; i < POL_HND_SIZE; i++)
1098                 {
1099                         r_u.pol.data[i] = i+1;
1100                 }
1101         }
1102
1103         make_dom_rid4(&(r_u.rid4), 0x0030, 0, 0);
1104         r_u.status    = status;
1105
1106         DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
1107
1108         /* store the response in the SMB stream */
1109         samr_io_r_unknown_32("", &r_u, rdata, 0);
1110
1111         DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
1112
1113 }
1114
1115 /*******************************************************************
1116  api_samr_unknown_32
1117  ********************************************************************/
1118 static void api_samr_unknown_32( int uid, prs_struct *data, prs_struct *rdata)
1119 {
1120         uint32 status = 0;
1121         struct smb_passwd *smb_pass;
1122         fstring mach_acct;
1123
1124         SAMR_Q_UNKNOWN_32 q_u;
1125
1126         /* grab the samr unknown 32 */
1127         samr_io_q_unknown_32("", &q_u, data, 0);
1128
1129         /* find the machine account: tell the caller if it exists.
1130            lkclXXXX i have *no* idea if this is a problem or not
1131            or even if you are supposed to construct a different
1132            reply if the account already exists...
1133          */
1134
1135         fstrcpy(mach_acct, unistrn2(q_u.uni_mach_acct.buffer,
1136                                     q_u.uni_mach_acct.uni_str_len));
1137
1138         become_root(True);
1139         smb_pass = getsampwnam(mach_acct);
1140         unbecome_root(True);
1141
1142         if (smb_pass != NULL)
1143         {
1144                 /* machine account exists: say so */
1145                 status = 0xC0000000 | NT_STATUS_USER_EXISTS;
1146         }
1147         else
1148         {
1149                 /* this could cause trouble... */
1150                 status = 0;
1151         }
1152
1153         /* construct reply. */
1154         samr_reply_unknown_32(&q_u, rdata, status);
1155 }
1156
1157
1158 /*******************************************************************
1159  samr_reply_connect
1160  ********************************************************************/
1161 static void samr_reply_connect(SAMR_Q_CONNECT *q_u,
1162                                 prs_struct *rdata)
1163 {
1164         SAMR_R_CONNECT r_u;
1165         BOOL pol_open = False;
1166
1167         /* set up the SAMR connect response */
1168
1169         r_u.status = 0x0;
1170         /* get a (unique) handle.  open a policy on it. */
1171         if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1172         {
1173                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1174         }
1175
1176         /* associate the domain SID with the (unique) handle. */
1177         if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1178         {
1179                 /* oh, whoops.  don't know what error message to return, here */
1180                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1181         }
1182
1183         if (r_u.status != 0 && pol_open)
1184         {
1185                 close_lsa_policy_hnd(&(r_u.connect_pol));
1186         }
1187
1188         DEBUG(5,("samr_connect: %d\n", __LINE__));
1189
1190         /* store the response in the SMB stream */
1191         samr_io_r_connect("", &r_u, rdata, 0);
1192
1193         DEBUG(5,("samr_connect: %d\n", __LINE__));
1194
1195 }
1196
1197 /*******************************************************************
1198  api_samr_connect
1199  ********************************************************************/
1200 static void api_samr_connect( int uid, prs_struct *data, prs_struct *rdata)
1201 {
1202         SAMR_Q_CONNECT q_u;
1203
1204         /* grab the samr open policy */
1205         samr_io_q_connect("", &q_u, data, 0);
1206
1207         /* construct reply.  always indicate success */
1208         samr_reply_connect(&q_u, rdata);
1209 }
1210
1211 /*******************************************************************
1212  samr_reply_open_alias
1213  ********************************************************************/
1214 static void samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
1215                                 prs_struct *rdata)
1216 {
1217         SAMR_R_OPEN_ALIAS r_u;
1218         BOOL pol_open = False;
1219
1220         /* set up the SAMR open_alias response */
1221
1222         r_u.status = 0x0;
1223         /* get a (unique) handle.  open a policy on it. */
1224         if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.pol))))
1225         {
1226                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1227         }
1228
1229         /* associate a RID with the (unique) handle. */
1230         if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.pol), q_u->rid_alias))
1231         {
1232                 /* oh, whoops.  don't know what error message to return, here */
1233                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1234         }
1235
1236         if (r_u.status != 0 && pol_open)
1237         {
1238                 close_lsa_policy_hnd(&(r_u.pol));
1239         }
1240
1241         DEBUG(5,("samr_open_alias: %d\n", __LINE__));
1242
1243         /* store the response in the SMB stream */
1244         samr_io_r_open_alias("", &r_u, rdata, 0);
1245
1246         DEBUG(5,("samr_open_alias: %d\n", __LINE__));
1247
1248 }
1249
1250 /*******************************************************************
1251  api_samr_open_alias
1252  ********************************************************************/
1253 static void api_samr_open_alias( int uid, prs_struct *data, prs_struct *rdata)
1254                                 
1255 {
1256         SAMR_Q_OPEN_ALIAS q_u;
1257
1258         /* grab the samr open policy */
1259         samr_io_q_open_alias("", &q_u, data, 0);
1260
1261         /* construct reply.  always indicate success */
1262         samr_reply_open_alias(&q_u, rdata);
1263 }
1264
1265 /*******************************************************************
1266  array of \PIPE\samr operations
1267  ********************************************************************/
1268 static struct api_struct api_samr_cmds [] =
1269 {
1270         { "SAMR_CLOSE_HND"        , SAMR_CLOSE_HND        , api_samr_close_hnd        },
1271         { "SAMR_CONNECT"          , SAMR_CONNECT          , api_samr_connect          },
1272         { "SAMR_ENUM_DOM_USERS"   , SAMR_ENUM_DOM_USERS   , api_samr_enum_dom_users   },
1273         { "SAMR_ENUM_DOM_GROUPS"  , SAMR_ENUM_DOM_GROUPS  , api_samr_enum_dom_groups  },
1274         { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
1275         { "SAMR_LOOKUP_IDS"       , SAMR_LOOKUP_IDS       , api_samr_lookup_ids       },
1276         { "SAMR_LOOKUP_NAMES"     , SAMR_LOOKUP_NAMES     , api_samr_lookup_names     },
1277         { "SAMR_OPEN_USER"        , SAMR_OPEN_USER        , api_samr_open_user        },
1278         { "SAMR_QUERY_USERINFO"   , SAMR_QUERY_USERINFO   , api_samr_query_userinfo   },
1279         { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
1280         { "SAMR_QUERY_DISPINFO"   , SAMR_QUERY_DISPINFO   , api_samr_query_dispinfo   },
1281         { "SAMR_QUERY_ALIASINFO"  , SAMR_QUERY_ALIASINFO  , api_samr_query_aliasinfo  },
1282         { "SAMR_0x32"             , 0x32                  , api_samr_unknown_32       },
1283         { "SAMR_UNKNOWN_12"       , SAMR_UNKNOWN_12       , api_samr_unknown_12       },
1284         { "SAMR_OPEN_ALIAS"       , SAMR_OPEN_ALIAS       , api_samr_open_alias       },
1285         { "SAMR_OPEN_DOMAIN"      , SAMR_OPEN_DOMAIN      , api_samr_open_domain      },
1286         { "SAMR_UNKNOWN_3"        , SAMR_UNKNOWN_3        , api_samr_unknown_3        },
1287     { NULL                    , 0                     , NULL                      }
1288 };
1289
1290 /*******************************************************************
1291  receives a samr pipe and responds.
1292  ********************************************************************/
1293 BOOL api_samr_rpc(pipes_struct *p, prs_struct *data)
1294 {
1295     return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds, data);
1296 }
1297