lib/system.c: Fix for pw caching.
[nivanova/samba-autobuild/.git] / source3 / rpc_server / srv_samr.c
1 #define OLD_NTDOMAIN 1
2 /* 
3  *  Unix SMB/Netbios implementation.
4  *  Version 1.9.
5  *  RPC Pipe client / server routines
6  *  Copyright (C) Andrew Tridgell              1992-1997,
7  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
8  *  Copyright (C) Paul Ashton                       1997.
9  *  Copyright (C) Hewlett-Packard Company           1999.
10  *  
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *  
16  *  This program is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *  
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  */
25
26 #include "includes.h"
27
28 extern int DEBUGLEVEL;
29
30 extern fstring global_myworkgroup;
31 extern pstring global_myname;
32 extern DOM_SID global_sam_sid;
33
34 extern rid_name domain_group_rids[];
35 extern rid_name domain_alias_rids[];
36 extern rid_name builtin_alias_rids[];
37
38 /*******************************************************************
39   This next function should be replaced with something that
40   dynamically returns the correct user info..... JRA.
41  ********************************************************************/
42
43 static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, 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                 sys_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 = sys_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                 sys_endpwent();
252                 sys_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 = sys_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 = sys_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->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 && 
1999             !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), 
2000                                             q_u->access_mask))
2001         {
2002                 /* oh, whoops.  don't know what error message to return, here */
2003                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2004         }
2005
2006         if (r_u.status != 0 && pol_open)
2007         {
2008                 close_lsa_policy_hnd(&(r_u.connect_pol));
2009         }
2010
2011         DEBUG(5,("samr_connect: %d\n", __LINE__));
2012
2013         /* store the response in the SMB stream */
2014         if(!samr_io_r_connect("", &r_u, rdata, 0))
2015                 return False;
2016
2017         DEBUG(5,("samr_connect: %d\n", __LINE__));
2018
2019         return True;
2020 }
2021
2022 /*******************************************************************
2023  api_samr_connect
2024  ********************************************************************/
2025 static BOOL api_samr_connect(pipes_struct *p)
2026 {
2027         SAMR_Q_CONNECT q_u;
2028         prs_struct *data = &p->in_data.data;
2029         prs_struct *rdata = &p->out_data.rdata;
2030
2031         /* grab the samr open policy */
2032         if(!samr_io_q_connect("", &q_u, data, 0))
2033                 return False;
2034
2035         /* construct reply.  always indicate success */
2036         if(!samr_reply_connect(&q_u, rdata))
2037                 return False;
2038
2039         return True;
2040 }
2041
2042   
2043 /**********************************************************************
2044  api_samr_lookup_domain
2045  **********************************************************************/
2046 static BOOL api_samr_lookup_domain(pipes_struct *p)
2047 {
2048         SAMR_Q_LOOKUP_DOMAIN q_u;
2049         SAMR_R_LOOKUP_DOMAIN r_u;
2050         prs_struct *data = &p->in_data.data;
2051         prs_struct *rdata = &p->out_data.rdata;
2052   
2053         ZERO_STRUCT(q_u);
2054         ZERO_STRUCT(r_u);
2055
2056         if(!samr_io_q_lookup_domain("", &q_u, data, 0)) {
2057                 DEBUG(0,("api_samr_lookup_domain: Unable to unmarshall SAMR_Q_LOOKUP_DOMAIN.\n"));
2058                 return False;
2059         }
2060         
2061         r_u.status = 0x0;
2062
2063         if (find_lsa_policy_by_hnd(&q_u.connect_pol) == -1){
2064                 r_u.status = NT_STATUS_INVALID_HANDLE;
2065                 DEBUG(5,("api_samr_lookup_domain: invalid handle\n"));
2066         }
2067   
2068         /* assume the domain name sent is our global_myname and 
2069            send global_sam_sid */
2070         init_samr_r_lookup_domain(&r_u, &global_sam_sid, r_u.status);
2071   
2072         if(!samr_io_r_lookup_domain("", &r_u, rdata, 0)){
2073                 DEBUG(0,("api_samr_lookup_domain: Unable to marshall SAMR_R_LOOKUP_DOMAIN.\n"));
2074                 return False;
2075         }
2076         
2077         return True;
2078 }
2079
2080 /**********************************************************************
2081  api_samr_enum_domains
2082  **********************************************************************/
2083 static BOOL api_samr_enum_domains(pipes_struct *p)
2084 {
2085         SAMR_Q_ENUM_DOMAINS q_u;
2086         SAMR_R_ENUM_DOMAINS r_u;
2087         prs_struct *data = &p->in_data.data;
2088         prs_struct *rdata = &p->out_data.rdata;
2089   
2090         fstring dom[2];
2091
2092         ZERO_STRUCT(q_u);
2093         ZERO_STRUCT(r_u);
2094
2095         fstrcpy(dom[0],global_myworkgroup);
2096         fstrcpy(dom[1],"Builtin");
2097
2098         if(!samr_io_q_enum_domains("", &q_u, data, 0)) {
2099                 DEBUG(0,("api_samr_enum_domains: Unable to unmarshall SAMR_Q_ENUM_DOMAINS.\n"));
2100                 return False;
2101         }
2102
2103         r_u.status = NT_STATUS_NO_PROBLEMO;
2104    
2105         init_samr_r_enum_domains(&r_u, q_u.start_idx, dom, 2); 
2106
2107         if(!samr_io_r_enum_domains("", &r_u, rdata, 0)) {
2108                 DEBUG(0,("api_samr_enum_domains: Unable to marshall SAMR_R_ENUM_DOMAINS.\n"));
2109                 free(r_u.sam);
2110                 free(r_u.uni_dom_name);
2111                 return False;
2112         }
2113
2114         free(r_u.sam);
2115         free(r_u.uni_dom_name);
2116         
2117         return True;
2118 }
2119
2120
2121 /*******************************************************************
2122  api_samr_open_alias
2123  ********************************************************************/
2124 static uint32 _api_samr_open_alias(POLICY_HND domain_pol, uint32 alias_rid, POLICY_HND *alias_pol)
2125 {
2126         DOM_SID sid;
2127         
2128         /* get the domain policy. */
2129         if (find_lsa_policy_by_hnd(&domain_pol) == -1)
2130                 return NT_STATUS_INVALID_HANDLE;
2131
2132         /* get a (unique) handle.  open a policy on it. */
2133         if (!open_lsa_policy_hnd(alias_pol))
2134                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2135
2136         /* Get the domain SID stored in the domain policy */
2137         if(!get_lsa_policy_samr_sid(&domain_pol, &sid)) {
2138                 close_lsa_policy_hnd(alias_pol);
2139                 return NT_STATUS_INVALID_HANDLE;
2140         }
2141
2142         /* append the alias' RID to it */
2143         if(!sid_append_rid(&sid, alias_rid)) {
2144                 close_lsa_policy_hnd(alias_pol);
2145                 return NT_STATUS_NO_SUCH_USER;
2146         }
2147
2148         /* associate a RID with the (unique) handle. */
2149         if (!set_lsa_policy_samr_sid(alias_pol, &sid)) {
2150                 /* oh, whoops.  don't know what error message to return, here */
2151                 close_lsa_policy_hnd(alias_pol);
2152                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2153         }
2154
2155         return NT_STATUS_NO_PROBLEMO;
2156 }
2157
2158 /*******************************************************************
2159  api_samr_open_alias
2160  ********************************************************************/
2161 static BOOL api_samr_open_alias(pipes_struct *p)
2162 {
2163         SAMR_Q_OPEN_ALIAS q_u;
2164         SAMR_R_OPEN_ALIAS r_u;
2165         prs_struct *data = &p->in_data.data;
2166         prs_struct *rdata = &p->out_data.rdata;
2167
2168         ZERO_STRUCT(q_u);
2169         ZERO_STRUCT(r_u);
2170
2171         /* grab the samr open policy */
2172         if(!samr_io_q_open_alias("", &q_u, data, 0)) {
2173                 DEBUG(0,("api_samr_open_alias: Unable to unmarshall SAMR_Q_OPEN_ALIAS.\n"));
2174                 return False;
2175         }
2176
2177         r_u.status=_api_samr_open_alias(q_u.dom_pol, q_u.rid_alias, &r_u.pol);
2178
2179         /* store the response in the SMB stream */
2180         if(!samr_io_r_open_alias("", &r_u, rdata, 0)) {
2181                 DEBUG(0,("api_samr_open_alias: Unable to marshall SAMR_R_OPEN_ALIAS.\n"));
2182                 return False;
2183         }
2184         
2185         return True;
2186 }
2187
2188 /*******************************************************************
2189  set_user_info_10
2190  ********************************************************************/
2191 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid)
2192 {
2193         SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2194
2195         if (id10 == NULL) {
2196                 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2197                 return False;
2198         }
2199
2200         if (pwd == NULL)
2201                 return False;
2202
2203         pdb_set_acct_ctrl(pwd, id10->acb_info);
2204
2205         if(!pdb_update_sam_account(pwd, True))
2206                 return False;
2207
2208         return True;
2209 }
2210
2211 /*******************************************************************
2212  set_user_info_12
2213  ********************************************************************/
2214 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, uint32 rid)
2215 {
2216         SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2217
2218         if (pwd == NULL)
2219                 return False;
2220
2221         if (id12 == NULL) {
2222                 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2223                 return False;
2224         }
2225
2226         pdb_set_lanman_passwd (pwd, id12->lm_pwd); 
2227         pdb_set_nt_passwd     (pwd, id12->nt_pwd); 
2228
2229         if(!pdb_update_sam_account(pwd, True))
2230                 return False;
2231
2232         return True;
2233 }
2234
2235 /*******************************************************************
2236  set_user_info_21
2237  ********************************************************************/
2238 static BOOL set_user_info_21 (SAM_USER_INFO_21 *id21, uint32 rid)
2239 {
2240         SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2241         SAM_ACCOUNT new_pwd;
2242
2243         if (id21 == NULL) {
2244                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2245                 return False;
2246         }
2247
2248         if (pwd == NULL)
2249                 return False;
2250
2251         /* we make a copy so that we can modify stuff */        
2252         copy_sam_passwd(&new_pwd, pwd);
2253         copy_id21_to_sam_passwd(&new_pwd, id21);
2254         
2255         /*
2256          * The funny part about the previous two calls is 
2257          * that pwd still has the password hashes from the 
2258          * passdb entry.  These have not been updated from
2259          * id21.  I don't know if they need to be set.    --jerry
2260          */
2261
2262         /* write the change out */
2263         if(!pdb_update_sam_account(&new_pwd, True))
2264                 return False;
2265         
2266         return True;
2267 }
2268
2269 /*******************************************************************
2270  set_user_info_23
2271  ********************************************************************/
2272 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
2273 {
2274         SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2275         SAM_ACCOUNT new_pwd;
2276         BYTE nt_hash[16];
2277         BYTE lm_hash[16];
2278         pstring buf;
2279         uint32 len;
2280
2281         if (id23 == NULL) {
2282                 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2283                 return False;
2284         }
2285
2286         if (pwd == NULL)
2287                 return False;
2288
2289         copy_sam_passwd(&new_pwd, pwd);
2290         copy_id23_to_sam_passwd(&new_pwd, id23);
2291
2292         if (!decode_pw_buffer((char*)id23->pass, buf, 256, &len))
2293                 return False;
2294
2295         nt_lm_owf_gen(buf, nt_hash, lm_hash);
2296
2297         pdb_set_lanman_passwd (&new_pwd, lm_hash);
2298         pdb_set_nt_passwd     (&new_pwd, nt_hash);
2299
2300         /* update the UNIX password */
2301         if (lp_unix_password_sync())
2302                 if(!chgpasswd(pdb_get_username(&new_pwd), "", buf, True))
2303                         return False;
2304
2305         memset(buf, 0, sizeof(buf));
2306
2307         if(!pdb_update_sam_account(&new_pwd, True))
2308                 return False;
2309         
2310         return True;
2311 }
2312
2313 /*******************************************************************
2314  set_user_info_24
2315  ********************************************************************/
2316 static BOOL set_user_info_24(const SAM_USER_INFO_24 *id24, uint32 rid)
2317 {
2318         SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2319         uchar nt_hash[16];
2320         uchar lm_hash[16];
2321         uint32 len;
2322         pstring buf;
2323
2324         if (pwd == NULL)
2325                 return False;
2326
2327         memset(buf, 0, sizeof(buf));
2328
2329         if (!decode_pw_buffer((char*)id24->pass, buf, 256, &len))
2330                 return False;
2331
2332         DEBUG(0,("set_user_info_24:nt_lm_owf_gen\n"));
2333
2334         nt_lm_owf_gen(buf, nt_hash, lm_hash);
2335
2336         pdb_set_lanman_passwd (pwd, lm_hash);
2337         pdb_set_nt_passwd     (pwd, nt_hash);
2338
2339         /* update the UNIX password */
2340         if (lp_unix_password_sync())
2341                 if(!chgpasswd(pdb_get_username(pwd), "", buf, True))
2342                         return False;
2343
2344         memset(buf, 0, sizeof(buf));
2345         
2346         DEBUG(0,("set_user_info_24: pdb_update_sam_account()\n"));
2347
2348         /* update the SAMBA password */
2349         if(!pdb_update_sam_account(pwd, True))
2350                 return False;
2351
2352         return True;
2353 }
2354
2355 /*******************************************************************
2356  samr_reply_set_userinfo
2357  ********************************************************************/
2358 static uint32 _samr_set_userinfo(POLICY_HND *pol, uint16 switch_value, 
2359                                  SAM_USERINFO_CTR *ctr, pipes_struct *p)
2360 {
2361         uint32 rid = 0x0;
2362         DOM_SID sid;
2363         struct current_user user;
2364         SAM_ACCOUNT *sam_pass;
2365         unsigned char sess_key[16];
2366
2367         DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2368
2369         if (p->ntlmssp_auth_validated) 
2370         {
2371                 memcpy(&user, &p->pipe_user, sizeof(user));
2372         } 
2373         else 
2374         {
2375                 extern struct current_user current_user;
2376                 memcpy(&user, &current_user, sizeof(user));
2377         }
2378
2379         /* search for the handle */
2380         if (find_lsa_policy_by_hnd(pol) == -1)
2381                 return NT_STATUS_INVALID_HANDLE;
2382
2383         /* find the policy handle.  open a policy on it. */
2384         if (!get_lsa_policy_samr_sid(pol, &sid))
2385                 return NT_STATUS_INVALID_HANDLE;
2386
2387         sid_split_rid(&sid, &rid);
2388
2389         DEBUG(5, ("_samr_set_userinfo: rid:0x%x, level:%d\n", rid, switch_value));
2390
2391         if (ctr == NULL) {
2392                 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2393                 return NT_STATUS_INVALID_INFO_CLASS;
2394         }
2395
2396
2397         /* 
2398          * We need the NT hash of the user who is changing the user's password.
2399          * This NT hash is used to generate a "user session key"
2400          * This "user session key" is in turn used to encrypt/decrypt the user's password.
2401          */
2402
2403         become_root();
2404         sam_pass = pdb_getsampwuid(user.uid);
2405         unbecome_root();
2406         if(sam_pass == NULL) {
2407                 DEBUG(0,("_samr_set_userinfo: Unable to get passdb entry for uid %u\n", 
2408                         (unsigned int)pdb_get_uid(sam_pass) ));
2409                 return NT_STATUS_ACCESS_DENIED;
2410         }
2411                 
2412         memset(sess_key, '\0', 16);
2413         mdfour(sess_key, pdb_get_nt_passwd(sam_pass), 16);
2414
2415         /* ok!  user info levels (lots: see MSDEV help), off we go... */
2416         switch (switch_value) {
2417                 case 0x12:
2418                         if (!set_user_info_12(ctr->info.id12, rid))
2419                                 return NT_STATUS_ACCESS_DENIED;
2420                         break;
2421
2422                 case 24:
2423                         SamOEMhash(ctr->info.id24->pass, sess_key, 1);
2424                         if (!set_user_info_24(ctr->info.id24, rid))
2425                                 return NT_STATUS_ACCESS_DENIED;
2426                         break;
2427
2428                 case 23:
2429                         SamOEMhash(ctr->info.id23->pass, sess_key, 1);
2430                         if (!set_user_info_23(ctr->info.id23, rid))
2431                                 return NT_STATUS_ACCESS_DENIED;
2432                         break;
2433
2434                 default:
2435                         return NT_STATUS_INVALID_INFO_CLASS;
2436         }
2437
2438         return NT_STATUS_NOPROBLEMO;
2439 }
2440
2441 /*******************************************************************
2442  api_samr_set_userinfo
2443  ********************************************************************/
2444 static BOOL api_samr_set_userinfo(pipes_struct *p)
2445 {
2446         SAMR_Q_SET_USERINFO q_u;
2447         SAMR_R_SET_USERINFO r_u;
2448
2449         prs_struct *data = &p->in_data.data;
2450         prs_struct *rdata = &p->out_data.rdata;
2451
2452         SAM_USERINFO_CTR ctr;
2453
2454         ZERO_STRUCT(q_u);
2455         ZERO_STRUCT(r_u);
2456
2457         q_u.ctr = &ctr;
2458
2459         if (!samr_io_q_set_userinfo("", &q_u, data, 0)) {
2460                 DEBUG(0,("api_samr_set_userinfo: Unable to unmarshall SAMR_Q_SET_USERINFO.\n"));
2461                 return False;
2462         }
2463
2464         r_u.status = _samr_set_userinfo(&q_u.pol, q_u.switch_value, &ctr, p);
2465
2466         free_samr_q_set_userinfo(&q_u);
2467         
2468         if(!samr_io_r_set_userinfo("", &r_u, rdata, 0)) {
2469                 DEBUG(0,("api_samr_set_userinfo: Unable to marshall SAMR_R_SET_USERINFO.\n"));
2470                 return False;
2471         }
2472
2473         return True;
2474 }
2475
2476 /*******************************************************************
2477  samr_reply_set_userinfo2
2478  ********************************************************************/
2479 static uint32 _samr_set_userinfo2(POLICY_HND *pol, uint16 switch_value, SAM_USERINFO_CTR *ctr)
2480 {
2481         DOM_SID sid;
2482         uint32 rid = 0x0;
2483
2484         DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
2485
2486         /* search for the handle */
2487         if (find_lsa_policy_by_hnd(pol) == -1)
2488                 return NT_STATUS_INVALID_HANDLE;
2489
2490         /* find the policy handle.  open a policy on it. */
2491         if (!get_lsa_policy_samr_sid(pol, &sid))
2492                 return NT_STATUS_INVALID_HANDLE;
2493
2494         sid_split_rid(&sid, &rid);
2495
2496         DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid));
2497
2498         if (ctr == NULL) {
2499                 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
2500                 return NT_STATUS_INVALID_INFO_CLASS;
2501         }
2502
2503         ctr->switch_value = switch_value;
2504
2505         /* ok!  user info levels (lots: see MSDEV help), off we go... */
2506         switch (switch_value) {
2507                 case 21:
2508                         if (!set_user_info_21(ctr->info.id21, rid))
2509                                 return NT_STATUS_ACCESS_DENIED;
2510                         break;
2511                 case 16:
2512                         if (!set_user_info_10(ctr->info.id10, rid))
2513                                 return NT_STATUS_ACCESS_DENIED;
2514                         break;
2515                 default:
2516                         return NT_STATUS_INVALID_INFO_CLASS;
2517         }
2518
2519         return NT_STATUS_NOPROBLEMO;
2520 }
2521
2522 /*******************************************************************
2523  api_samr_set_userinfo2
2524  ********************************************************************/
2525 static BOOL api_samr_set_userinfo2(pipes_struct *p)
2526 {
2527         SAMR_Q_SET_USERINFO2 q_u;
2528         SAMR_R_SET_USERINFO2 r_u;
2529         SAM_USERINFO_CTR ctr;
2530
2531         prs_struct *data = &p->in_data.data;
2532         prs_struct *rdata = &p->out_data.rdata;
2533
2534         ZERO_STRUCT(q_u);
2535         ZERO_STRUCT(r_u);
2536
2537         q_u.ctr = &ctr;
2538
2539         if (!samr_io_q_set_userinfo2("", &q_u, data, 0)) {
2540                 DEBUG(0,("api_samr_set_userinfo2: Unable to unmarshall SAMR_Q_SET_USERINFO2.\n"));
2541                 return False;
2542         }
2543
2544         r_u.status = _samr_set_userinfo2(&q_u.pol, q_u.switch_value, &ctr);
2545
2546         free_samr_q_set_userinfo2(&q_u);
2547
2548         if(!samr_io_r_set_userinfo2("", &r_u, rdata, 0)) {
2549                 DEBUG(0,("api_samr_set_userinfo2: Unable to marshall SAMR_R_SET_USERINFO2.\n"));
2550                 return False;
2551         }
2552
2553         return True;
2554 }
2555
2556
2557 /*******************************************************************
2558  array of \PIPE\samr operations
2559  ********************************************************************/
2560 static struct api_struct api_samr_cmds [] =
2561 {
2562         { "SAMR_CLOSE_HND"        , SAMR_CLOSE_HND        , api_samr_close_hnd        },
2563         { "SAMR_CONNECT"          , SAMR_CONNECT          , api_samr_connect          },
2564         { "SAMR_CONNECT_ANON"     , SAMR_CONNECT_ANON     , api_samr_connect_anon     },
2565         { "SAMR_ENUM_DOM_USERS"   , SAMR_ENUM_DOM_USERS   , api_samr_enum_dom_users   },
2566         { "SAMR_ENUM_DOM_GROUPS"  , SAMR_ENUM_DOM_GROUPS  , api_samr_enum_dom_groups  },
2567         { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
2568         { "SAMR_LOOKUP_IDS"       , SAMR_LOOKUP_IDS       , api_samr_lookup_ids       },
2569         { "SAMR_LOOKUP_NAMES"     , SAMR_LOOKUP_NAMES     , api_samr_lookup_names     },
2570         { "SAMR_OPEN_USER"        , SAMR_OPEN_USER        , api_samr_open_user        },
2571         { "SAMR_QUERY_USERINFO"   , SAMR_QUERY_USERINFO   , api_samr_query_userinfo   },
2572         { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info   },
2573         { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
2574         { "SAMR_QUERY_DISPINFO"   , SAMR_QUERY_DISPINFO   , api_samr_query_dispinfo   },
2575         { "SAMR_QUERY_ALIASINFO"  , SAMR_QUERY_ALIASINFO  , api_samr_query_aliasinfo  },
2576         { "SAMR_CREATE_USER"      , SAMR_CREATE_USER      , api_samr_create_user      },
2577         { "SAMR_LOOKUP_RIDS"      , SAMR_LOOKUP_RIDS      , api_samr_lookup_rids      },
2578         { "SAMR_UNKNOWN_38"       , SAMR_UNKNOWN_38       , api_samr_unknown_38       },
2579         { "SAMR_CHGPASSWD_USER"   , SAMR_CHGPASSWD_USER   , api_samr_chgpasswd_user   },
2580         { "SAMR_OPEN_ALIAS"       , SAMR_OPEN_ALIAS       , api_samr_open_alias       },
2581         { "SAMR_OPEN_DOMAIN"      , SAMR_OPEN_DOMAIN      , api_samr_open_domain      },
2582         { "SAMR_UNKNOWN_3"        , SAMR_UNKNOWN_3        , api_samr_unknown_3        },
2583         { "SAMR_UNKNOWN_2C"       , SAMR_UNKNOWN_2C       , api_samr_unknown_2c       },
2584         { "SAMR_LOOKUP_DOMAIN"    , SAMR_LOOKUP_DOMAIN    , api_samr_lookup_domain    },
2585         { "SAMR_ENUM_DOMAINS"     , SAMR_ENUM_DOMAINS     , api_samr_enum_domains     },
2586         { "SAMR_SET_USERINFO"     , SAMR_SET_USERINFO     , api_samr_set_userinfo     },
2587         { "SAMR_SET_USERINFO2"    , SAMR_SET_USERINFO2    , api_samr_set_userinfo2    },
2588         { NULL                    , 0                     , NULL                      }
2589 };
2590
2591 /*******************************************************************
2592  receives a samr pipe and responds.
2593  ********************************************************************/
2594 BOOL api_samr_rpc(pipes_struct *p)
2595 {
2596         return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds);
2597 }
2598 #undef OLD_NTDOMAIN