Win9x user level security.
[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 fstring global_sam_name;
32 extern pstring global_myname;
33 extern DOM_SID global_sam_sid;
34 extern DOM_SID global_sid_S_1_1;
35 extern DOM_SID global_sid_S_1_5_20;
36
37 /*******************************************************************
38   This next function should be replaced with something that
39   dynamically returns the correct user info..... JRA.
40  ********************************************************************/
41
42 static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf,
43                                 int start_idx,
44                                 int *total_entries, int *num_entries,
45                                 int max_num_entries,
46                                 uint16 acb_mask)
47 {
48         void *vp = NULL;
49         struct sam_passwd *pwd = NULL;
50
51         (*num_entries) = 0;
52         (*total_entries) = 0;
53
54         if (pw_buf == NULL) return False;
55
56         vp = startsmbpwent(False);
57         if (!vp)
58         {
59                 DEBUG(0, ("get_sampwd_entries: Unable to open SMB password database.\n"));
60                 return False;
61         }
62
63         while (((pwd = getsam21pwent(vp)) != NULL) && (*num_entries) < max_num_entries)
64         {
65                 int user_name_len;
66
67                 if (start_idx > 0)
68                 {
69                         /* skip the requested number of entries.
70                            not very efficient, but hey...
71                          */
72                         if (acb_mask == 0 || IS_BITS_SET_SOME(pwd->acct_ctrl, acb_mask))
73                         {
74                                 start_idx--;
75                         }
76                         continue;
77                 }
78
79                 user_name_len = strlen(pwd->nt_name);
80                 make_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->nt_name, user_name_len);
81                 make_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len, 
82                                user_name_len, 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->nt_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         samr_io_q_close_hnd("", &q_u, data, 0);
153         samr_reply_close_hnd(&q_u, rdata);
154 }
155
156
157 /*******************************************************************
158  samr_reply_open_domain
159  ********************************************************************/
160 static void samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
161                                 prs_struct *rdata)
162 {
163         SAMR_R_OPEN_DOMAIN r_u;
164         BOOL pol_open = False;
165
166         r_u.status = 0x0;
167
168         /* find the connection policy handle. */
169         if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->connect_pol)) == -1))
170         {
171                 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
172         }
173
174         /* get a (unique) handle.  open a policy on it. */
175         if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.domain_pol))))
176         {
177                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
178         }
179
180         /* associate the domain SID with the (unique) handle. */
181         if (r_u.status == 0x0 && !set_lsa_policy_samr_sid(&(r_u.domain_pol), &(q_u->dom_sid.sid)))
182         {
183                 /* oh, whoops.  don't know what error message to return, here */
184                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
185         }
186
187         if (r_u.status != 0 && pol_open)
188         {
189                 close_lsa_policy_hnd(&(r_u.domain_pol));
190         }
191
192         DEBUG(5,("samr_open_domain: %d\n", __LINE__));
193
194         /* store the response in the SMB stream */
195         samr_io_r_open_domain("", &r_u, rdata, 0);
196
197         DEBUG(5,("samr_open_domain: %d\n", __LINE__));
198
199 }
200
201 /*******************************************************************
202  api_samr_open_domain
203  ********************************************************************/
204 static void api_samr_open_domain( uint16 vuid, prs_struct *data, prs_struct *rdata)
205 {
206         SAMR_Q_OPEN_DOMAIN q_u;
207         samr_io_q_open_domain("", &q_u, data, 0);
208         samr_reply_open_domain(&q_u, rdata);
209 }
210
211
212 /*******************************************************************
213  samr_reply_unknown_2c
214  ********************************************************************/
215 static void samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u,
216                                 prs_struct *rdata)
217 {
218         SAMR_R_UNKNOWN_2C r_u;
219         uint32 status = 0x0;
220
221         /* find the policy handle.  open a policy on it. */
222         if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
223         {
224                 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
225         }
226
227         /* find the user's rid */
228         if ((status == 0x0) && (get_lsa_policy_samr_rid(&(q_u->user_pol)) == 0xffffffff))
229         {
230                 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
231         }
232
233         make_samr_r_unknown_2c(&r_u, status);
234
235         DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
236
237         /* store the response in the SMB stream */
238         samr_io_r_unknown_2c("", &r_u, rdata, 0);
239
240         DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
241
242 }
243
244 /*******************************************************************
245  api_samr_unknown_2c
246  ********************************************************************/
247 static void api_samr_unknown_2c( uint16 vuid, prs_struct *data, prs_struct *rdata)
248 {
249         SAMR_Q_UNKNOWN_2C q_u;
250         samr_io_q_unknown_2c("", &q_u, data, 0);
251         samr_reply_unknown_2c(&q_u, rdata);
252 }
253
254
255 /*******************************************************************
256  samr_reply_unknown_3
257  ********************************************************************/
258 static void samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
259                                 prs_struct *rdata)
260 {
261         SAMR_R_UNKNOWN_3 r_u;
262         DOM_SID3 sid[MAX_SAM_SIDS];
263         uint32 rid;
264         uint32 status;
265
266         status = 0x0;
267
268         /* find the policy handle.  open a policy on it. */
269         if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
270         {
271                 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
272         }
273
274         /* find the user's rid */
275         if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->user_pol))) == 0xffffffff)
276         {
277                 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
278         }
279
280         if (status == 0x0)
281         {
282                 DOM_SID usr_sid;
283
284                 usr_sid = global_sam_sid;
285
286                 SMB_ASSERT_ARRAY(usr_sid.sub_auths, usr_sid.num_auths+1);
287
288                 /*
289                  * Add the user RID.
290                  */
291                 sid_append_rid(&usr_sid, rid);
292                 
293                 /* maybe need another 1 or 2 (S-1-5-0x20-0x220 and S-1-5-20-0x224) */
294                 /* these two are DOMAIN_ADMIN and DOMAIN_ACCT_OP group RIDs */
295                 make_dom_sid3(&(sid[0]), 0x035b, 0x0002, &global_sid_S_1_1);
296                 make_dom_sid3(&(sid[1]), 0x0044, 0x0002, &usr_sid);
297         }
298
299         make_samr_r_unknown_3(&r_u,
300                                 0x0001, 0x8004,
301                                 0x00000014, 0x0002, 0x0070,
302                                 2, sid, status);
303
304         DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
305
306         /* store the response in the SMB stream */
307         samr_io_r_unknown_3("", &r_u, rdata, 0);
308
309         DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
310
311 }
312
313 /*******************************************************************
314  api_samr_unknown_3
315  ********************************************************************/
316 static void api_samr_unknown_3( uint16 vuid, prs_struct *data, prs_struct *rdata)
317 {
318         SAMR_Q_UNKNOWN_3 q_u;
319         samr_io_q_unknown_3("", &q_u, data, 0);
320         samr_reply_unknown_3(&q_u, rdata);
321 }
322
323
324 /*******************************************************************
325  samr_reply_enum_dom_users
326  ********************************************************************/
327 static void samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
328                                 prs_struct *rdata)
329 {
330         SAMR_R_ENUM_DOM_USERS r_e;
331         SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
332         int num_entries;
333         int total_entries;
334
335         r_e.status = 0x0;
336
337         /* find the policy handle.  open a policy on it. */
338         if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
339         {
340                 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
341         }
342
343         DEBUG(5,("samr_reply_enum_dom_users: %d\n", __LINE__));
344
345         become_root(True);
346         get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
347                            MAX_SAM_ENTRIES, q_u->acb_mask);
348         unbecome_root(True);
349
350         make_samr_r_enum_dom_users(&r_e, 
351                                    q_u->start_idx + num_entries, num_entries,
352                                    pass, r_e.status);
353
354         /* store the response in the SMB stream */
355         samr_io_r_enum_dom_users("", &r_e, rdata, 0);
356
357         DEBUG(5,("samr_enum_dom_users: %d\n", __LINE__));
358
359 }
360
361 /*******************************************************************
362  api_samr_enum_dom_users
363  ********************************************************************/
364 static void api_samr_enum_dom_users( uint16 vuid, prs_struct *data, prs_struct *rdata)
365 {
366         SAMR_Q_ENUM_DOM_USERS q_e;
367         samr_io_q_enum_dom_users("", &q_e, data, 0);
368         samr_reply_enum_dom_users(&q_e, rdata);
369 }
370
371
372 /*******************************************************************
373  samr_reply_add_groupmem
374  ********************************************************************/
375 static void samr_reply_add_groupmem(SAMR_Q_ADD_GROUPMEM *q_u,
376                                 prs_struct *rdata)
377 {
378         SAMR_R_ADD_GROUPMEM r_e;
379         DOM_SID group_sid;
380         uint32 group_rid;
381         fstring group_sid_str;
382
383         r_e.status = 0x0;
384
385         /* find the policy handle.  open a policy on it. */
386         if (r_e.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &group_sid))
387         {
388                 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
389         }
390         else
391         {
392                 sid_to_string(group_sid_str, &group_sid);
393                 sid_split_rid(&group_sid, &group_rid);
394         }
395
396         if (r_e.status == 0x0)
397         {
398                 DEBUG(10,("sid is %s\n", group_sid_str));
399
400                 if (sid_equal(&group_sid, &global_sam_sid))
401                 {
402                         DEBUG(10,("lookup on Domain SID\n"));
403
404                         become_root(True);
405                         r_e.status = add_group_member(group_rid, q_u->rid) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
406                         unbecome_root(True);
407                 }
408                 else
409                 {
410                         r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_GROUP;
411                 }
412         }
413
414         /* store the response in the SMB stream */
415         samr_io_r_add_groupmem("", &r_e, rdata, 0);
416
417         DEBUG(5,("samr_add_groupmem: %d\n", __LINE__));
418 }
419
420 /*******************************************************************
421  api_samr_add_groupmem
422  ********************************************************************/
423 static void api_samr_add_groupmem( uint16 vuid, prs_struct *data, prs_struct *rdata)
424 {
425         SAMR_Q_ADD_GROUPMEM q_e;
426         samr_io_q_add_groupmem("", &q_e, data, 0);
427         samr_reply_add_groupmem(&q_e, rdata);
428 }
429
430 /*******************************************************************
431  samr_reply_del_groupmem
432  ********************************************************************/
433 static void samr_reply_del_groupmem(SAMR_Q_DEL_GROUPMEM *q_u,
434                                 prs_struct *rdata)
435 {
436         SAMR_R_DEL_GROUPMEM r_e;
437         DOM_SID group_sid;
438         uint32 group_rid;
439         fstring group_sid_str;
440
441         r_e.status = 0x0;
442
443         /* find the policy handle.  open a policy on it. */
444         if (r_e.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &group_sid))
445         {
446                 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
447         }
448         else
449         {
450                 sid_to_string(group_sid_str, &group_sid);
451                 sid_split_rid(&group_sid, &group_rid);
452         }
453
454         if (r_e.status == 0x0)
455         {
456                 DEBUG(10,("sid is %s\n", group_sid_str));
457
458                 if (sid_equal(&group_sid, &global_sam_sid))
459                 {
460                         DEBUG(10,("lookup on Domain SID\n"));
461
462                         become_root(True);
463                         r_e.status = del_group_member(group_rid, q_u->rid) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
464                         unbecome_root(True);
465                 }
466                 else
467                 {
468                         r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_GROUP;
469                 }
470         }
471
472         /* store the response in the SMB stream */
473         samr_io_r_del_groupmem("", &r_e, rdata, 0);
474
475         DEBUG(5,("samr_del_groupmem: %d\n", __LINE__));
476 }
477
478 /*******************************************************************
479  api_samr_del_groupmem
480  ********************************************************************/
481 static void api_samr_del_groupmem( uint16 vuid, prs_struct *data, prs_struct *rdata)
482 {
483         SAMR_Q_DEL_GROUPMEM q_e;
484         samr_io_q_del_groupmem("", &q_e, data, 0);
485         samr_reply_del_groupmem(&q_e, rdata);
486 }
487
488 /*******************************************************************
489  samr_reply_add_aliasmem
490  ********************************************************************/
491 static void samr_reply_add_aliasmem(SAMR_Q_ADD_ALIASMEM *q_u,
492                                 prs_struct *rdata)
493 {
494         SAMR_R_ADD_ALIASMEM r_e;
495         DOM_SID alias_sid;
496         uint32 alias_rid;
497         fstring alias_sid_str;
498
499         r_e.status = 0x0;
500
501         /* find the policy handle.  open a policy on it. */
502         if (r_e.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->alias_pol, &alias_sid))
503         {
504                 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
505         }
506         else
507         {
508                 sid_to_string(alias_sid_str, &alias_sid);
509                 sid_split_rid(&alias_sid, &alias_rid);
510         }
511
512         if (r_e.status == 0x0)
513         {
514                 DEBUG(10,("sid is %s\n", alias_sid_str));
515
516                 if (sid_equal(&alias_sid, &global_sam_sid))
517                 {
518                         DEBUG(10,("add member on Domain SID\n"));
519
520                         become_root(True);
521                         r_e.status = add_alias_member(alias_rid, &q_u->sid.sid) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
522                         unbecome_root(True);
523                 }
524                 else if (sid_equal(&alias_sid, &global_sid_S_1_5_20))
525                 {
526                         DEBUG(10,("add member on BUILTIN SID\n"));
527
528                         become_root(True);
529                         r_e.status = add_builtin_member(alias_rid, &q_u->sid.sid) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
530                         unbecome_root(True);
531                 }
532                 else
533                 {
534                         r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
535                 }
536         }
537
538         /* store the response in the SMB stream */
539         samr_io_r_add_aliasmem("", &r_e, rdata, 0);
540
541         DEBUG(5,("samr_add_aliasmem: %d\n", __LINE__));
542 }
543
544 /*******************************************************************
545  api_samr_add_aliasmem
546  ********************************************************************/
547 static void api_samr_add_aliasmem( uint16 vuid, prs_struct *data, prs_struct *rdata)
548 {
549         SAMR_Q_ADD_ALIASMEM q_e;
550         samr_io_q_add_aliasmem("", &q_e, data, 0);
551         samr_reply_add_aliasmem(&q_e, rdata);
552 }
553
554 /*******************************************************************
555  samr_reply_del_aliasmem
556  ********************************************************************/
557 static void samr_reply_del_aliasmem(SAMR_Q_DEL_ALIASMEM *q_u,
558                                 prs_struct *rdata)
559 {
560         SAMR_R_DEL_ALIASMEM r_e;
561         DOM_SID alias_sid;
562         uint32 alias_rid;
563         fstring alias_sid_str;
564
565         r_e.status = 0x0;
566
567         /* find the policy handle.  open a policy on it. */
568         if (r_e.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->alias_pol, &alias_sid))
569         {
570                 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
571         }
572         else
573         {
574                 sid_to_string(alias_sid_str, &alias_sid);
575                 sid_split_rid(&alias_sid, &alias_rid);
576         }
577
578         if (r_e.status == 0x0)
579         {
580                 DEBUG(10,("sid is %s\n", alias_sid_str));
581
582                 if (sid_equal(&alias_sid, &global_sam_sid))
583                 {
584                         DEBUG(10,("del member on Domain SID\n"));
585
586                         become_root(True);
587                         r_e.status = del_alias_member(alias_rid, &q_u->sid.sid) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
588                         unbecome_root(True);
589                 }
590                 else if (sid_equal(&alias_sid, &global_sid_S_1_5_20))
591                 {
592                         DEBUG(10,("del member on BUILTIN SID\n"));
593
594                         become_root(True);
595                         r_e.status = del_builtin_member(alias_rid, &q_u->sid.sid) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
596                         unbecome_root(True);
597                 }
598                 else
599                 {
600                         r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
601                 }
602         }
603
604         /* store the response in the SMB stream */
605         samr_io_r_del_aliasmem("", &r_e, rdata, 0);
606
607         DEBUG(5,("samr_del_aliasmem: %d\n", __LINE__));
608 }
609
610 /*******************************************************************
611  api_samr_del_aliasmem
612  ********************************************************************/
613 static void api_samr_del_aliasmem( uint16 vuid, prs_struct *data, prs_struct *rdata)
614 {
615         SAMR_Q_DEL_ALIASMEM q_e;
616         samr_io_q_del_aliasmem("", &q_e, data, 0);
617         samr_reply_del_aliasmem(&q_e, rdata);
618 }
619
620 /*******************************************************************
621  samr_reply_enum_dom_groups
622  ********************************************************************/
623 static void samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u,
624                                 prs_struct *rdata)
625 {
626         SAMR_R_ENUM_DOM_GROUPS r_e;
627         DOMAIN_GRP *grps = NULL;
628         int num_entries = 0;
629         DOM_SID sid;
630         fstring sid_str;
631
632         r_e.status = 0x0;
633         r_e.num_entries = 0;
634
635         /* find the policy handle.  open a policy on it. */
636         if (r_e.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &sid))
637         {
638                 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
639         }
640
641         sid_to_string(sid_str, &sid);
642
643         DEBUG(5,("samr_reply_enum_dom_groups: sid %s\n", sid_str));
644
645         if (sid_equal(&sid, &global_sam_sid))
646         {
647                 BOOL ret;
648
649                 become_root(True);
650                 ret = enumdomgroups(&grps, &num_entries);
651                 unbecome_root(True);
652                 if (!ret)
653                 {
654                         r_e.status = 0xC0000000 | NT_STATUS_NO_MEMORY;
655                 }
656         }
657
658         if (r_e.status == 0x0)
659         {
660                 make_samr_r_enum_dom_groups(&r_e, num_entries, grps, r_e.status);
661         }
662
663         /* store the response in the SMB stream */
664         samr_io_r_enum_dom_groups("", &r_e, rdata, 0);
665
666         if (grps != NULL)
667         {
668                 free(grps);
669         }
670
671         DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
672 }
673
674 /*******************************************************************
675  api_samr_enum_dom_aliases
676  ********************************************************************/
677 static void api_samr_enum_dom_groups( uint16 vuid, prs_struct *data, prs_struct *rdata)
678 {
679         SAMR_Q_ENUM_DOM_GROUPS q_e;
680
681         /* grab the samr open */
682         samr_io_q_enum_dom_groups("", &q_e, data, 0);
683
684         /* construct reply. */
685         samr_reply_enum_dom_groups(&q_e, rdata);
686 }
687
688
689 /*******************************************************************
690  samr_reply_enum_dom_aliases
691  ********************************************************************/
692 static void samr_reply_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_u,
693                                 prs_struct *rdata)
694 {
695         SAMR_R_ENUM_DOM_ALIASES r_e;
696         LOCAL_GRP *alss = NULL;
697         int num_entries = 0;
698         DOM_SID sid;
699         fstring sid_str;
700
701         r_e.status = 0x0;
702         r_e.num_entries = 0;
703
704         /* find the policy handle.  open a policy on it. */
705         if (r_e.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &sid))
706         {
707                 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
708         }
709
710         sid_to_string(sid_str, &sid);
711
712         DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
713
714         /* well-known aliases */
715         if (sid_equal(&sid, &global_sid_S_1_5_20))
716         {
717                 BOOL ret;
718                 /* builtin aliases */
719
720                 become_root(True);
721                 ret = enumdombuiltins(&alss, &num_entries);
722                 unbecome_root(True);
723                 if (!ret)
724                 {
725                         r_e.status = 0xC0000000 | NT_STATUS_NO_MEMORY;
726                 }
727         }
728         else if (sid_equal(&sid, &global_sam_sid))
729         {
730                 BOOL ret;
731                 /* local aliases */
732
733                 become_root(True);
734                 ret = enumdomaliases(&alss, &num_entries);
735                 unbecome_root(True);
736                 if (!ret)
737                 {
738                         r_e.status = 0xC0000000 | NT_STATUS_NO_MEMORY;
739                 }
740         }
741                 
742         if (r_e.status == 0x0)
743         {
744                 make_samr_r_enum_dom_aliases(&r_e, num_entries, alss, r_e.status);
745         }
746
747         /* store the response in the SMB stream */
748         samr_io_r_enum_dom_aliases("", &r_e, rdata, 0);
749
750         if (alss != NULL)
751         {
752                 free(alss);
753         }
754
755         DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
756
757 }
758
759 /*******************************************************************
760  api_samr_enum_dom_aliases
761  ********************************************************************/
762 static void api_samr_enum_dom_aliases( uint16 vuid, prs_struct *data, prs_struct *rdata)
763 {
764         SAMR_Q_ENUM_DOM_ALIASES q_e;
765
766         /* grab the samr open */
767         samr_io_q_enum_dom_aliases("", &q_e, data, 0);
768
769         /* construct reply. */
770         samr_reply_enum_dom_aliases(&q_e, rdata);
771 }
772
773
774 /*******************************************************************
775  samr_reply_query_dispinfo
776  ********************************************************************/
777 static void samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u,
778                                 prs_struct *rdata)
779 {
780         SAMR_R_QUERY_DISPINFO r_e;
781         SAM_DISPINFO_CTR ctr;
782         SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
783         DOMAIN_GRP *grps = NULL;
784         DOMAIN_GRP *sam_grps = NULL;
785         uint32 data_size = 0;
786         uint32 status = 0x0;
787         uint16 acb_mask = ACB_NORMAL;
788         int num_sam_entries = 0;
789         int num_entries = 0;
790         int total_entries;
791
792         DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
793
794         /* find the policy handle.  open a policy on it. */
795         if (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1)
796         {
797                 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
798                 DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n"));
799         }
800
801         if (status == 0x0)
802         {
803                 become_root(True);
804
805                 /* Get what we need from the password database */
806                 switch (q_u->switch_level)
807                 {
808                         case 0x2:
809                         {
810                                 acb_mask = ACB_WSTRUST;
811                                 /* Fall through */
812                         }
813                         case 0x1:
814                         case 0x4:
815                         {
816                                 get_sampwd_entries(pass, q_u->start_idx,
817                                               &total_entries, &num_sam_entries,
818                                               MAX_SAM_ENTRIES, acb_mask);
819                                 break;
820                         }
821                         case 0x3:
822                         case 0x5:
823                         {
824                                 enumdomgroups(&sam_grps, &num_sam_entries);
825
826                                 if (q_u->start_idx < num_sam_entries) {
827                                         grps = sam_grps + q_u->start_idx;
828                                         num_sam_entries -= q_u->start_idx;
829                                 } else {
830                                         num_sam_entries = 0;
831                                 }
832                                 break;
833                         }
834                 }
835
836                 unbecome_root(True);
837
838                 num_entries = num_sam_entries;
839
840                 if (num_entries > q_u->max_entries)
841                 {
842                         num_entries = q_u->max_entries;
843                 }
844
845                 if (num_entries > MAX_SAM_ENTRIES)
846                 {
847                         num_entries = MAX_SAM_ENTRIES;
848                         DEBUG(5,("limiting number of entries to %d\n", 
849                                  num_entries));
850                 }
851
852                 data_size = q_u->max_size;
853
854                 /* Now create reply structure */
855                 switch (q_u->switch_level)
856                 {
857                         case 0x1:
858                         {
859                                 ctr.sam.info1 = malloc(sizeof(SAM_DISPINFO_1));
860                                 make_sam_dispinfo_1(ctr.sam.info1,
861                                                     &num_entries, &data_size,
862                                                     q_u->start_idx, pass);
863                                 break;
864                         }
865                         case 0x2:
866                         {
867                                 ctr.sam.info2 = malloc(sizeof(SAM_DISPINFO_2));
868                                 make_sam_dispinfo_2(ctr.sam.info2,
869                                                     &num_entries, &data_size,
870                                                     q_u->start_idx, pass);
871                                 break;
872                         }
873                         case 0x3:
874                         {
875                                 ctr.sam.info3 = malloc(sizeof(SAM_DISPINFO_3));
876                                 make_sam_dispinfo_3(ctr.sam.info3,
877                                                     &num_entries, &data_size,
878                                                     q_u->start_idx, grps);
879                                 break;
880                         }
881                         case 0x4:
882                         {
883                                 ctr.sam.info4 = malloc(sizeof(SAM_DISPINFO_4));
884                                 make_sam_dispinfo_4(ctr.sam.info4,
885                                                     &num_entries, &data_size,
886                                                     q_u->start_idx, pass);
887                                 break;
888                         }
889                         case 0x5:
890                         {
891                                 ctr.sam.info5 = malloc(sizeof(SAM_DISPINFO_5));
892                                 make_sam_dispinfo_5(ctr.sam.info5,
893                                                     &num_entries, &data_size,
894                                                     q_u->start_idx, grps);
895                                 break;
896                         }
897                         default:
898                         {
899                                 ctr.sam.info = NULL;
900                                 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
901                                 break;
902                         }
903                 }
904         }
905
906         if ((status == 0) && (num_entries < num_sam_entries))
907         {
908                 status = 0x105; /* STATUS_MORE_ENTRIES */
909         }
910
911         make_samr_r_query_dispinfo(&r_e, num_entries, data_size,
912                                    q_u->switch_level, &ctr, status);
913
914         /* store the response in the SMB stream */
915         samr_io_r_query_dispinfo("", &r_e, rdata, 0);
916
917         /* free malloc'd areas */
918         if (sam_grps != NULL)
919         {
920                 free(sam_grps);
921         }
922
923         if (ctr.sam.info != NULL)
924         {
925                 free(ctr.sam.info);
926         }
927
928         DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
929 }
930
931 /*******************************************************************
932  api_samr_query_dispinfo
933  ********************************************************************/
934 static void api_samr_query_dispinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
935 {
936         SAMR_Q_QUERY_DISPINFO q_e;
937
938         samr_io_q_query_dispinfo("", &q_e, data, 0);
939         samr_reply_query_dispinfo(&q_e, rdata);
940 }
941
942 /*******************************************************************
943  samr_reply_delete_dom_group
944  ********************************************************************/
945 static void samr_reply_delete_dom_group(SAMR_Q_DELETE_DOM_GROUP *q_u,
946                                 prs_struct *rdata)
947 {
948         uint32 status = 0;
949
950         DOM_SID group_sid;
951         uint32 group_rid;
952         fstring group_sid_str;
953
954         SAMR_R_DELETE_DOM_GROUP r_u;
955
956         DEBUG(5,("samr_delete_dom_group: %d\n", __LINE__));
957
958         /* find the policy handle.  open a policy on it. */
959         if (status == 0x0 && !get_lsa_policy_samr_sid(&q_u->group_pol, &group_sid))
960         {
961                 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
962         }
963         else
964         {
965                 sid_to_string(group_sid_str, &group_sid     );
966                 sid_split_rid(&group_sid, &group_rid);
967         }
968
969         if (status == 0x0)
970         {
971                 DEBUG(10,("sid is %s\n", group_sid_str));
972
973                 if (sid_equal(&group_sid, &global_sam_sid))
974                 {
975                         DEBUG(10,("lookup on Domain SID\n"));
976
977                         become_root(True);
978                         status = del_group_entry(group_rid) ? 0x0 : (0xC0000000 | NT_STATUS_NO_SUCH_GROUP);
979                         unbecome_root(True);
980                 }
981                 else
982                 {
983                         status = 0xC0000000 | NT_STATUS_NO_SUCH_GROUP;
984                 }
985         }
986
987         make_samr_r_delete_dom_group(&r_u, status);
988
989         /* store the response in the SMB stream */
990         samr_io_r_delete_dom_group("", &r_u, rdata, 0);
991 }
992
993 /*******************************************************************
994  api_samr_delete_dom_group
995  ********************************************************************/
996 static void api_samr_delete_dom_group( uint16 vuid, prs_struct *data, prs_struct *rdata)
997 {
998         SAMR_Q_DELETE_DOM_GROUP q_u;
999         samr_io_q_delete_dom_group("", &q_u, data, 0);
1000         samr_reply_delete_dom_group(&q_u, rdata);
1001 }
1002
1003
1004 /*******************************************************************
1005  samr_reply_query_groupmem
1006  ********************************************************************/
1007 static void samr_reply_query_groupmem(SAMR_Q_QUERY_GROUPMEM *q_u,
1008                                 prs_struct *rdata)
1009 {
1010         uint32 status = 0;
1011
1012         DOMAIN_GRP_MEMBER *mem_grp = NULL;
1013         uint32 *rid = NULL;
1014         uint32 *attr = NULL;
1015         int num_rids = 0;
1016         DOM_SID group_sid;
1017         uint32 group_rid;
1018         fstring group_sid_str;
1019
1020         SAMR_R_QUERY_GROUPMEM r_u;
1021
1022         DEBUG(5,("samr_query_groupmem: %d\n", __LINE__));
1023
1024         /* find the policy handle.  open a policy on it. */
1025         if (status == 0x0 && !get_lsa_policy_samr_sid(&q_u->group_pol, &group_sid))
1026         {
1027                 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1028         }
1029         else
1030         {
1031                 sid_to_string(group_sid_str, &group_sid     );
1032                 sid_split_rid(&group_sid, &group_rid);
1033         }
1034
1035         if (status == 0x0)
1036         {
1037                 DEBUG(10,("sid is %s\n", group_sid_str));
1038
1039                 if (sid_equal(&group_sid, &global_sam_sid))
1040                 {
1041                         DEBUG(10,("lookup on Domain SID\n"));
1042
1043                         become_root(True);
1044                         status = getgrouprid(group_rid, &mem_grp, &num_rids) != NULL ? 0x0 : (0xC0000000 | NT_STATUS_NO_SUCH_GROUP);
1045                         unbecome_root(True);
1046                 }
1047                 else
1048                 {
1049                         status = 0xC0000000 | NT_STATUS_NO_SUCH_GROUP;
1050                 }
1051         }
1052
1053         if (status == 0x0 && num_rids > 0)
1054         {
1055                 rid  = malloc(num_rids * sizeof(uint32));
1056                 attr = malloc(num_rids * sizeof(uint32));
1057                 if (mem_grp != NULL && rid != NULL && attr != NULL)
1058                 {
1059                         int i;
1060                         for (i = 0; i < num_rids; i++)
1061                         {
1062                                 rid [i] = mem_grp[i].rid;
1063                                 attr[i] = mem_grp[i].attr;
1064                         }
1065                         free(mem_grp);
1066                 }
1067         }
1068
1069         make_samr_r_query_groupmem(&r_u, num_rids, rid, attr, status);
1070
1071         /* store the response in the SMB stream */
1072         samr_io_r_query_groupmem("", &r_u, rdata, 0);
1073
1074         if (rid != NULL)
1075         {
1076                 free(rid);
1077         }
1078
1079         if (attr != NULL)
1080         {
1081                 free(attr);
1082         }
1083
1084         DEBUG(5,("samr_query_groupmem: %d\n", __LINE__));
1085
1086 }
1087
1088 /*******************************************************************
1089  api_samr_query_groupmem
1090  ********************************************************************/
1091 static void api_samr_query_groupmem( uint16 vuid, prs_struct *data, prs_struct *rdata)
1092 {
1093         SAMR_Q_QUERY_GROUPMEM q_u;
1094         samr_io_q_query_groupmem("", &q_u, data, 0);
1095         samr_reply_query_groupmem(&q_u, rdata);
1096 }
1097
1098
1099 /*******************************************************************
1100  samr_reply_query_groupinfo
1101  ********************************************************************/
1102 static void samr_reply_query_groupinfo(SAMR_Q_QUERY_GROUPINFO *q_u,
1103                                 prs_struct *rdata)
1104 {
1105         SAMR_R_QUERY_GROUPINFO r_e;
1106         GROUP_INFO_CTR ctr;
1107         uint32 status = 0x0;
1108
1109         r_e.ptr = 0;
1110
1111         /* find the policy handle.  open a policy on it. */
1112         if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1113         {
1114                 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1115         }
1116
1117         DEBUG(5,("samr_reply_query_groupinfo: %d\n", __LINE__));
1118
1119         if (status == 0x0)
1120         {
1121                 if (q_u->switch_level == 1)
1122                 {
1123                         r_e.ptr = 1;
1124                         ctr.switch_value1 = 1;
1125                         make_samr_group_info1(&ctr.group.info1, "account name", "account description");
1126                 }
1127                 else if (q_u->switch_level == 4)
1128                 {
1129                         r_e.ptr = 1;
1130                         ctr.switch_value1 = 4;
1131                         make_samr_group_info4(&ctr.group.info4, "account description");
1132                 }
1133                 else
1134                 {
1135                         status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
1136                 }
1137         }
1138
1139         make_samr_r_query_groupinfo(&r_e, status == 0 ? &ctr : NULL, status);
1140
1141         /* store the response in the SMB stream */
1142         samr_io_r_query_groupinfo("", &r_e, rdata, 0);
1143
1144         DEBUG(5,("samr_query_groupinfo: %d\n", __LINE__));
1145
1146 }
1147
1148 /*******************************************************************
1149  api_samr_query_groupinfo
1150  ********************************************************************/
1151 static void api_samr_query_groupinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
1152 {
1153         SAMR_Q_QUERY_GROUPINFO q_e;
1154         samr_io_q_query_groupinfo("", &q_e, data, 0);
1155         samr_reply_query_groupinfo(&q_e, rdata);
1156 }
1157
1158
1159 /*******************************************************************
1160  samr_reply_query_aliasinfo
1161  ********************************************************************/
1162 static void samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
1163                                 prs_struct *rdata)
1164 {
1165         SAMR_R_QUERY_ALIASINFO r_e;
1166         ALIAS_INFO_CTR ctr;
1167         uint32 status = 0x0;
1168
1169         r_e.ptr = 0;
1170
1171         /* find the policy handle.  open a policy on it. */
1172         if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1173         {
1174                 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1175         }
1176
1177         DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__));
1178
1179         if (status == 0x0)
1180         {
1181                 if (q_u->switch_level == 3)
1182                 {
1183                         r_e.ptr = 1;
1184                         ctr.switch_value1 = 3;
1185                         make_samr_alias_info3(&ctr.alias.info3, "<account description>");
1186                 }
1187                 else
1188                 {
1189                         status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
1190                 }
1191         }
1192
1193         make_samr_r_query_aliasinfo(&r_e, status == 0 ? &ctr : NULL, status);
1194
1195         /* store the response in the SMB stream */
1196         samr_io_r_query_aliasinfo("", &r_e, rdata, 0);
1197
1198         DEBUG(5,("samr_query_aliasinfo: %d\n", __LINE__));
1199
1200 }
1201
1202 /*******************************************************************
1203  api_samr_query_aliasinfo
1204  ********************************************************************/
1205 static void api_samr_query_aliasinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
1206 {
1207         SAMR_Q_QUERY_ALIASINFO q_e;
1208         samr_io_q_query_aliasinfo("", &q_e, data, 0);
1209         samr_reply_query_aliasinfo(&q_e, rdata);
1210 }
1211
1212
1213 /*******************************************************************
1214  samr_reply_query_useraliases
1215  ********************************************************************/
1216 static void samr_reply_query_useraliases(SAMR_Q_QUERY_USERALIASES *q_u,
1217                                 prs_struct *rdata)
1218 {
1219         uint32 status = 0;
1220
1221         LOCAL_GRP *mem_grp = NULL;
1222         uint32 *rid = NULL;
1223         int num_rids = 0;
1224         struct sam_passwd *sam_pass;
1225         DOM_SID usr_sid;
1226         DOM_SID dom_sid;
1227         uint32 user_rid;
1228         fstring sam_sid_str;
1229         fstring dom_sid_str;
1230         fstring usr_sid_str;
1231
1232         SAMR_R_QUERY_USERALIASES r_u;
1233
1234         DEBUG(5,("samr_query_useraliases: %d\n", __LINE__));
1235
1236         /* find the policy handle.  open a policy on it. */
1237         if (status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &dom_sid))
1238         {
1239                 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1240         }
1241         else
1242         {
1243                 sid_to_string(dom_sid_str, &dom_sid       );
1244                 sid_to_string(sam_sid_str, &global_sam_sid);
1245         }
1246
1247         if (status == 0x0)
1248         {
1249                 usr_sid = q_u->sid[0].sid;
1250                 sid_split_rid(&usr_sid, &user_rid);
1251                 sid_to_string(usr_sid_str, &usr_sid);
1252
1253         }
1254
1255         if (status == 0x0)
1256         {
1257                 /* find the user account */
1258                 become_root(True);
1259                 sam_pass = getsam21pwrid(user_rid);
1260                 unbecome_root(True);
1261
1262                 if (sam_pass == NULL)
1263                 {
1264                         status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1265                         num_rids = 0;
1266                 }
1267         }
1268
1269         if (status == 0x0)
1270         {
1271                 DEBUG(10,("sid is %s\n", dom_sid_str));
1272
1273                 if (sid_equal(&dom_sid, &global_sid_S_1_5_20))
1274                 {
1275                         DEBUG(10,("lookup on S-1-5-20\n"));
1276
1277                         become_root(True);
1278                         getuserbuiltinntnam(sam_pass->nt_name, &mem_grp, &num_rids);
1279                         unbecome_root(True);
1280                 }
1281                 else if (sid_equal(&dom_sid, &usr_sid))
1282                 {
1283                         DEBUG(10,("lookup on Domain SID\n"));
1284
1285                         become_root(True);
1286                         getuseraliasntnam(sam_pass->nt_name, &mem_grp, &num_rids);
1287                         unbecome_root(True);
1288                 }
1289                 else
1290                 {
1291                         status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1292                 }
1293         }
1294
1295         if (status == 0x0 && num_rids > 0)
1296         {
1297                 rid = malloc(num_rids * sizeof(uint32));
1298                 if (mem_grp != NULL && rid != NULL)
1299                 {
1300                         int i;
1301                         for (i = 0; i < num_rids; i++)
1302                         {
1303                                 rid[i] = mem_grp[i].rid;
1304                         }
1305                         free(mem_grp);
1306                 }
1307         }
1308
1309         make_samr_r_query_useraliases(&r_u, num_rids, rid, status);
1310
1311         /* store the response in the SMB stream */
1312         samr_io_r_query_useraliases("", &r_u, rdata, 0);
1313
1314         if (rid != NULL)
1315         {
1316                 free(rid);
1317         }
1318
1319         DEBUG(5,("samr_query_useraliases: %d\n", __LINE__));
1320
1321 }
1322
1323 /*******************************************************************
1324  api_samr_query_useraliases
1325  ********************************************************************/
1326 static void api_samr_query_useraliases( uint16 vuid, prs_struct *data, prs_struct *rdata)
1327 {
1328         SAMR_Q_QUERY_USERALIASES q_u;
1329         samr_io_q_query_useraliases("", &q_u, data, 0);
1330         samr_reply_query_useraliases(&q_u, rdata);
1331 }
1332
1333 /*******************************************************************
1334  samr_reply_delete_dom_alias
1335  ********************************************************************/
1336 static void samr_reply_delete_dom_alias(SAMR_Q_DELETE_DOM_ALIAS *q_u,
1337                                 prs_struct *rdata)
1338 {
1339         uint32 status = 0;
1340
1341         DOM_SID alias_sid;
1342         uint32 alias_rid;
1343         fstring alias_sid_str;
1344
1345         SAMR_R_DELETE_DOM_ALIAS r_u;
1346
1347         DEBUG(5,("samr_delete_dom_alias: %d\n", __LINE__));
1348
1349         /* find the policy handle.  open a policy on it. */
1350         if (status == 0x0 && !get_lsa_policy_samr_sid(&q_u->alias_pol, &alias_sid))
1351         {
1352                 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1353         }
1354         else
1355         {
1356                 sid_to_string(alias_sid_str, &alias_sid     );
1357                 sid_split_rid(&alias_sid, &alias_rid);
1358         }
1359
1360         if (status == 0x0)
1361         {
1362                 DEBUG(10,("sid is %s\n", alias_sid_str));
1363
1364                 if (sid_equal(&alias_sid, &global_sam_sid))
1365                 {
1366                         DEBUG(10,("lookup on Domain SID\n"));
1367
1368                         become_root(True);
1369                         status = del_alias_entry(alias_rid) ? 0x0 : (0xC0000000 | NT_STATUS_NO_SUCH_ALIAS);
1370                         unbecome_root(True);
1371                 }
1372                 else
1373                 {
1374                         status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
1375                 }
1376         }
1377
1378         make_samr_r_delete_dom_alias(&r_u, status);
1379
1380         /* store the response in the SMB stream */
1381         samr_io_r_delete_dom_alias("", &r_u, rdata, 0);
1382 }
1383
1384 /*******************************************************************
1385  api_samr_delete_dom_alias
1386  ********************************************************************/
1387 static void api_samr_delete_dom_alias( uint16 vuid, prs_struct *data, prs_struct *rdata)
1388 {
1389         SAMR_Q_DELETE_DOM_ALIAS q_u;
1390         samr_io_q_delete_dom_alias("", &q_u, data, 0);
1391         samr_reply_delete_dom_alias(&q_u, rdata);
1392 }
1393
1394
1395 /*******************************************************************
1396  samr_reply_query_aliasmem
1397  ********************************************************************/
1398 static void samr_reply_query_aliasmem(SAMR_Q_QUERY_ALIASMEM *q_u,
1399                                 prs_struct *rdata)
1400 {
1401         uint32 status = 0;
1402
1403         LOCAL_GRP_MEMBER *mem_grp = NULL;
1404         DOM_SID2 *sid = NULL;
1405         int num_sids = 0;
1406         DOM_SID alias_sid;
1407         uint32 alias_rid;
1408         fstring alias_sid_str;
1409
1410         SAMR_R_QUERY_ALIASMEM r_u;
1411
1412         DEBUG(5,("samr_query_aliasmem: %d\n", __LINE__));
1413
1414         /* find the policy handle.  open a policy on it. */
1415         if (status == 0x0 && !get_lsa_policy_samr_sid(&q_u->alias_pol, &alias_sid))
1416         {
1417                 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1418         }
1419         else
1420         {
1421                 sid_to_string(alias_sid_str, &alias_sid     );
1422                 sid_split_rid(&alias_sid, &alias_rid);
1423         }
1424
1425         if (status == 0x0)
1426         {
1427                 DEBUG(10,("sid is %s\n", alias_sid_str));
1428
1429                 if (sid_equal(&alias_sid, &global_sid_S_1_5_20))
1430                 {
1431                         DEBUG(10,("lookup on S-1-5-20\n"));
1432
1433                         become_root(True);
1434                         status = getbuiltinrid(alias_rid, &mem_grp, &num_sids) != NULL ? 0x0 : 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
1435                         unbecome_root(True);
1436                 }
1437                 else if (sid_equal(&alias_sid, &global_sam_sid))
1438                 {
1439                         DEBUG(10,("lookup on Domain SID\n"));
1440
1441                         become_root(True);
1442                         status = getaliasrid(alias_rid, &mem_grp, &num_sids) != NULL ? 0x0 : 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
1443                         unbecome_root(True);
1444                 }
1445                 else
1446                 {
1447                         status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
1448                 }
1449         }
1450
1451         if (status == 0x0 && num_sids > 0)
1452         {
1453                 sid = malloc(num_sids * sizeof(DOM_SID));
1454                 if (mem_grp != NULL && sid != NULL)
1455                 {
1456                         int i;
1457                         for (i = 0; i < num_sids; i++)
1458                         {
1459                                 make_dom_sid2(&sid[i], &mem_grp[i].sid);
1460                         }
1461                         free(mem_grp);
1462                 }
1463         }
1464
1465         make_samr_r_query_aliasmem(&r_u, num_sids, sid, status);
1466
1467         /* store the response in the SMB stream */
1468         samr_io_r_query_aliasmem("", &r_u, rdata, 0);
1469
1470         if (sid != NULL)
1471         {
1472                 free(sid);
1473         }
1474
1475         DEBUG(5,("samr_query_aliasmem: %d\n", __LINE__));
1476
1477 }
1478
1479 /*******************************************************************
1480  api_samr_query_aliasmem
1481  ********************************************************************/
1482 static void api_samr_query_aliasmem( uint16 vuid, prs_struct *data, prs_struct *rdata)
1483 {
1484         SAMR_Q_QUERY_ALIASMEM q_u;
1485         samr_io_q_query_aliasmem("", &q_u, data, 0);
1486         samr_reply_query_aliasmem(&q_u, rdata);
1487 }
1488
1489 /*******************************************************************
1490  samr_reply_lookup_names
1491  ********************************************************************/
1492 static void samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
1493                                 prs_struct *rdata)
1494 {
1495         uint32 rid [MAX_SAM_ENTRIES];
1496         uint8  type[MAX_SAM_ENTRIES];
1497         uint32 status     = 0;
1498         int i;
1499         int num_rids = q_u->num_names1;
1500         DOM_SID pol_sid;
1501
1502         SAMR_R_LOOKUP_NAMES r_u;
1503
1504         DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1505
1506         if (status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &pol_sid))
1507         {
1508                 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
1509         }
1510
1511         if (num_rids > MAX_SAM_ENTRIES)
1512         {
1513                 num_rids = MAX_SAM_ENTRIES;
1514                 DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
1515         }
1516
1517         SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
1518
1519         for (i = 0; i < num_rids && status == 0; i++)
1520         {
1521                 DOM_SID sid;
1522                 fstring name;
1523                 unistr2_to_ascii(name, &q_u->uni_name[i], sizeof(name)-1);
1524
1525                 status = lookup_name(name, &sid, &(type[i]));
1526                 if (status == 0x0)
1527                 {
1528                         sid_split_rid(&sid, &rid[i]);
1529                 }
1530                 else
1531                 {
1532                         type[i] = SID_NAME_UNKNOWN;
1533                         rid [i] = 0xffffffff;
1534                 }
1535                 if (!sid_equal(&pol_sid, &sid))
1536                 {
1537                         rid [i] = 0xffffffff;
1538                         type[i] = SID_NAME_UNKNOWN;
1539                 }
1540         }
1541
1542         make_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
1543
1544         /* store the response in the SMB stream */
1545         samr_io_r_lookup_names("", &r_u, rdata, 0);
1546
1547         DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1548
1549 }
1550
1551 /*******************************************************************
1552  api_samr_lookup_names
1553  ********************************************************************/
1554 static void api_samr_lookup_names( uint16 vuid, prs_struct *data, prs_struct *rdata)
1555 {
1556         SAMR_Q_LOOKUP_NAMES q_u;
1557         samr_io_q_lookup_names("", &q_u, data, 0);
1558         samr_reply_lookup_names(&q_u, rdata);
1559 }
1560
1561 /*******************************************************************
1562  samr_reply_chgpasswd_user
1563  ********************************************************************/
1564 static void samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
1565                                 prs_struct *rdata)
1566 {
1567         SAMR_R_CHGPASSWD_USER r_u;
1568         uint32 status = 0x0;
1569         fstring user_name;
1570         fstring wks;
1571
1572         unistr2_to_ascii(user_name, &q_u->uni_user_name, sizeof(user_name)-1);
1573         unistr2_to_ascii(wks, &q_u->uni_dest_host, sizeof(wks)-1);
1574
1575         DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1576
1577         if (!pass_oem_change(user_name,
1578                              q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1579                              q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1580         {
1581                 status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
1582         }
1583
1584         make_samr_r_chgpasswd_user(&r_u, status);
1585
1586         /* store the response in the SMB stream */
1587         samr_io_r_chgpasswd_user("", &r_u, rdata, 0);
1588
1589         DEBUG(5,("samr_chgpasswd_user: %d\n", __LINE__));
1590 }
1591
1592 /*******************************************************************
1593  api_samr_chgpasswd_user
1594  ********************************************************************/
1595 static void api_samr_chgpasswd_user( uint16 vuid, prs_struct *data, prs_struct *rdata)
1596 {
1597         SAMR_Q_CHGPASSWD_USER q_u;
1598         samr_io_q_chgpasswd_user("", &q_u, data, 0);
1599         samr_reply_chgpasswd_user(&q_u, rdata);
1600 }
1601
1602
1603 /*******************************************************************
1604  samr_reply_unknown_38
1605  ********************************************************************/
1606 static void samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u,
1607                                 prs_struct *rdata)
1608 {
1609         SAMR_R_UNKNOWN_38 r_u;
1610
1611         DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1612
1613         make_samr_r_unknown_38(&r_u);
1614
1615         /* store the response in the SMB stream */
1616         samr_io_r_unknown_38("", &r_u, rdata, 0);
1617
1618         DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1619 }
1620
1621 /*******************************************************************
1622  api_samr_unknown_38
1623  ********************************************************************/
1624 static void api_samr_unknown_38( uint16 vuid, prs_struct *data, prs_struct *rdata)
1625 {
1626         SAMR_Q_UNKNOWN_38 q_u;
1627         samr_io_q_unknown_38("", &q_u, data, 0);
1628         samr_reply_unknown_38(&q_u, rdata);
1629 }
1630
1631
1632 /*******************************************************************
1633  samr_reply_lookup_rids
1634  ********************************************************************/
1635 static void samr_reply_lookup_rids(SAMR_Q_LOOKUP_RIDS *q_u,
1636                                 prs_struct *rdata)
1637 {
1638         fstring group_names[MAX_SAM_ENTRIES];
1639         uint8   group_attrs[MAX_SAM_ENTRIES];
1640         uint32 status     = 0;
1641         int num_rids = q_u->num_rids1;
1642         DOM_SID pol_sid;
1643
1644         SAMR_R_LOOKUP_RIDS r_u;
1645
1646         DEBUG(5,("samr_lookup_rids: %d\n", __LINE__));
1647
1648         /* find the policy handle.  open a policy on it. */
1649         if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1650         {
1651                 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1652         }
1653
1654         if (status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &pol_sid))
1655         {
1656                 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
1657         }
1658
1659         if (status == 0x0)
1660         {
1661                 int i;
1662                 if (num_rids > MAX_SAM_ENTRIES)
1663                 {
1664                         num_rids = MAX_SAM_ENTRIES;
1665                         DEBUG(5,("samr_lookup_rids: truncating entries to %d\n", num_rids));
1666                 }
1667
1668                 for (i = 0; i < num_rids && status == 0; i++)
1669                 {
1670                         DOM_SID sid;
1671                         sid_copy(&sid, &pol_sid);
1672                         sid_append_rid(&sid, q_u->rid[i]);
1673                         lookup_sid(&sid, group_names[i], &group_attrs[i]);
1674                 }
1675         }
1676
1677         make_samr_r_lookup_rids(&r_u, num_rids, group_names, group_attrs, status);
1678
1679         /* store the response in the SMB stream */
1680         samr_io_r_lookup_rids("", &r_u, rdata, 0);
1681
1682         DEBUG(5,("samr_lookup_rids: %d\n", __LINE__));
1683
1684 }
1685
1686 /*******************************************************************
1687  api_samr_lookup_rids
1688  ********************************************************************/
1689 static void api_samr_lookup_rids( uint16 vuid, prs_struct *data, prs_struct *rdata)
1690 {
1691         SAMR_Q_LOOKUP_RIDS q_u;
1692         samr_io_q_lookup_rids("", &q_u, data, 0);
1693         samr_reply_lookup_rids(&q_u, rdata);
1694 }
1695
1696
1697 /*******************************************************************
1698  samr_reply_open_user
1699  ********************************************************************/
1700 static void samr_reply_open_user(SAMR_Q_OPEN_USER *q_u,
1701                                 prs_struct *rdata,
1702                                 int status)
1703 {
1704         SAMR_R_OPEN_USER r_u;
1705         struct sam_passwd *sam_pass;
1706         BOOL pol_open = False;
1707
1708         /* set up the SAMR open_user response */
1709         bzero(r_u.user_pol.data, POL_HND_SIZE);
1710
1711         r_u.status = 0x0;
1712
1713         /* find the policy handle.  open a policy on it. */
1714         if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
1715         {
1716                 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1717         }
1718
1719         /* get a (unique) handle.  open a policy on it. */
1720         if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.user_pol))))
1721         {
1722                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1723         }
1724
1725         become_root(True);
1726         sam_pass = getsam21pwrid(q_u->user_rid);
1727         unbecome_root(True);
1728
1729         /* check that the RID exists in our domain. */
1730         if (r_u.status == 0x0 && sam_pass == NULL)
1731         {
1732                 r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1733         }
1734
1735         /* associate the RID with the (unique) handle. */
1736         if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.user_pol), q_u->user_rid))
1737         {
1738                 /* oh, whoops.  don't know what error message to return, here */
1739                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1740         }
1741
1742         if (r_u.status != 0 && pol_open)
1743         {
1744                 close_lsa_policy_hnd(&(r_u.user_pol));
1745         }
1746
1747         DEBUG(5,("samr_open_user: %d\n", __LINE__));
1748
1749         /* store the response in the SMB stream */
1750         samr_io_r_open_user("", &r_u, rdata, 0);
1751
1752         DEBUG(5,("samr_open_user: %d\n", __LINE__));
1753
1754 }
1755
1756 /*******************************************************************
1757  api_samr_open_user
1758  ********************************************************************/
1759 static void api_samr_open_user( uint16 vuid, prs_struct *data, prs_struct *rdata)
1760 {
1761         SAMR_Q_OPEN_USER q_u;
1762         samr_io_q_open_user("", &q_u, data, 0);
1763         samr_reply_open_user(&q_u, rdata, 0x0);
1764 }
1765
1766
1767 /*************************************************************************
1768  get_user_info_10
1769  *************************************************************************/
1770 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1771 {
1772         struct sam_passwd *sam_pass;
1773
1774         become_root(True);
1775         sam_pass = getsam21pwrid(user_rid);
1776         unbecome_root(True);
1777
1778         if (sam_pass == NULL)
1779         {
1780                 DEBUG(4,("User 0x%x not found\n", user_rid));
1781                 return False;
1782         }
1783
1784         DEBUG(3,("User:[%s]\n", sam_pass->nt_name));
1785
1786         make_sam_user_info10(id10, sam_pass->acct_ctrl); 
1787
1788         return True;
1789 }
1790
1791 /*************************************************************************
1792  get_user_info_21
1793  *************************************************************************/
1794 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1795 {
1796         struct sam_passwd *sam_pass;
1797         LOGON_HRS hrs;
1798         int i;
1799
1800         become_root(True);
1801         sam_pass = getsam21pwrid(user_rid);
1802         unbecome_root(True);
1803
1804         if (sam_pass == NULL)
1805         {
1806                 DEBUG(4,("User 0x%x not found\n", user_rid));
1807                 return False;
1808         }
1809
1810         DEBUG(3,("User:[%s]\n", sam_pass->nt_name));
1811
1812         /* create a LOGON_HRS structure */
1813         hrs.len = sam_pass->hours_len;
1814         SMB_ASSERT_ARRAY(hrs.hours, hrs.len);
1815         for (i = 0; i < hrs.len; i++)
1816         {
1817                 hrs.hours[i] = sam_pass->hours[i];
1818         }
1819
1820         make_sam_user_info21(id21,
1821
1822                            &sam_pass->logon_time,
1823                            &sam_pass->logoff_time,
1824                            &sam_pass->kickoff_time,
1825                            &sam_pass->pass_last_set_time,
1826                            &sam_pass->pass_can_change_time,
1827                            &sam_pass->pass_must_change_time,
1828
1829                            sam_pass->nt_name, /* user_name */
1830                            sam_pass->full_name, /* full_name */
1831                            sam_pass->home_dir, /* home_dir */
1832                            sam_pass->dir_drive, /* dir_drive */
1833                            sam_pass->logon_script, /* logon_script */
1834                            sam_pass->profile_path, /* profile_path */
1835                            sam_pass->acct_desc, /* description */
1836                            sam_pass->workstations, /* workstations user can log in from */
1837                            sam_pass->unknown_str, /* don't know, yet */
1838                            sam_pass->munged_dial, /* dialin info.  contains dialin path and tel no */
1839
1840                            sam_pass->user_rid, /* RID user_id */
1841                            sam_pass->group_rid, /* RID group_id */
1842                            sam_pass->acct_ctrl,
1843
1844                            sam_pass->unknown_3, /* unknown_3 */
1845                            sam_pass->logon_divs, /* divisions per week */
1846                            &hrs, /* logon hours */
1847                            sam_pass->unknown_5,
1848                            sam_pass->unknown_6);
1849
1850         return True;
1851 }
1852
1853 /*******************************************************************
1854  samr_reply_query_userinfo
1855  ********************************************************************/
1856 static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
1857                                 prs_struct *rdata)
1858 {
1859         SAMR_R_QUERY_USERINFO r_u;
1860 #if 0
1861         SAM_USER_INFO_11 id11;
1862 #endif
1863         SAM_USER_INFO_10 id10;
1864         SAM_USER_INFO_21 id21;
1865         void *info = NULL;
1866
1867         uint32 status = 0x0;
1868         uint32 rid = 0x0;
1869
1870         DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1871
1872         /* search for the handle */
1873         if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1874         {
1875                 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1876         }
1877
1878         /* find the user's rid */
1879         if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1880         {
1881                 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
1882         }
1883
1884         DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
1885
1886         /* ok!  user info levels (there are lots: see MSDEV help), off we go... */
1887         if (status == 0x0)
1888         {
1889                 switch (q_u->switch_value)
1890                 {
1891                         case 0x10:
1892                         {
1893                                 info = (void*)&id10;
1894                                 status = get_user_info_10(&id10, rid) ? 0 : (0xC0000000 | NT_STATUS_NO_SUCH_USER);
1895                                 break;
1896                         }
1897 #if 0
1898 /* whoops - got this wrong.  i think.  or don't understand what's happening. */
1899                         case 0x11:
1900                         {
1901                                 NTTIME expire;
1902                                 info = (void*)&id11;
1903                                 
1904                                 expire.low  = 0xffffffff;
1905                                 expire.high = 0x7fffffff;
1906
1907                                 make_sam_user_info11(&id11, &expire, "BROOKFIELDS$", 0x03ef, 0x201, 0x0080);
1908
1909                                 break;
1910                         }
1911 #endif
1912                         case 21:
1913                         {
1914                                 info = (void*)&id21;
1915                                 status = get_user_info_21(&id21, rid) ? 0 : (0xC0000000 | NT_STATUS_NO_SUCH_USER);
1916                                 break;
1917                         }
1918
1919                         default:
1920                         {
1921                                 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
1922
1923                                 break;
1924                         }
1925                 }
1926         }
1927
1928         make_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
1929
1930         /* store the response in the SMB stream */
1931         samr_io_r_query_userinfo("", &r_u, rdata, 0);
1932
1933         DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1934
1935 }
1936
1937 /*******************************************************************
1938  api_samr_query_userinfo
1939  ********************************************************************/
1940 static void api_samr_query_userinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
1941 {
1942         SAMR_Q_QUERY_USERINFO q_u;
1943         samr_io_q_query_userinfo("", &q_u, data, 0);
1944         samr_reply_query_userinfo(&q_u, rdata);
1945 }
1946
1947
1948 /*******************************************************************
1949  samr_reply_query_usergroups
1950  ********************************************************************/
1951 static void samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
1952                                 prs_struct *rdata)
1953 {
1954         SAMR_R_QUERY_USERGROUPS r_u;
1955         uint32 status = 0x0;
1956
1957         struct sam_passwd *sam_pass;
1958         DOM_GID *gids = NULL;
1959         int num_groups = 0;
1960         uint32 rid;
1961
1962         DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1963
1964         /* find the policy handle.  open a policy on it. */
1965         if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1966         {
1967                 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1968         }
1969
1970         /* find the user's rid */
1971         if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1972         {
1973                 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
1974         }
1975
1976         if (status == 0x0)
1977         {
1978                 become_root(True);
1979                 sam_pass = getsam21pwrid(rid);
1980                 unbecome_root(True);
1981
1982                 if (sam_pass == NULL)
1983                 {
1984                         status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1985                 }
1986         }
1987
1988         if (status == 0x0)
1989         {
1990                 DOMAIN_GRP *mem_grp = NULL;
1991
1992                 become_root(True);
1993                 getusergroupsntnam(sam_pass->nt_name, &mem_grp, &num_groups);
1994                 unbecome_root(True);
1995
1996                 gids = NULL;
1997                 num_groups = make_dom_gids(mem_grp, num_groups, &gids);
1998
1999                 if (mem_grp != NULL)
2000                 {
2001                         free(mem_grp);
2002                 }
2003         }
2004
2005         /* construct the response.  lkclXXXX: gids are not copied! */
2006         make_samr_r_query_usergroups(&r_u, num_groups, gids, status);
2007
2008         /* store the response in the SMB stream */
2009         samr_io_r_query_usergroups("", &r_u, rdata, 0);
2010
2011         if (gids)
2012         {
2013                 free((char *)gids);
2014         }
2015
2016         DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
2017
2018 }
2019
2020 /*******************************************************************
2021  api_samr_query_usergroups
2022  ********************************************************************/
2023 static void api_samr_query_usergroups( uint16 vuid, prs_struct *data, prs_struct *rdata)
2024 {
2025         SAMR_Q_QUERY_USERGROUPS q_u;
2026         samr_io_q_query_usergroups("", &q_u, data, 0);
2027         samr_reply_query_usergroups(&q_u, rdata);
2028 }
2029
2030
2031 /*******************************************************************
2032  opens a samr alias by rid, returns a policy handle.
2033  ********************************************************************/
2034 static uint32 open_samr_alias(DOM_SID *sid, POLICY_HND *alias_pol,
2035                                 uint32 alias_rid)
2036 {
2037         BOOL pol_open = False;
2038         uint32 status = 0x0;
2039
2040         /* get a (unique) handle.  open a policy on it. */
2041         if (status == 0x0 && !(pol_open = open_lsa_policy_hnd(alias_pol)))
2042         {
2043                 status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2044         }
2045
2046         DEBUG(0,("TODO: verify that the alias rid exists\n"));
2047
2048         /* associate a RID with the (unique) handle. */
2049         if (status == 0x0 && !set_lsa_policy_samr_rid(alias_pol, alias_rid))
2050         {
2051                 /* oh, whoops.  don't know what error message to return, here */
2052                 status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2053         }
2054
2055         sid_append_rid(sid, alias_rid);
2056
2057         /* associate an alias SID with the (unique) handle. */
2058         if (status == 0x0 && !set_lsa_policy_samr_sid(alias_pol, sid))
2059         {
2060                 /* oh, whoops.  don't know what error message to return, here */
2061                 status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2062         }
2063
2064         if (status != 0 && pol_open)
2065         {
2066                 close_lsa_policy_hnd(alias_pol);
2067         }
2068
2069         return status;
2070 }
2071
2072 /*******************************************************************
2073  samr_reply_create_dom_alias
2074  ********************************************************************/
2075 static void samr_reply_create_dom_alias(SAMR_Q_CREATE_DOM_ALIAS *q_u,
2076                                 prs_struct *rdata)
2077 {
2078         SAMR_R_CREATE_DOM_ALIAS r_u;
2079         DOM_SID dom_sid;
2080         LOCAL_GRP grp;
2081         POLICY_HND alias_pol;
2082         uint32 status = 0x0;
2083
2084         bzero(&alias_pol, sizeof(alias_pol));
2085
2086         DEBUG(5,("samr_create_dom_alias: %d\n", __LINE__));
2087
2088         /* find the policy handle.  open a policy on it. */
2089         if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->dom_pol)) == -1))
2090         {
2091                 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
2092         }
2093
2094         /* find the domain sid */
2095         if (status == 0x0 && !get_lsa_policy_samr_sid(&q_u->dom_pol, &dom_sid))
2096         {
2097                 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
2098         }
2099
2100         if (!sid_equal(&dom_sid, &global_sam_sid))
2101         {
2102                 status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
2103         }
2104
2105         if (status == 0x0)
2106         {
2107                 unistr2_to_ascii(grp.name, &q_u->uni_acct_desc, sizeof(grp.name)-1);
2108                 fstrcpy(grp.comment, "");
2109                 grp.rid = 0xffffffff;
2110
2111                 become_root(True);
2112                 status = add_alias_entry(&grp) ? 0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
2113                 unbecome_root(True);
2114         }
2115
2116         if (status == 0x0)
2117         {
2118                 status = open_samr_alias(&dom_sid, &alias_pol, grp.rid);
2119         }
2120
2121         /* construct the response. */
2122         make_samr_r_create_dom_alias(&r_u, &alias_pol, grp.rid, status);
2123
2124         /* store the response in the SMB stream */
2125         samr_io_r_create_dom_alias("", &r_u, rdata, 0);
2126
2127         DEBUG(5,("samr_create_dom_alias: %d\n", __LINE__));
2128
2129 }
2130
2131 /*******************************************************************
2132  api_samr_create_dom_alias
2133  ********************************************************************/
2134 static void api_samr_create_dom_alias( uint16 vuid, prs_struct *data, prs_struct *rdata)
2135 {
2136         SAMR_Q_CREATE_DOM_ALIAS q_u;
2137         samr_io_q_create_dom_alias("", &q_u, data, 0);
2138         samr_reply_create_dom_alias(&q_u, rdata);
2139 }
2140
2141
2142 /*******************************************************************
2143  opens a samr group by rid, returns a policy handle.
2144  ********************************************************************/
2145 static uint32 open_samr_group(DOM_SID *sid, POLICY_HND *group_pol,
2146                                 uint32 group_rid)
2147 {
2148         BOOL pol_open = False;
2149         uint32 status = 0x0;
2150
2151         /* get a (unique) handle.  open a policy on it. */
2152         if (status == 0x0 && !(pol_open = open_lsa_policy_hnd(group_pol)))
2153         {
2154                 status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2155         }
2156
2157         DEBUG(0,("TODO: verify that the group rid exists\n"));
2158
2159         /* associate a RID with the (unique) handle. */
2160         if (status == 0x0 && !set_lsa_policy_samr_rid(group_pol, group_rid))
2161         {
2162                 /* oh, whoops.  don't know what error message to return, here */
2163                 status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2164         }
2165
2166         sid_append_rid(sid, group_rid);
2167
2168         /* associate an group SID with the (unique) handle. */
2169         if (status == 0x0 && !set_lsa_policy_samr_sid(group_pol, sid))
2170         {
2171                 /* oh, whoops.  don't know what error message to return, here */
2172                 status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2173         }
2174
2175         if (status != 0 && pol_open)
2176         {
2177                 close_lsa_policy_hnd(group_pol);
2178         }
2179
2180         return status;
2181 }
2182
2183 /*******************************************************************
2184  samr_reply_create_dom_group
2185  ********************************************************************/
2186 static void samr_reply_create_dom_group(SAMR_Q_CREATE_DOM_GROUP *q_u,
2187                                 prs_struct *rdata)
2188 {
2189         SAMR_R_CREATE_DOM_GROUP r_u;
2190         DOM_SID dom_sid;
2191         DOMAIN_GRP grp;
2192         POLICY_HND group_pol;
2193         uint32 status = 0x0;
2194
2195         bzero(&group_pol, sizeof(group_pol));
2196
2197         DEBUG(5,("samr_create_dom_group: %d\n", __LINE__));
2198
2199         /* find the policy handle.  open a policy on it. */
2200         if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
2201         {
2202                 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
2203         }
2204
2205         /* find the domain sid */
2206         if (status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &dom_sid))
2207         {
2208                 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
2209         }
2210
2211         if (!sid_equal(&dom_sid, &global_sam_sid))
2212         {
2213                 status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
2214         }
2215
2216         if (status == 0x0)
2217         {
2218                 unistr2_to_ascii(grp.name, &q_u->uni_acct_desc, sizeof(grp.name)-1);
2219                 fstrcpy(grp.comment, "");
2220                 grp.rid = 0xffffffff;
2221                 grp.attr = 0x07;
2222
2223                 become_root(True);
2224                 status = add_group_entry(&grp) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
2225                 unbecome_root(True);
2226         }
2227
2228         if (status == 0x0)
2229         {
2230                 status = open_samr_group(&dom_sid, &group_pol, grp.rid);
2231         }
2232
2233         /* construct the response. */
2234         make_samr_r_create_dom_group(&r_u, &group_pol, grp.rid, status);
2235
2236         /* store the response in the SMB stream */
2237         samr_io_r_create_dom_group("", &r_u, rdata, 0);
2238
2239         DEBUG(5,("samr_create_dom_group: %d\n", __LINE__));
2240
2241 }
2242
2243 /*******************************************************************
2244  api_samr_create_dom_group
2245  ********************************************************************/
2246 static void api_samr_create_dom_group( uint16 vuid, prs_struct *data, prs_struct *rdata)
2247 {
2248         SAMR_Q_CREATE_DOM_GROUP q_u;
2249         samr_io_q_create_dom_group("", &q_u, data, 0);
2250         samr_reply_create_dom_group(&q_u, rdata);
2251 }
2252
2253
2254 /*******************************************************************
2255  samr_reply_query_dom_info
2256  ********************************************************************/
2257 static void samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
2258                                 prs_struct *rdata)
2259 {
2260         SAMR_R_QUERY_DOMAIN_INFO r_u;
2261         SAM_UNK_CTR ctr;
2262         uint16 switch_value = 0x0;
2263         uint32 status = 0x0;
2264
2265         ZERO_STRUCT(r_u);
2266         ZERO_STRUCT(ctr);
2267
2268         r_u.ctr = &ctr;
2269
2270         DEBUG(5,("samr_reply_query_dom_info: %d\n", __LINE__));
2271
2272         /* find the policy handle.  open a policy on it. */
2273         if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
2274         {
2275                 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
2276                 DEBUG(5,("samr_reply_query_dom_info: invalid handle\n"));
2277         }
2278
2279         if (status == 0x0)
2280         {
2281                 switch (q_u->switch_value)
2282                 {
2283                         case 0x06:
2284                         {
2285                                 switch_value = 0x6;
2286                                 make_unk_info6(&ctr.info.inf6);
2287
2288                                 break;
2289                         }
2290                         case 0x07:
2291                         {
2292                                 switch_value = 0x7;
2293                                 make_unk_info7(&ctr.info.inf7);
2294
2295                                 break;
2296                         }
2297                         case 0x02:
2298                         {
2299                                 switch_value = 0x2;
2300                                 make_unk_info2(&ctr.info.inf2, global_sam_name, global_myname);
2301
2302                                 break;
2303                         }
2304                         default:
2305                         {
2306                                 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
2307                                 break;
2308                         }
2309                 }
2310         }
2311
2312         make_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
2313
2314         /* store the response in the SMB stream */
2315         samr_io_r_query_dom_info("", &r_u, rdata, 0);
2316
2317         DEBUG(5,("samr_query_dom_info: %d\n", __LINE__));
2318
2319 }
2320
2321 /*******************************************************************
2322  api_samr_query_dom_info
2323  ********************************************************************/
2324 static void api_samr_query_dom_info( uint16 vuid, prs_struct *data, prs_struct *rdata)
2325 {
2326         SAMR_Q_QUERY_DOMAIN_INFO q_e;
2327         samr_io_q_query_dom_info("", &q_e, data, 0);
2328         samr_reply_query_dom_info(&q_e, rdata);
2329 }
2330
2331
2332
2333 /*******************************************************************
2334  samr_reply_unknown_32
2335  ********************************************************************/
2336 static void samr_reply_unknown_32(SAMR_Q_UNKNOWN_32 *q_u,
2337                                 prs_struct *rdata,
2338                                 int status)
2339 {
2340         int i;
2341         SAMR_R_UNKNOWN_32 r_u;
2342
2343         /* set up the SAMR unknown_32 response */
2344         bzero(r_u.pol.data, POL_HND_SIZE);
2345         if (status == 0)
2346         {
2347                 for (i = 4; i < POL_HND_SIZE; i++)
2348                 {
2349                         r_u.pol.data[i] = i+1;
2350                 }
2351         }
2352
2353         make_dom_rid4(&(r_u.rid4), 0x0030, 0, 0);
2354         r_u.status    = status;
2355
2356         DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
2357
2358         /* store the response in the SMB stream */
2359         samr_io_r_unknown_32("", &r_u, rdata, 0);
2360
2361         DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
2362
2363 }
2364
2365 /*******************************************************************
2366  api_samr_unknown_32
2367  ********************************************************************/
2368 static void api_samr_unknown_32( uint16 vuid, prs_struct *data, prs_struct *rdata)
2369 {
2370         uint32 status = 0;
2371         struct sam_passwd *sam_pass;
2372         fstring mach_acct;
2373
2374         SAMR_Q_UNKNOWN_32 q_u;
2375
2376         /* grab the samr unknown 32 */
2377         samr_io_q_unknown_32("", &q_u, data, 0);
2378
2379         /* find the machine account: tell the caller if it exists.
2380            lkclXXXX i have *no* idea if this is a problem or not
2381            or even if you are supposed to construct a different
2382            reply if the account already exists...
2383          */
2384
2385         unistr2_to_ascii(mach_acct, &q_u.uni_mach_acct, sizeof(mach_acct)-1);
2386
2387         become_root(True);
2388         sam_pass = getsam21pwntnam(mach_acct);
2389         unbecome_root(True);
2390
2391         if (sam_pass != NULL)
2392         {
2393                 /* machine account exists: say so */
2394                 status = 0xC0000000 | NT_STATUS_USER_EXISTS;
2395         }
2396         else
2397         {
2398                 /* this could cause trouble... */
2399                 DEBUG(0,("trouble!\n"));
2400                 status = 0;
2401         }
2402
2403         /* construct reply. */
2404         samr_reply_unknown_32(&q_u, rdata, status);
2405 }
2406
2407
2408 /*******************************************************************
2409  samr_reply_connect_anon
2410  ********************************************************************/
2411 static void samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u,
2412                                 prs_struct *rdata)
2413 {
2414         SAMR_R_CONNECT_ANON r_u;
2415         BOOL pol_open = False;
2416
2417         /* set up the SAMR connect_anon response */
2418
2419         r_u.status = 0x0;
2420         /* get a (unique) handle.  open a policy on it. */
2421         if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
2422         {
2423                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2424         }
2425
2426         /* associate the domain SID with the (unique) handle. */
2427         if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
2428         {
2429                 /* oh, whoops.  don't know what error message to return, here */
2430                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2431         }
2432
2433         if (r_u.status != 0 && pol_open)
2434         {
2435                 close_lsa_policy_hnd(&(r_u.connect_pol));
2436         }
2437
2438         DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
2439
2440         /* store the response in the SMB stream */
2441         samr_io_r_connect_anon("", &r_u, rdata, 0);
2442
2443         DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
2444
2445 }
2446
2447 /*******************************************************************
2448  api_samr_connect_anon
2449  ********************************************************************/
2450 static void api_samr_connect_anon( uint16 vuid, prs_struct *data, prs_struct *rdata)
2451 {
2452         SAMR_Q_CONNECT_ANON q_u;
2453         samr_io_q_connect_anon("", &q_u, data, 0);
2454         samr_reply_connect_anon(&q_u, rdata);
2455 }
2456
2457 /*******************************************************************
2458  samr_reply_connect
2459  ********************************************************************/
2460 static void samr_reply_connect(SAMR_Q_CONNECT *q_u,
2461                                 prs_struct *rdata)
2462 {
2463         SAMR_R_CONNECT r_u;
2464         BOOL pol_open = False;
2465
2466         /* set up the SAMR connect response */
2467
2468         r_u.status = 0x0;
2469         /* get a (unique) handle.  open a policy on it. */
2470         if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
2471         {
2472                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2473         }
2474
2475         /* associate the domain SID with the (unique) handle. */
2476         if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
2477         {
2478                 /* oh, whoops.  don't know what error message to return, here */
2479                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2480         }
2481
2482         if (r_u.status != 0 && pol_open)
2483         {
2484                 close_lsa_policy_hnd(&(r_u.connect_pol));
2485         }
2486
2487         DEBUG(5,("samr_connect: %d\n", __LINE__));
2488
2489         /* store the response in the SMB stream */
2490         samr_io_r_connect("", &r_u, rdata, 0);
2491
2492         DEBUG(5,("samr_connect: %d\n", __LINE__));
2493
2494 }
2495
2496 /*******************************************************************
2497  api_samr_connect
2498  ********************************************************************/
2499 static void api_samr_connect( uint16 vuid, prs_struct *data, prs_struct *rdata)
2500 {
2501         SAMR_Q_CONNECT q_u;
2502         samr_io_q_connect("", &q_u, data, 0);
2503         samr_reply_connect(&q_u, rdata);
2504 }
2505
2506 /*******************************************************************
2507  samr_reply_open_alias
2508  ********************************************************************/
2509 static void samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
2510                                 prs_struct *rdata)
2511 {
2512         SAMR_R_OPEN_ALIAS r_u;
2513         DOM_SID sid;
2514         BOOL pol_open = False;
2515
2516         /* set up the SAMR open_alias response */
2517
2518         r_u.status = 0x0;
2519         if (r_u.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->dom_pol, &sid))
2520         {
2521                 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
2522         }
2523
2524         /* get a (unique) handle.  open a policy on it. */
2525         if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.pol))))
2526         {
2527                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2528         }
2529
2530         DEBUG(0,("TODO: verify that the alias rid exists\n"));
2531
2532         /* associate a RID with the (unique) handle. */
2533         if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.pol), q_u->rid_alias))
2534         {
2535                 /* oh, whoops.  don't know what error message to return, here */
2536                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2537         }
2538
2539         sid_append_rid(&sid, q_u->rid_alias);
2540
2541         /* associate an alias SID with the (unique) handle. */
2542         if (r_u.status == 0x0 && !set_lsa_policy_samr_sid(&(r_u.pol), &sid))
2543         {
2544                 /* oh, whoops.  don't know what error message to return, here */
2545                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2546         }
2547
2548         if (r_u.status != 0 && pol_open)
2549         {
2550                 close_lsa_policy_hnd(&(r_u.pol));
2551         }
2552
2553         DEBUG(5,("samr_open_alias: %d\n", __LINE__));
2554
2555         /* store the response in the SMB stream */
2556         samr_io_r_open_alias("", &r_u, rdata, 0);
2557
2558         DEBUG(5,("samr_open_alias: %d\n", __LINE__));
2559
2560 }
2561
2562 /*******************************************************************
2563  api_samr_open_alias
2564  ********************************************************************/
2565 static void api_samr_open_alias( uint16 vuid, prs_struct *data, prs_struct *rdata)
2566                                 
2567 {
2568         SAMR_Q_OPEN_ALIAS q_u;
2569         samr_io_q_open_alias("", &q_u, data, 0);
2570         samr_reply_open_alias(&q_u, rdata);
2571 }
2572
2573 /*******************************************************************
2574  samr_reply_open_group
2575  ********************************************************************/
2576 static void samr_reply_open_group(SAMR_Q_OPEN_GROUP *q_u,
2577                                 prs_struct *rdata)
2578 {
2579         SAMR_R_OPEN_GROUP r_u;
2580         DOM_SID sid;
2581
2582         DEBUG(5,("samr_open_group: %d\n", __LINE__));
2583
2584         r_u.status = 0x0;
2585
2586         /* find the domain sid associated with the policy handle */
2587         if (r_u.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->domain_pol, &sid))
2588         {
2589                 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
2590         }
2591
2592         if (r_u.status == 0x0 && !sid_equal(&sid, &global_sam_sid))
2593         {
2594                 r_u.status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
2595         }
2596
2597         if (r_u.status == 0x0)
2598         {
2599                 r_u.status = open_samr_group(&sid, &r_u.pol, q_u->rid_group);
2600         }
2601
2602         /* store the response in the SMB stream */
2603         samr_io_r_open_group("", &r_u, rdata, 0);
2604
2605         DEBUG(5,("samr_open_group: %d\n", __LINE__));
2606
2607 }
2608
2609 /*******************************************************************
2610  api_samr_open_group
2611  ********************************************************************/
2612 static void api_samr_open_group( uint16 vuid, prs_struct *data, prs_struct *rdata)
2613                                 
2614 {
2615         SAMR_Q_OPEN_GROUP q_u;
2616         samr_io_q_open_group("", &q_u, data, 0);
2617         samr_reply_open_group(&q_u, rdata);
2618 }
2619
2620 /*******************************************************************
2621  samr_reply_lookup_domain
2622  ********************************************************************/
2623 static void samr_reply_lookup_domain(SAMR_Q_LOOKUP_DOMAIN *q_u,
2624                                 prs_struct *rdata)
2625 {
2626         SAMR_R_LOOKUP_DOMAIN r_u;
2627         fstring domain;
2628
2629         DEBUG(5,("samr_lookup_domain: %d\n", __LINE__));
2630
2631         r_u.ptr_sid = 0;
2632         r_u.status = 0x0;
2633
2634         /* find the connection policy handle */
2635         if (find_lsa_policy_by_hnd(&(q_u->connect_pol)) == -1)
2636         {
2637                 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
2638         }
2639
2640         if (r_u.status == 0x0)
2641         {
2642                 unistr2_to_ascii(domain, &(q_u->uni_domain), sizeof(domain));
2643                 DEBUG(5, ("Lookup Domain: %s\n", domain));
2644
2645                 /* check it's one of ours */
2646                 if (strequal(domain, global_sam_name))
2647                 {
2648                         make_dom_sid2(&(r_u.dom_sid), &global_sam_sid);
2649                         r_u.ptr_sid = 1;
2650                 }
2651                 else if (strequal(domain, "BUILTIN"))
2652                 {
2653                         make_dom_sid2(&(r_u.dom_sid), &global_sid_S_1_5_20);
2654                         r_u.ptr_sid = 1;
2655                 }
2656                 else
2657                 {
2658                         r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_DOMAIN;
2659                 }
2660         }
2661
2662         /* store the response in the SMB stream */
2663         samr_io_r_lookup_domain("", &r_u, rdata, 0);
2664
2665         DEBUG(5,("samr_lookup_domain: %d\n", __LINE__));
2666 }
2667
2668 /*******************************************************************
2669  api_samr_lookup_domain
2670  ********************************************************************/
2671 static void api_samr_lookup_domain( uint16 vuid, prs_struct *data, prs_struct *rdata)
2672 {
2673         SAMR_Q_LOOKUP_DOMAIN q_u;
2674         samr_io_q_lookup_domain("", &q_u, data, 0);
2675         samr_reply_lookup_domain(&q_u, rdata);
2676 }
2677
2678 /*******************************************************************
2679  array of \PIPE\samr operations
2680  ********************************************************************/
2681 static struct api_struct api_samr_cmds [] =
2682 {
2683         { "SAMR_CLOSE_HND"        , SAMR_CLOSE_HND        , api_samr_close_hnd        },
2684         { "SAMR_CONNECT"          , SAMR_CONNECT          , api_samr_connect          },
2685         { "SAMR_CONNECT_ANON"     , SAMR_CONNECT_ANON     , api_samr_connect_anon     },
2686         { "SAMR_ENUM_DOM_USERS"   , SAMR_ENUM_DOM_USERS   , api_samr_enum_dom_users   },
2687         { "SAMR_ENUM_DOM_GROUPS"  , SAMR_ENUM_DOM_GROUPS  , api_samr_enum_dom_groups  },
2688         { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
2689         { "SAMR_QUERY_USERALIASES", SAMR_QUERY_USERALIASES, api_samr_query_useraliases},
2690         { "SAMR_QUERY_ALIASMEM"   , SAMR_QUERY_ALIASMEM   , api_samr_query_aliasmem   },
2691         { "SAMR_QUERY_GROUPMEM"   , SAMR_QUERY_GROUPMEM   , api_samr_query_groupmem   },
2692         { "SAMR_ADD_ALIASMEM"     , SAMR_ADD_ALIASMEM     , api_samr_add_aliasmem     },
2693         { "SAMR_DEL_ALIASMEM"     , SAMR_DEL_ALIASMEM     , api_samr_del_aliasmem     },
2694         { "SAMR_ADD_GROUPMEM"     , SAMR_ADD_GROUPMEM     , api_samr_add_groupmem     },
2695         { "SAMR_DEL_GROUPMEM"     , SAMR_DEL_GROUPMEM     , api_samr_del_groupmem     },
2696         { "SAMR_DELETE_DOM_GROUP" , SAMR_DELETE_DOM_GROUP , api_samr_delete_dom_group },
2697         { "SAMR_DELETE_DOM_ALIAS" , SAMR_DELETE_DOM_ALIAS , api_samr_delete_dom_alias },
2698         { "SAMR_CREATE_DOM_GROUP" , SAMR_CREATE_DOM_GROUP , api_samr_create_dom_group },
2699         { "SAMR_CREATE_DOM_ALIAS" , SAMR_CREATE_DOM_ALIAS , api_samr_create_dom_alias },
2700         { "SAMR_LOOKUP_NAMES"     , SAMR_LOOKUP_NAMES     , api_samr_lookup_names     },
2701         { "SAMR_OPEN_USER"        , SAMR_OPEN_USER        , api_samr_open_user        },
2702         { "SAMR_QUERY_USERINFO"   , SAMR_QUERY_USERINFO   , api_samr_query_userinfo   },
2703         { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info   },
2704         { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
2705         { "SAMR_QUERY_DISPINFO"   , SAMR_QUERY_DISPINFO   , api_samr_query_dispinfo   },
2706         { "SAMR_QUERY_DISPINFO3"  , SAMR_QUERY_DISPINFO3  , api_samr_query_dispinfo   },
2707         { "SAMR_QUERY_DISPINFO4"  , SAMR_QUERY_DISPINFO4  , api_samr_query_dispinfo   },
2708         { "SAMR_QUERY_ALIASINFO"  , SAMR_QUERY_ALIASINFO  , api_samr_query_aliasinfo  },
2709         { "SAMR_QUERY_GROUPINFO"  , SAMR_QUERY_GROUPINFO  , api_samr_query_groupinfo  },
2710         { "SAMR_0x32"             , SAMR_UNKNOWN_32       , api_samr_unknown_32       },
2711         { "SAMR_LOOKUP_RIDS"      , SAMR_LOOKUP_RIDS      , api_samr_lookup_rids      },
2712         { "SAMR_UNKNOWN_38"       , SAMR_UNKNOWN_38       , api_samr_unknown_38       },
2713         { "SAMR_CHGPASSWD_USER"   , SAMR_CHGPASSWD_USER   , api_samr_chgpasswd_user   },
2714         { "SAMR_OPEN_ALIAS"       , SAMR_OPEN_ALIAS       , api_samr_open_alias       },
2715         { "SAMR_OPEN_GROUP"       , SAMR_OPEN_GROUP       , api_samr_open_group       },
2716         { "SAMR_OPEN_DOMAIN"      , SAMR_OPEN_DOMAIN      , api_samr_open_domain      },
2717         { "SAMR_LOOKUP_DOMAIN"    , SAMR_LOOKUP_DOMAIN    , api_samr_lookup_domain    },
2718         { "SAMR_UNKNOWN_3"        , SAMR_UNKNOWN_3        , api_samr_unknown_3        },
2719         { "SAMR_UNKNOWN_2C"       , SAMR_UNKNOWN_2C       , api_samr_unknown_2c       },
2720         { NULL                    , 0                     , NULL                      }
2721 };
2722
2723 /*******************************************************************
2724  receives a samr pipe and responds.
2725  ********************************************************************/
2726 BOOL api_samr_rpc(pipes_struct *p, prs_struct *data)
2727 {
2728     return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds, data);
2729 }
2730