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