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