I introduced a bug in my last commits. Hopefully nobody noticed :-)
[sfrench/samba-autobuild/.git] / source3 / 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         if (!local_password_change(mach_acct, local_flags, NULL, err_str, sizeof(err_str), msg_str, sizeof(msg_str))) {
1874                 DEBUG(0, ("%s\n", err_str));
1875                 close_lsa_policy_hnd(user_pol);
1876                 return NT_STATUS_ACCESS_DENIED;
1877         }
1878
1879         become_root();
1880         sam_pass = getsam21pwnam(mach_acct);
1881         unbecome_root();
1882         if (sam_pass == NULL) {
1883                 /* account doesn't exist: say so */
1884                 close_lsa_policy_hnd(user_pol);
1885                 return NT_STATUS_ACCESS_DENIED;
1886         }
1887
1888         /* Get the domain SID stored in the domain policy */
1889         if(!get_lsa_policy_samr_sid(&dom_pol, &sid)) {
1890                 close_lsa_policy_hnd(user_pol);
1891                 return NT_STATUS_INVALID_HANDLE;
1892         }
1893
1894         /* append the user's RID to it */
1895         if(!sid_append_rid(&sid, sam_pass->user_rid)) {
1896                 close_lsa_policy_hnd(user_pol);
1897                 return NT_STATUS_NO_SUCH_USER;
1898         }
1899
1900         /* associate the RID with the (unique) handle. */
1901         if (!set_lsa_policy_samr_sid(user_pol, &sid)) {
1902                 /* oh, whoops.  don't know what error message to return, here */
1903                 close_lsa_policy_hnd(user_pol);
1904                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1905         }
1906
1907         *unknown0=0x000703ff;
1908         *user_rid=sam_pass->user_rid;
1909
1910         return NT_STATUS_NO_PROBLEMO;
1911 }
1912
1913 /*******************************************************************
1914  api_samr_create_user
1915  ********************************************************************/
1916 static BOOL api_samr_create_user(pipes_struct *p)
1917 {
1918         prs_struct *data = &p->in_data.data;
1919         prs_struct *rdata = &p->out_data.rdata;
1920
1921         SAMR_Q_CREATE_USER q_u;
1922         SAMR_R_CREATE_USER r_u;
1923
1924         ZERO_STRUCT(q_u);
1925         ZERO_STRUCT(r_u);
1926
1927         /* grab the samr create user */
1928         if (!samr_io_q_create_user("", &q_u, data, 0)) {
1929                 DEBUG(0,("api_samr_create_user: Unable to unmarshall SAMR_Q_CREATE_USER.\n"));
1930                 return False;
1931         }
1932
1933         r_u.status=_api_samr_create_user(q_u.pol, q_u.uni_mach_acct, q_u.acb_info, q_u.access_mask,
1934                                         &r_u.pol, &r_u.unknown_0, &r_u.user_rid);
1935
1936         /* store the response in the SMB stream */
1937         if(!samr_io_r_create_user("", &r_u, rdata, 0)) {
1938                 DEBUG(0,("api_samr_create_user: Unable to marshall SAMR_R_CREATE_USER.\n"));
1939                 return False;
1940         }
1941
1942         return True;
1943 }
1944
1945
1946 /*******************************************************************
1947  samr_reply_connect_anon
1948  ********************************************************************/
1949 static BOOL samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u, prs_struct *rdata)
1950 {
1951         SAMR_R_CONNECT_ANON r_u;
1952         BOOL pol_open = False;
1953
1954         /* set up the SAMR connect_anon response */
1955
1956         r_u.status = 0x0;
1957         /* get a (unique) handle.  open a policy on it. */
1958         if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1959         {
1960                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1961         }
1962
1963         /* associate the domain SID with the (unique) handle. */
1964         if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1965         {
1966                 /* oh, whoops.  don't know what error message to return, here */
1967                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1968         }
1969
1970         if (r_u.status != 0 && pol_open)
1971         {
1972                 close_lsa_policy_hnd(&(r_u.connect_pol));
1973         }
1974
1975         DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1976
1977         /* store the response in the SMB stream */
1978         if(!samr_io_r_connect_anon("", &r_u, rdata, 0))
1979                 return False;
1980
1981         DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1982
1983         return True;
1984 }
1985
1986 /*******************************************************************
1987  api_samr_connect_anon
1988  ********************************************************************/
1989 static BOOL api_samr_connect_anon(pipes_struct *p)
1990 {
1991         SAMR_Q_CONNECT_ANON q_u;
1992         prs_struct *data = &p->in_data.data;
1993         prs_struct *rdata = &p->out_data.rdata;
1994
1995         /* grab the samr open policy */
1996         if(!samr_io_q_connect_anon("", &q_u, data, 0))
1997                 return False;
1998
1999         /* construct reply.  always indicate success */
2000         if(!samr_reply_connect_anon(&q_u, rdata))
2001                 return False;
2002
2003         return True;
2004 }
2005
2006 /*******************************************************************
2007  samr_reply_connect
2008  ********************************************************************/
2009 static BOOL samr_reply_connect(SAMR_Q_CONNECT *q_u, prs_struct *rdata)
2010 {
2011         SAMR_R_CONNECT r_u;
2012         BOOL pol_open = False;
2013
2014         /* set up the SAMR connect response */
2015
2016         r_u.status = 0x0;
2017         /* get a (unique) handle.  open a policy on it. */
2018         if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
2019         {
2020                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2021         }
2022
2023         /* associate the domain SID with the (unique) handle. */
2024         if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
2025         {
2026                 /* oh, whoops.  don't know what error message to return, here */
2027                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2028         }
2029
2030         if (r_u.status != 0 && pol_open)
2031         {
2032                 close_lsa_policy_hnd(&(r_u.connect_pol));
2033         }
2034
2035         DEBUG(5,("samr_connect: %d\n", __LINE__));
2036
2037         /* store the response in the SMB stream */
2038         if(!samr_io_r_connect("", &r_u, rdata, 0))
2039                 return False;
2040
2041         DEBUG(5,("samr_connect: %d\n", __LINE__));
2042
2043         return True;
2044 }
2045
2046 /*******************************************************************
2047  api_samr_connect
2048  ********************************************************************/
2049 static BOOL api_samr_connect(pipes_struct *p)
2050 {
2051         SAMR_Q_CONNECT q_u;
2052         prs_struct *data = &p->in_data.data;
2053         prs_struct *rdata = &p->out_data.rdata;
2054
2055         /* grab the samr open policy */
2056         if(!samr_io_q_connect("", &q_u, data, 0))
2057                 return False;
2058
2059         /* construct reply.  always indicate success */
2060         if(!samr_reply_connect(&q_u, rdata))
2061                 return False;
2062
2063         return True;
2064 }
2065
2066   
2067 /**********************************************************************
2068  api_samr_lookup_domain
2069  **********************************************************************/
2070 static BOOL api_samr_lookup_domain(pipes_struct *p)
2071 {
2072         SAMR_Q_LOOKUP_DOMAIN q_u;
2073         SAMR_R_LOOKUP_DOMAIN r_u;
2074         prs_struct *data = &p->in_data.data;
2075         prs_struct *rdata = &p->out_data.rdata;
2076   
2077         ZERO_STRUCT(q_u);
2078         ZERO_STRUCT(r_u);
2079
2080         if(!samr_io_q_lookup_domain("", &q_u, data, 0)) {
2081                 DEBUG(0,("api_samr_lookup_domain: Unable to unmarshall SAMR_Q_LOOKUP_DOMAIN.\n"));
2082                 return False;
2083         }
2084         
2085         r_u.status = 0x0;
2086
2087         if (find_lsa_policy_by_hnd(&q_u.connect_pol) == -1){
2088                 r_u.status = NT_STATUS_INVALID_HANDLE;
2089                 DEBUG(5,("api_samr_lookup_domain: invalid handle\n"));
2090         }
2091   
2092         /* assume the domain name sent is our global_myname and 
2093            send global_sam_sid */
2094         init_samr_r_lookup_domain(&r_u, &global_sam_sid, r_u.status);
2095   
2096         if(!samr_io_r_lookup_domain("", &r_u, rdata, 0)){
2097                 DEBUG(0,("api_samr_lookup_domain: Unable to marshall SAMR_R_LOOKUP_DOMAIN.\n"));
2098                 return False;
2099         }
2100         
2101         return True;
2102 }
2103
2104 /**********************************************************************
2105  api_samr_enum_domains
2106  **********************************************************************/
2107 static BOOL api_samr_enum_domains(pipes_struct *p)
2108 {
2109         SAMR_Q_ENUM_DOMAINS q_u;
2110         SAMR_R_ENUM_DOMAINS r_u;
2111         prs_struct *data = &p->in_data.data;
2112         prs_struct *rdata = &p->out_data.rdata;
2113   
2114         fstring dom[2];
2115
2116         ZERO_STRUCT(q_u);
2117         ZERO_STRUCT(r_u);
2118
2119         fstrcpy(dom[0],global_myname);
2120         fstrcpy(dom[1],"Builtin");
2121
2122         if(!samr_io_q_enum_domains("", &q_u, data, 0)) {
2123                 DEBUG(0,("api_samr_enum_domains: Unable to unmarshall SAMR_Q_ENUM_DOMAINS.\n"));
2124                 return False;
2125         }
2126
2127         r_u.status = NT_STATUS_NO_PROBLEMO;
2128    
2129         init_samr_r_enum_domains(&r_u, q_u.start_idx, dom, 2); 
2130
2131         if(!samr_io_r_enum_domains("", &r_u, rdata, 0)) {
2132                 DEBUG(0,("api_samr_enum_domains: Unable to marshall SAMR_R_ENUM_DOMAINS.\n"));
2133                 free(r_u.sam);
2134                 free(r_u.uni_dom_name);
2135                 return False;
2136         }
2137
2138         free(r_u.sam);
2139         free(r_u.uni_dom_name);
2140         
2141         return True;
2142 }
2143
2144
2145 /*******************************************************************
2146  api_samr_open_alias
2147  ********************************************************************/
2148 static uint32 _api_samr_open_alias(POLICY_HND domain_pol, uint32 alias_rid, POLICY_HND *alias_pol)
2149 {
2150         DOM_SID sid;
2151         
2152         /* get the domain policy. */
2153         if (find_lsa_policy_by_hnd(&domain_pol) == -1)
2154                 return NT_STATUS_INVALID_HANDLE;
2155
2156         /* get a (unique) handle.  open a policy on it. */
2157         if (!open_lsa_policy_hnd(alias_pol))
2158                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2159
2160         /* Get the domain SID stored in the domain policy */
2161         if(!get_lsa_policy_samr_sid(&domain_pol, &sid)) {
2162                 close_lsa_policy_hnd(alias_pol);
2163                 return NT_STATUS_INVALID_HANDLE;
2164         }
2165
2166         /* append the alias' RID to it */
2167         if(!sid_append_rid(&sid, alias_rid)) {
2168                 close_lsa_policy_hnd(alias_pol);
2169                 return NT_STATUS_NO_SUCH_USER;
2170         }
2171
2172         /* associate a RID with the (unique) handle. */
2173         if (!set_lsa_policy_samr_sid(alias_pol, &sid)) {
2174                 /* oh, whoops.  don't know what error message to return, here */
2175                 close_lsa_policy_hnd(alias_pol);
2176                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2177         }
2178
2179         return NT_STATUS_NO_PROBLEMO;
2180 }
2181
2182 /*******************************************************************
2183  api_samr_open_alias
2184  ********************************************************************/
2185 static BOOL api_samr_open_alias(pipes_struct *p)
2186 {
2187         SAMR_Q_OPEN_ALIAS q_u;
2188         SAMR_R_OPEN_ALIAS r_u;
2189         prs_struct *data = &p->in_data.data;
2190         prs_struct *rdata = &p->out_data.rdata;
2191
2192         ZERO_STRUCT(q_u);
2193         ZERO_STRUCT(r_u);
2194
2195         /* grab the samr open policy */
2196         if(!samr_io_q_open_alias("", &q_u, data, 0)) {
2197                 DEBUG(0,("api_samr_open_alias: Unable to unmarshall SAMR_Q_OPEN_ALIAS.\n"));
2198                 return False;
2199         }
2200
2201         r_u.status=_api_samr_open_alias(q_u.dom_pol, q_u.rid_alias, &r_u.pol);
2202
2203         /* store the response in the SMB stream */
2204         if(!samr_io_r_open_alias("", &r_u, rdata, 0)) {
2205                 DEBUG(0,("api_samr_open_alias: Unable to marshall SAMR_R_OPEN_ALIAS.\n"));
2206                 return False;
2207         }
2208         
2209         return True;
2210 }
2211
2212 /*******************************************************************
2213  set_user_info_10
2214  ********************************************************************/
2215 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid)
2216 {
2217         struct sam_passwd *pwd = getsam21pwrid(rid);
2218         struct sam_passwd new_pwd;
2219
2220         if (id10 == NULL) {
2221                 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2222                 return False;
2223         }
2224
2225         if (pwd == NULL)
2226                 return False;
2227
2228         copy_sam_passwd(&new_pwd, pwd);
2229
2230         new_pwd.acct_ctrl = id10->acb_info;
2231
2232         if(!mod_sam21pwd_entry(&new_pwd, True))
2233                 return False;
2234
2235         return True;
2236 }
2237
2238 /*******************************************************************
2239  set_user_info_12
2240  ********************************************************************/
2241 static BOOL set_user_info_12(const SAM_USER_INFO_12 *id12, uint32 rid)
2242 {
2243         struct sam_passwd *pwd = getsam21pwrid(rid);
2244         struct sam_passwd new_pwd;
2245         static uchar nt_hash[16];
2246         static uchar lm_hash[16];
2247
2248         if (pwd == NULL)
2249                 return False;
2250
2251         if (id12 == NULL) {
2252                 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2253                 return False;
2254         }
2255
2256         pdb_init_sam(&new_pwd);
2257         copy_sam_passwd(&new_pwd, pwd);
2258
2259         memcpy(nt_hash, id12->nt_pwd, sizeof(nt_hash));
2260         memcpy(lm_hash, id12->lm_pwd, sizeof(lm_hash));
2261
2262         new_pwd.smb_passwd = lm_hash;
2263         new_pwd.smb_nt_passwd = nt_hash;
2264
2265         if(!mod_sam21pwd_entry(&new_pwd, True))
2266                 return False;
2267
2268         return True;
2269 }
2270
2271 /*******************************************************************
2272  set_user_info_21
2273  ********************************************************************/
2274 static BOOL set_user_info_21(SAM_USER_INFO_21 * id21, uint32 rid)
2275 {
2276         struct sam_passwd *pwd = getsam21pwrid(rid);
2277         struct sam_passwd new_pwd;
2278         static uchar nt_hash[16];
2279         static uchar lm_hash[16];
2280
2281         if (id21 == NULL) {
2282                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2283                 return False;
2284         }
2285
2286         if (pwd == NULL)
2287                 return False;
2288
2289         pdb_init_sam(&new_pwd);
2290         copy_sam_passwd(&new_pwd, pwd);
2291         copy_id21_to_sam_passwd(&new_pwd, id21);
2292
2293         if (pwd->smb_nt_passwd != NULL) {
2294                 memcpy(nt_hash, pwd->smb_nt_passwd, 16);
2295                 new_pwd.smb_nt_passwd = nt_hash;
2296         } else
2297                 new_pwd.smb_nt_passwd = NULL;
2298
2299         if (pwd->smb_nt_passwd != NULL) {
2300                 memcpy(lm_hash, pwd->smb_passwd, 16);
2301                 new_pwd.smb_passwd = lm_hash;
2302         } else
2303                 new_pwd.smb_passwd = NULL;
2304
2305         if(!mod_sam21pwd_entry(&new_pwd, True))
2306                 return False;
2307
2308         return True;
2309 }
2310
2311 /*******************************************************************
2312  set_user_info_23
2313  ********************************************************************/
2314 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
2315 {
2316         struct sam_passwd *pwd = getsam21pwrid(rid);
2317         struct sam_passwd new_pwd;
2318         static uchar nt_hash[16];
2319         static uchar lm_hash[16];
2320         pstring buf;
2321         uint32 len;
2322
2323         if (id23 == NULL) {
2324                 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2325                 return False;
2326         }
2327
2328         if (pwd == NULL)
2329                 return False;
2330
2331         pdb_init_sam(&new_pwd);
2332         copy_sam_passwd(&new_pwd, pwd);
2333         copy_id23_to_sam_passwd(&new_pwd, id23);
2334
2335         if (!decode_pw_buffer(id23->pass, buf, 256, &len))
2336                 return False;
2337
2338         nt_lm_owf_gen(buf, nt_hash, lm_hash);
2339
2340         new_pwd.smb_passwd = lm_hash;
2341         new_pwd.smb_nt_passwd = nt_hash;
2342
2343         if(!mod_sam21pwd_entry(&new_pwd, True))
2344                 return False;
2345         
2346         return True;
2347 }
2348
2349 /*******************************************************************
2350  set_user_info_24
2351  ********************************************************************/
2352 static BOOL set_user_info_24(const SAM_USER_INFO_24 *id24, uint32 rid)
2353 {
2354         struct sam_passwd *pwd = getsam21pwrid(rid);
2355         struct sam_passwd new_pwd;
2356         static uchar nt_hash[16];
2357         static uchar lm_hash[16];
2358         uint32 len;
2359         pstring buf;
2360
2361         if (pwd == NULL)
2362                 return False;
2363
2364         pdb_init_sam(&new_pwd);
2365         copy_sam_passwd(&new_pwd, pwd);
2366
2367         if (!decode_pw_buffer(id24->pass, buf, 256, &len))
2368                 return False;
2369
2370         nt_lm_owf_gen(buf, nt_hash, lm_hash);
2371
2372         new_pwd.smb_passwd = lm_hash;
2373         new_pwd.smb_nt_passwd = nt_hash;
2374
2375         if(!mod_sam21pwd_entry(&new_pwd, True))
2376                 return False;
2377
2378         return True;
2379 }
2380
2381 /*******************************************************************
2382  samr_reply_set_userinfo
2383  ********************************************************************/
2384 static uint32 _samr_set_userinfo(POLICY_HND *pol, uint16 switch_value, SAM_USERINFO_CTR *ctr, uint16 vuid)
2385 {
2386         uint32 rid = 0x0;
2387         DOM_SID sid;
2388         user_struct *vuser = NULL;
2389
2390         DEBUG(5, ("samr_reply_set_userinfo: %d\n", __LINE__));
2391
2392         /* search for the handle */
2393         if (find_lsa_policy_by_hnd(pol) == -1)
2394                 return NT_STATUS_INVALID_HANDLE;
2395
2396         if ((vuser = get_valid_user_struct(vuid)) == NULL)
2397                 return NT_STATUS_INVALID_HANDLE;
2398
2399         /* find the policy handle.  open a policy on it. */
2400         if (!get_lsa_policy_samr_sid(pol, &sid))
2401                 return NT_STATUS_INVALID_HANDLE;
2402
2403         sid_split_rid(&sid, &rid);
2404
2405         DEBUG(5, ("samr_reply_set_userinfo: rid:0x%x, level:%d\n", rid, switch_value));
2406
2407         if (ctr == NULL) {
2408                 DEBUG(5, ("samr_reply_set_userinfo: NULL info level\n"));
2409                 return NT_STATUS_INVALID_INFO_CLASS;
2410         }
2411
2412         /* ok!  user info levels (lots: see MSDEV help), off we go... */
2413         switch (switch_value) {
2414                 case 0x12:
2415                         if (!set_user_info_12(ctr->info.id12, rid))
2416                                 return NT_STATUS_ACCESS_DENIED;
2417                         break;
2418
2419                 case 24:
2420                         SamOEMhash(ctr->info.id24->pass, vuser->dc.sess_key, True);
2421                         if (!set_user_info_24(ctr->info.id24, rid))
2422                                 return NT_STATUS_ACCESS_DENIED;
2423                         break;
2424
2425                 case 23:
2426                 DEBUG(5, ("samr_reply_set_userinfo: sess key:[%s]\n", credstr(vuser->dc.sess_key)));
2427                         SamOEMhash(ctr->info.id23->pass, vuser->dc.sess_key, 1);
2428                         if (!set_user_info_23(ctr->info.id23, rid))
2429                                 return NT_STATUS_ACCESS_DENIED;
2430                         break;
2431
2432                 default:
2433                         return NT_STATUS_INVALID_INFO_CLASS;
2434         }
2435
2436         return NT_STATUS_NOPROBLEMO;
2437 }
2438
2439 /*******************************************************************
2440  api_samr_set_userinfo
2441  ********************************************************************/
2442 static BOOL api_samr_set_userinfo(pipes_struct *p)
2443 {
2444         SAMR_Q_SET_USERINFO q_u;
2445         SAMR_R_SET_USERINFO r_u;
2446
2447         prs_struct *data = &p->in_data.data;
2448         prs_struct *rdata = &p->out_data.rdata;
2449
2450         SAM_USERINFO_CTR ctr;
2451
2452         ZERO_STRUCT(q_u);
2453         ZERO_STRUCT(r_u);
2454
2455         q_u.ctr = &ctr;
2456
2457         if (!samr_io_q_set_userinfo("", &q_u, data, 0)) {
2458                 DEBUG(0,("api_samr_set_userinfo: Unable to unmarshall SAMR_Q_SET_USERINFO.\n"));
2459                 return False;
2460         }
2461
2462         r_u.status = _samr_set_userinfo(&q_u.pol, q_u.switch_value, &ctr, p->vuid);
2463
2464         free_samr_q_set_userinfo(&q_u);
2465         
2466         if(!samr_io_r_set_userinfo("", &r_u, rdata, 0)) {
2467                 DEBUG(0,("api_samr_set_userinfo: Unable to marshall SAMR_R_SET_USERINFO.\n"));
2468                 return False;
2469         }
2470
2471         return True;
2472 }
2473
2474 /*******************************************************************
2475  samr_reply_set_userinfo2
2476  ********************************************************************/
2477 static uint32 _samr_set_userinfo2(POLICY_HND *pol, uint16 switch_value, SAM_USERINFO_CTR *ctr)
2478 {
2479         DOM_SID sid;
2480         uint32 rid = 0x0;
2481
2482         DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
2483
2484         /* search for the handle */
2485         if (find_lsa_policy_by_hnd(pol) == -1)
2486                 return NT_STATUS_INVALID_HANDLE;
2487
2488         /* find the policy handle.  open a policy on it. */
2489         if (!get_lsa_policy_samr_sid(pol, &sid))
2490                 return NT_STATUS_INVALID_HANDLE;
2491
2492         sid_split_rid(&sid, &rid);
2493
2494         DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid));
2495
2496         if (ctr == NULL) {
2497                 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
2498                 return NT_STATUS_INVALID_INFO_CLASS;
2499         }
2500
2501         ctr->switch_value = switch_value;
2502
2503         /* ok!  user info levels (lots: see MSDEV help), off we go... */
2504         switch (switch_value) {
2505                 case 21:
2506                         if (!set_user_info_21(ctr->info.id21, rid))
2507                                 return NT_STATUS_ACCESS_DENIED;
2508                         break;
2509                 case 16:
2510                         if (!set_user_info_10(ctr->info.id10, rid))
2511                                 return NT_STATUS_ACCESS_DENIED;
2512                         break;
2513                 default:
2514                         return NT_STATUS_INVALID_INFO_CLASS;
2515         }
2516
2517         return NT_STATUS_NOPROBLEMO;
2518 }
2519
2520 /*******************************************************************
2521  api_samr_set_userinfo2
2522  ********************************************************************/
2523 static BOOL api_samr_set_userinfo2(pipes_struct *p)
2524 {
2525         SAMR_Q_SET_USERINFO2 q_u;
2526         SAMR_R_SET_USERINFO2 r_u;
2527         SAM_USERINFO_CTR ctr;
2528
2529         prs_struct *data = &p->in_data.data;
2530         prs_struct *rdata = &p->out_data.rdata;
2531
2532         ZERO_STRUCT(q_u);
2533         ZERO_STRUCT(r_u);
2534
2535         q_u.ctr = &ctr;
2536
2537         if (!samr_io_q_set_userinfo2("", &q_u, data, 0)) {
2538                 DEBUG(0,("api_samr_set_userinfo2: Unable to unmarshall SAMR_Q_SET_USERINFO2.\n"));
2539                 return False;
2540         }
2541
2542         r_u.status = _samr_set_userinfo2(&q_u.pol, q_u.switch_value, &ctr);
2543
2544         free_samr_q_set_userinfo2(&q_u);
2545
2546         if(!samr_io_r_set_userinfo2("", &r_u, rdata, 0)) {
2547                 DEBUG(0,("api_samr_set_userinfo2: Unable to marshall SAMR_R_SET_USERINFO2.\n"));
2548                 return False;
2549         }
2550
2551         return True;
2552 }
2553
2554
2555 /*******************************************************************
2556  array of \PIPE\samr operations
2557  ********************************************************************/
2558 static struct api_struct api_samr_cmds [] =
2559 {
2560         { "SAMR_CLOSE_HND"        , SAMR_CLOSE_HND        , api_samr_close_hnd        },
2561         { "SAMR_CONNECT"          , SAMR_CONNECT          , api_samr_connect          },
2562         { "SAMR_CONNECT_ANON"     , SAMR_CONNECT_ANON     , api_samr_connect_anon     },
2563         { "SAMR_ENUM_DOM_USERS"   , SAMR_ENUM_DOM_USERS   , api_samr_enum_dom_users   },
2564         { "SAMR_ENUM_DOM_GROUPS"  , SAMR_ENUM_DOM_GROUPS  , api_samr_enum_dom_groups  },
2565         { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
2566         { "SAMR_LOOKUP_IDS"       , SAMR_LOOKUP_IDS       , api_samr_lookup_ids       },
2567         { "SAMR_LOOKUP_NAMES"     , SAMR_LOOKUP_NAMES     , api_samr_lookup_names     },
2568         { "SAMR_OPEN_USER"        , SAMR_OPEN_USER        , api_samr_open_user        },
2569         { "SAMR_QUERY_USERINFO"   , SAMR_QUERY_USERINFO   , api_samr_query_userinfo   },
2570         { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info   },
2571         { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
2572         { "SAMR_QUERY_DISPINFO"   , SAMR_QUERY_DISPINFO   , api_samr_query_dispinfo   },
2573         { "SAMR_QUERY_ALIASINFO"  , SAMR_QUERY_ALIASINFO  , api_samr_query_aliasinfo  },
2574         { "SAMR_CREATE_USER"      , SAMR_CREATE_USER      , api_samr_create_user      },
2575         { "SAMR_LOOKUP_RIDS"      , SAMR_LOOKUP_RIDS      , api_samr_lookup_rids      },
2576         { "SAMR_UNKNOWN_38"       , SAMR_UNKNOWN_38       , api_samr_unknown_38       },
2577         { "SAMR_CHGPASSWD_USER"   , SAMR_CHGPASSWD_USER   , api_samr_chgpasswd_user   },
2578         { "SAMR_OPEN_ALIAS"       , SAMR_OPEN_ALIAS       , api_samr_open_alias       },
2579         { "SAMR_OPEN_DOMAIN"      , SAMR_OPEN_DOMAIN      , api_samr_open_domain      },
2580         { "SAMR_UNKNOWN_3"        , SAMR_UNKNOWN_3        , api_samr_unknown_3        },
2581         { "SAMR_UNKNOWN_2C"       , SAMR_UNKNOWN_2C       , api_samr_unknown_2c       },
2582         { "SAMR_LOOKUP_DOMAIN"    , SAMR_LOOKUP_DOMAIN    , api_samr_lookup_domain    },
2583         { "SAMR_ENUM_DOMAINS"     , SAMR_ENUM_DOMAINS     , api_samr_enum_domains     },
2584         { "SAMR_SET_USERINFO"     , SAMR_SET_USERINFO     , api_samr_set_userinfo     },
2585         { "SAMR_SET_USERINFO2"    , SAMR_SET_USERINFO2    , api_samr_set_userinfo2    },
2586         { NULL                    , 0                     , NULL                      }
2587 };
2588
2589 /*******************************************************************
2590  receives a samr pipe and responds.
2591  ********************************************************************/
2592 BOOL api_samr_rpc(pipes_struct *p)
2593 {
2594         return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds);
2595 }
2596 #undef OLD_NTDOMAIN