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