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