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