Excise snprintf -> slprintf.
[samba.git] / source / rpc_server / srv_samr.c
1 #define OLD_NTDOMAIN 1
2 /* 
3  *  Unix SMB/Netbios implementation.
4  *  Version 1.9.
5  *  RPC Pipe client / server routines
6  *  Copyright (C) Andrew Tridgell              1992-1997,
7  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
8  *  Copyright (C) Paul Ashton                       1997.
9  *  Copyright (C) Hewlett-Packard Company           1999.
10  *  
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *  
16  *  This program is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *  
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  */
25
26 #include "includes.h"
27
28 extern int DEBUGLEVEL;
29
30 extern fstring global_myworkgroup;
31 extern pstring global_myname;
32 extern DOM_SID global_sam_sid;
33
34 extern rid_name domain_group_rids[];
35 extern rid_name domain_alias_rids[];
36 extern rid_name builtin_alias_rids[];
37
38 /*******************************************************************
39   This next function should be replaced with something that
40   dynamically returns the correct user info..... JRA.
41  ********************************************************************/
42
43 static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx,
44                                 int *total_entries, int *num_entries,
45                                 int max_num_entries, uint16 acb_mask)
46 {
47         SAM_ACCOUNT *pwd = NULL;
48
49         (*num_entries) = 0;
50         (*total_entries) = 0;
51
52         if (pw_buf == NULL) 
53                 return False;
54
55         if (!pdb_setsampwent(False))
56         {
57                 DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n"));
58                 return False;
59         }
60
61         while ( ((pwd=pdb_getsampwent()) != NULL) && ((*num_entries) < max_num_entries) ) 
62         {
63                 int user_name_len;
64
65                 if (start_idx > 0) {
66                         /* skip the requested number of entries.
67                            not very efficient, but hey...
68                          */
69                         start_idx--;
70                         continue;
71                 }
72
73                 user_name_len = strlen(pdb_get_username(pwd))+1;
74                 init_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pdb_get_username(pwd), user_name_len);
75                 init_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
76                 pw_buf[(*num_entries)].user_rid = pdb_get_user_rid(pwd);
77                 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
78
79                 /* Now check if the NT compatible password is available. */
80                 if (pdb_get_nt_passwd(pwd) != NULL) 
81                 {
82                         memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
83                 }
84
85                 pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
86
87                 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
88                           (*num_entries), pdb_get_username(pwd),
89                           pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd)));
90
91                 if (acb_mask == 0 || (pdb_get_acct_ctrl(pwd) & acb_mask)) 
92                 {
93                         DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
94                         (*num_entries)++;
95                 } 
96                 else 
97                 {
98                         DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
99                 }
100
101                 (*total_entries)++;
102         }
103
104         pdb_endsampwent();
105
106         return (*num_entries) > 0;
107 }
108
109 /*******************************************************************
110  This function uses the username map file and tries to map a UNIX
111  user name to an DOS name.  (Sort of the reverse of the
112  map_username() function.)  Since more than one DOS name can map
113  to the UNIX name, to reverse the mapping you have to specify
114  which corresponding DOS name you want; that's where the name_idx
115  parameter comes in.  Returns the string requested or NULL if it
116  fails or can't complete the request for any reason.  This doesn't
117  handle group names (starting with '@') or names starting with
118  '+' or '&'.  If they are encountered, they are skipped.
119 ********************************************************************/
120
121 static char *unmap_unixname(char *unix_user_name, int name_idx)
122 {
123         char *mapfile = lp_username_map();
124         char **lines;
125         static pstring tok;
126         int i;
127
128         if (!*unix_user_name) return NULL;
129         if (!*mapfile) return NULL;
130
131         lines = file_lines_load(mapfile, NULL,False);
132         if (!lines) {
133                 DEBUG(0,("unmap_unixname: can't open username map %s\n", mapfile));
134                 return NULL;
135         }
136
137         DEBUG(5,("unmap_unixname: scanning username map %s, index: %d\n", mapfile, name_idx));
138
139         for (i=0; lines[i]; i++) {
140                 char *unixname = lines[i];
141                 char *dosname = strchr(unixname,'=');
142
143                 if (!dosname)
144                         continue;
145
146                 *dosname++ = 0;
147
148                 while (isspace(*unixname))
149                         unixname++;
150                 if ('!' == *unixname) {
151                         unixname++;
152                         while (*unixname && isspace(*unixname))
153                                 unixname++;
154                 }
155     
156                 if (!*unixname || strchr("#;",*unixname))
157                         continue;
158
159                 if (strncmp(unixname, unix_user_name, strlen(unix_user_name)))
160                         continue;
161
162                 /* We have matched the UNIX user name */
163
164                 while(next_token(&dosname, tok, LIST_SEP, sizeof(tok))) {
165                         if (!strchr("@&+", *tok)) {
166                                 name_idx--;
167                                 if (name_idx < 0 ) {
168                                         break;
169                                 }
170                         }
171                 }
172
173                 if (name_idx >= 0) {
174                         DEBUG(0,("unmap_unixname: index too high - not that many DOS names\n"));
175                         file_lines_free(lines);
176                         return NULL;
177                 } else {
178                         file_lines_free(lines);
179                         return tok;
180                 }
181         }
182
183         DEBUG(0,("unmap_unixname: Couldn't find the UNIX user name\n"));
184         file_lines_free(lines);
185         return NULL;
186 }
187
188 /*******************************************************************
189  This function sets up a list of users taken from the list of
190  users that UNIX knows about, as well as all the user names that
191  Samba maps to a valid UNIX user name.  (This should work with
192  /etc/passwd or NIS.)
193 ********************************************************************/
194
195 static BOOL get_passwd_entries(SAM_USER_INFO_21 *pw_buf,
196                                 int start_idx,
197                                 int *total_entries, int *num_entries,
198                                 int max_num_entries,
199                                 uint16 acb_mask)
200 {
201         static struct passwd *pwd = NULL;
202         static uint32 pw_rid;
203         static BOOL orig_done = False;
204         static int current_idx = 0;
205         static int mapped_idx = 0;
206         char *sep;
207
208         DEBUG(5, ("get_passwd_entries: retrieving a list of UNIX users\n"));
209
210         (*num_entries) = 0;
211         (*total_entries) = 0;
212
213         /* Skip all this stuff if we're in appliance mode */
214
215         if (lp_hide_local_users()) goto done;
216
217         if (pw_buf == NULL) return False;
218
219         if (current_idx == 0) {
220                 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                 sys_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                         int i;
792                         uint32 trid;
793                         name = grp->gr_name;
794
795                         /* Don't return winbind groups as they are not local! */
796
797                         if (strchr(name, *sep) != NULL) {
798                                 continue;
799                         }
800
801                         trid = pdb_gid_to_group_rid(grp->gr_gid);
802                         for( i = 0; i < num_entries; i++)
803                                 if ( pass[i].user_rid == trid ) break;
804                         if ( i < num_entries )
805                                 continue; /* rid was there, dup! */
806
807                         init_unistr2(&(pass[num_entries].uni_user_name), name, strlen(name)+1);
808                         pass[num_entries].user_rid = trid;
809                         num_entries++;
810                 }
811
812                 endgrent();
813         }
814                 
815         init_samr_r_enum_dom_aliases(&r_e, num_entries, pass, r_e.status);
816
817         /* store the response in the SMB stream */
818         if(!samr_io_r_enum_dom_aliases("", &r_e, rdata, 0))
819                 return False;
820
821         DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
822
823         return True;
824 }
825
826 /*******************************************************************
827  api_samr_enum_dom_aliases
828  ********************************************************************/
829 static BOOL api_samr_enum_dom_aliases(pipes_struct *p)
830 {
831         SAMR_Q_ENUM_DOM_ALIASES q_e;
832         prs_struct *data = &p->in_data.data;
833         prs_struct *rdata = &p->out_data.rdata;
834         
835         ZERO_STRUCT(q_e);
836
837         /* grab the samr open */
838         if(!samr_io_q_enum_dom_aliases("", &q_e, data, 0))
839                 return False;
840
841         /* construct reply. */
842         if(!samr_reply_enum_dom_aliases(&q_e, rdata))
843                 return False;
844
845         return True;
846 }
847
848
849 /*******************************************************************
850  samr_reply_query_dispinfo
851  ********************************************************************/
852 static BOOL samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u, prs_struct *rdata)
853 {
854         SAMR_R_QUERY_DISPINFO r_e;
855         SAM_INFO_CTR ctr;
856         SAM_INFO_1 info1;
857         SAM_INFO_2 info2;
858         SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
859         int num_entries = 0;
860         int total_entries = 0;
861         BOOL got_pwds;
862         uint16 switch_level = 0x0;
863
864         ZERO_STRUCT(r_e);
865
866         DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
867
868         /* find the policy handle.  open a policy on it. */
869         if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
870         {
871                 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
872                 DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n"));
873         }
874
875         if (r_e.status == 0x0)
876         {
877           /* decide how many entries to get depending on the max_entries 
878              and max_size passed by client */
879           uint32 retsize;
880
881           if(q_u->max_entries > MAX_SAM_ENTRIES)
882             q_u->max_entries = MAX_SAM_ENTRIES;
883           
884           retsize = (q_u->max_entries * (sizeof(SAM_ENTRY1)+sizeof(SAM_STR1)))
885             + 3*sizeof(uint32);
886
887           if(retsize > q_u->max_size)
888             {
889               /* determine max_entries based on max_size */
890               q_u->max_entries = (q_u->max_size - 3*sizeof(uint32)) /
891                 (sizeof(SAM_ENTRY1)+sizeof(SAM_STR1));
892               q_u->max_entries = (q_u->max_entries>0?q_u->max_entries:1);
893             }
894
895           DEBUG(10,("samr_reply_query_dispinfo: Setting q_u->max_entries to %u\n",q_u->max_entries));
896
897                 become_root();
898                 got_pwds = get_passwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, q_u->max_entries, 0);
899                 unbecome_root();
900
901                 /* more left - set resume handle */
902                 if(total_entries > num_entries)
903                   {
904                     r_e.status = 0x105;
905                   }
906
907                 switch (q_u->switch_level)
908                 {
909                         case 0x1:
910                         {
911                         
912                                 /* query disp info is for users */
913                                 ZERO_STRUCT (info1);
914                                 switch_level = 0x1;
915                                 init_sam_info_1(&info1, ACB_NORMAL,
916                                         q_u->start_idx, num_entries, pass);
917
918                                 ctr.sam.info1 = &info1;
919
920                                 break;
921                         }
922                         case 0x2:
923                         {
924                                 /* query disp info is for servers */
925                                 ZERO_STRUCT (info2);
926                                 switch_level = 0x2;
927                                 init_sam_info_2(&info2, ACB_WSTRUST,
928                                         q_u->start_idx, num_entries, pass);
929
930                                 ctr.sam.info2 = &info2;
931
932                                 break;
933                         }
934                 }
935         }
936
937         /* more left - set resume handle */
938         if(total_entries > num_entries)
939           {
940             r_e.status = 0x105;
941           }
942
943         if (r_e.status == 0 || r_e.status == 0x105)
944         {
945           init_samr_r_query_dispinfo(&r_e, switch_level, &ctr, r_e.status);
946         }
947
948         /* store the response in the SMB stream */
949         if(!samr_io_r_query_dispinfo("", &r_e, rdata, 0))
950                 return False;
951
952         DEBUG(5,("samr_query_dispinfo: %d\n", __LINE__));
953
954         return True;
955 }
956
957 /*******************************************************************
958  api_samr_query_dispinfo
959  ********************************************************************/
960 static BOOL api_samr_query_dispinfo(pipes_struct *p)
961 {
962         SAMR_Q_QUERY_DISPINFO q_e;
963         prs_struct *data = &p->in_data.data;
964         prs_struct *rdata = &p->out_data.rdata;
965
966         /* grab the samr open */
967         if(!samr_io_q_query_dispinfo("", &q_e, data, 0))
968                 return False;
969
970         /* construct reply. */
971         if(!samr_reply_query_dispinfo(&q_e, rdata))
972                 return False;
973
974         return True;
975 }
976
977
978 /*******************************************************************
979  samr_reply_query_aliasinfo
980  ********************************************************************/
981 static BOOL samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
982                                 prs_struct *rdata)
983 {
984   SAMR_R_QUERY_ALIASINFO r_e;
985   fstring alias_desc = "Local Unix group";
986   fstring alias="";
987   enum SID_NAME_USE type;
988   uint32 alias_rid;
989
990   ZERO_STRUCT(r_e);
991
992   DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__));
993
994   /* find the policy handle.  open a policy on it. */
995   if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
996     {
997       r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
998     }
999
1000   alias_rid = get_lsa_policy_samr_rid(&q_u->pol);
1001   if(alias_rid == 0xffffffff)
1002       r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
1003
1004   if(!local_lookup_rid(alias_rid, alias, &type))
1005     {
1006       r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
1007     }
1008   
1009   init_samr_r_query_aliasinfo(&r_e, q_u->switch_level, alias, alias_desc);
1010   
1011   /* store the response in the SMB stream */
1012   if(!samr_io_r_query_aliasinfo("", &r_e, rdata, 0))
1013                 return False;
1014   
1015   DEBUG(5,("samr_query_aliasinfo: %d\n", __LINE__));
1016
1017         return True;
1018 }
1019
1020 /*******************************************************************
1021  api_samr_query_aliasinfo
1022  ********************************************************************/
1023 static BOOL api_samr_query_aliasinfo(pipes_struct *p)
1024 {
1025         SAMR_Q_QUERY_ALIASINFO q_e;
1026         prs_struct *data = &p->in_data.data;
1027         prs_struct *rdata = &p->out_data.rdata;
1028
1029         /* grab the samr open */
1030         if(!samr_io_q_query_aliasinfo("", &q_e, data, 0))
1031                 return False;
1032
1033         /* construct reply. */
1034         if(!samr_reply_query_aliasinfo(&q_e, rdata))
1035                 return False;
1036
1037         return True;
1038 }
1039
1040
1041 /*******************************************************************
1042  samr_reply_lookup_ids
1043  ********************************************************************/
1044 static BOOL samr_reply_lookup_ids(SAMR_Q_LOOKUP_IDS *q_u,
1045                                 prs_struct *rdata)
1046 {
1047         uint32 rid[MAX_SAM_ENTRIES];
1048         uint32 status     = 0;
1049         int num_rids = q_u->num_sids1;
1050
1051         SAMR_R_LOOKUP_IDS r_u;
1052
1053         DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
1054
1055         if (num_rids > MAX_SAM_ENTRIES)
1056         {
1057                 num_rids = MAX_SAM_ENTRIES;
1058                 DEBUG(5,("samr_lookup_ids: truncating entries to %d\n", num_rids));
1059         }
1060
1061 #if 0
1062         int i;
1063         SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1064
1065         for (i = 0; i < num_rids && status == 0; i++)
1066         {
1067                 SAM_ACCOUNT *sam_pass;
1068                 fstring user_name;
1069
1070
1071                 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1072                                             q_u->uni_user_name[i].uni_str_len));
1073
1074                 /* find the user account */
1075                 become_root();
1076                 sam_pass = pdb_getsampwnam(user_name);
1077                 unbecome_root();
1078
1079                 if (sam_pass == NULL)
1080                 {
1081                         status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1082                         rid[i] = 0;
1083                 }
1084                 else
1085                 {
1086                         rid[i] = pdb_get_user_rid(sam_pass);
1087                 }
1088         }
1089 #endif
1090
1091         num_rids = 1;
1092         rid[0] = BUILTIN_ALIAS_RID_USERS;
1093
1094         init_samr_r_lookup_ids(&r_u, num_rids, rid, status);
1095
1096         /* store the response in the SMB stream */
1097         if(!samr_io_r_lookup_ids("", &r_u, rdata, 0))
1098                 return False;
1099
1100         DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
1101
1102         return True;
1103 }
1104
1105 /*******************************************************************
1106  api_samr_lookup_ids
1107  ********************************************************************/
1108 static BOOL api_samr_lookup_ids(pipes_struct *p)
1109 {
1110         SAMR_Q_LOOKUP_IDS q_u;
1111         prs_struct *data = &p->in_data.data;
1112         prs_struct *rdata = &p->out_data.rdata;
1113
1114         /* grab the samr 0x10 */
1115         if(!samr_io_q_lookup_ids("", &q_u, data, 0))
1116                 return False;
1117
1118         /* construct reply.  always indicate success */
1119         if(!samr_reply_lookup_ids(&q_u, rdata))
1120                 return False;
1121
1122         return True;
1123 }
1124
1125 /*******************************************************************
1126  samr_reply_lookup_names
1127  ********************************************************************/
1128
1129 static BOOL samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
1130                                     prs_struct *rdata)
1131 {
1132   uint32 rid[MAX_SAM_ENTRIES];
1133   enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1134   uint32 status = 0;
1135   int i;
1136   int num_rids = q_u->num_names1;
1137   DOM_SID pol_sid;
1138
1139   SAMR_R_LOOKUP_NAMES r_u;
1140
1141   DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1142
1143   ZERO_ARRAY(rid);
1144   ZERO_ARRAY(type);
1145
1146   if (!get_lsa_policy_samr_sid(&q_u->pol, &pol_sid)) {
1147     status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
1148     init_samr_r_lookup_names(&r_u, 0, rid, type, status);
1149     if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
1150       DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
1151       return False;
1152     }
1153     return True;
1154   }
1155
1156   if (num_rids > MAX_SAM_ENTRIES) {
1157     num_rids = MAX_SAM_ENTRIES;
1158     DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
1159   }
1160
1161   SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
1162
1163   for (i = 0; i < num_rids; i++) {
1164     fstring name;
1165
1166     status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
1167
1168     rid [i] = 0xffffffff;
1169     type[i] = SID_NAME_UNKNOWN;
1170
1171     fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer,
1172                                q_u->uni_name[i].uni_str_len));
1173
1174     if(sid_equal(&pol_sid, &global_sam_sid)) 
1175     {
1176       DOM_SID sid;
1177       if(local_lookup_name(global_myname, name, 
1178                            &sid, &type[i]))
1179         {
1180           sid_split_rid( &sid, &rid[i]);
1181           status = 0;
1182         }
1183     }
1184   }
1185
1186   init_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
1187
1188   /* store the response in the SMB stream */
1189   if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
1190     DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
1191     return False;
1192   }
1193
1194   DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1195
1196   return True;
1197 }
1198
1199 /*******************************************************************
1200  api_samr_lookup_names
1201  ********************************************************************/
1202
1203 static BOOL api_samr_lookup_names(pipes_struct *p)
1204 {
1205         SAMR_Q_LOOKUP_NAMES q_u;
1206         prs_struct *data = &p->in_data.data;
1207         prs_struct *rdata = &p->out_data.rdata;
1208
1209         memset(&q_u, '\0', sizeof(q_u));
1210
1211         /* grab the samr lookup names */
1212         if(!samr_io_q_lookup_names("", &q_u, data, 0)) {
1213                 DEBUG(0,("api_samr_lookup_names: failed to unmarshall SAMR_Q_LOOKUP_NAMES.\n"));
1214                 return False;
1215         }
1216
1217         /* construct reply.  always indicate success */
1218         if(!samr_reply_lookup_names(&q_u, rdata))
1219                 return False;
1220
1221         return True;
1222 }
1223
1224 /*******************************************************************
1225  samr_reply_chgpasswd_user
1226  ********************************************************************/
1227
1228 static BOOL samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
1229                                 prs_struct *rdata)
1230 {
1231         SAMR_R_CHGPASSWD_USER r_u;
1232         uint32 status = 0x0;
1233         fstring user_name;
1234         fstring wks;
1235
1236         fstrcpy(user_name, dos_unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len));
1237         fstrcpy(wks      , dos_unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len));
1238
1239         DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1240
1241         if (!pass_oem_change(user_name,
1242                              q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1243                              q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1244         {
1245                 status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
1246         }
1247
1248         init_samr_r_chgpasswd_user(&r_u, status);
1249
1250         /* store the response in the SMB stream */
1251         if(!samr_io_r_chgpasswd_user("", &r_u, rdata, 0)) {
1252                 DEBUG(0,("samr_reply_chgpasswd_user: Failed to marshall SAMR_R_CHGPASSWD_USER struct.\n" ));
1253                 return False;
1254         }
1255
1256         DEBUG(5,("samr_chgpasswd_user: %d\n", __LINE__));
1257         return True;
1258 }
1259
1260 /*******************************************************************
1261  api_samr_chgpasswd_user
1262  ********************************************************************/
1263
1264 static BOOL api_samr_chgpasswd_user(pipes_struct *p)
1265 {
1266         SAMR_Q_CHGPASSWD_USER q_u;
1267         prs_struct *data = &p->in_data.data;
1268         prs_struct *rdata = &p->out_data.rdata;
1269
1270         /* unknown 38 command */
1271         if (!samr_io_q_chgpasswd_user("", &q_u, data, 0)) {
1272                 DEBUG(0,("api_samr_chgpasswd_user: samr_io_q_chgpasswd_user failed to parse RPC packet.\n"));
1273                 return False;
1274         }
1275
1276         /* construct reply. */
1277         if(!samr_reply_chgpasswd_user(&q_u, rdata)) {
1278                 DEBUG(0,("api_samr_chgpasswd_user: samr_reply_chgpasswd_user failed to create reply packet.\n"));
1279                 return False;
1280         }
1281
1282         return True;
1283 }
1284
1285
1286 /*******************************************************************
1287  samr_reply_unknown_38
1288  ********************************************************************/
1289 static BOOL samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u, prs_struct *rdata)
1290 {
1291         SAMR_R_UNKNOWN_38 r_u;
1292
1293         DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1294
1295         init_samr_r_unknown_38(&r_u);
1296
1297         /* store the response in the SMB stream */
1298         if(!samr_io_r_unknown_38("", &r_u, rdata, 0))
1299                 return False;
1300
1301         DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1302         return True;
1303 }
1304
1305 /*******************************************************************
1306  api_samr_unknown_38
1307  ********************************************************************/
1308 static BOOL api_samr_unknown_38(pipes_struct *p)
1309 {
1310         SAMR_Q_UNKNOWN_38 q_u;
1311         prs_struct *data = &p->in_data.data;
1312         prs_struct *rdata = &p->out_data.rdata;
1313
1314         /* unknown 38 command */
1315         if(!samr_io_q_unknown_38("", &q_u, data, 0))
1316                 return False;
1317
1318         /* construct reply.  always indicate success */
1319         if(!samr_reply_unknown_38(&q_u, rdata))
1320                 return False;
1321
1322         return True;
1323 }
1324
1325
1326 /*******************************************************************
1327  samr_reply_lookup_rids
1328  ********************************************************************/
1329 static BOOL samr_reply_lookup_rids(SAMR_Q_LOOKUP_RIDS *q_u,
1330                                 prs_struct *rdata)
1331 {
1332         fstring group_names[MAX_SAM_ENTRIES];
1333         uint32  group_attrs[MAX_SAM_ENTRIES];
1334         uint32 status     = 0;
1335         int num_gids = q_u->num_gids1;
1336
1337         SAMR_R_LOOKUP_RIDS r_u;
1338
1339         DEBUG(5,("samr_reply_lookup_rids: %d\n", __LINE__));
1340
1341         /* find the policy handle.  open a policy on it. */
1342         if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1343         {
1344                 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1345         }
1346
1347         if (status == 0x0)
1348         {
1349                 int i;
1350                 if (num_gids > MAX_SAM_ENTRIES)
1351                 {
1352                         num_gids = MAX_SAM_ENTRIES;
1353                         DEBUG(5,("samr_reply_lookup_rids: truncating entries to %d\n", num_gids));
1354                 }
1355
1356                 for (i = 0; i < num_gids && status == 0; i++)
1357                 {
1358                         fstrcpy(group_names[i], "dummy group");
1359                         group_attrs[i] = 0x2;
1360                 }
1361         }
1362
1363         init_samr_r_lookup_rids(&r_u, num_gids, group_names, group_attrs, status);
1364
1365         /* store the response in the SMB stream */
1366         if(!samr_io_r_lookup_rids("", &r_u, rdata, 0))
1367                 return False;
1368
1369         DEBUG(5,("samr_reply_lookup_rids: %d\n", __LINE__));
1370
1371         return True;
1372 }
1373
1374 /*******************************************************************
1375  api_samr_lookup_rids
1376  ********************************************************************/
1377 static BOOL api_samr_lookup_rids(pipes_struct *p)
1378 {
1379         SAMR_Q_LOOKUP_RIDS q_u;
1380         prs_struct *data = &p->in_data.data;
1381         prs_struct *rdata = &p->out_data.rdata;
1382
1383         /* grab the samr lookup names */
1384         if(!samr_io_q_lookup_rids("", &q_u, data, 0))
1385                 return False;
1386
1387         /* construct reply.  always indicate success */
1388         if(!samr_reply_lookup_rids(&q_u, rdata))
1389                 return False;
1390
1391         return True;
1392 }
1393
1394
1395 /*******************************************************************
1396  _api_samr_open_user
1397  ********************************************************************/
1398 static uint32 _api_samr_open_user(POLICY_HND domain_pol, uint32 user_rid, POLICY_HND *user_pol)
1399 {
1400         SAM_ACCOUNT *sam_pass;
1401         DOM_SID sid;
1402
1403         /* find the domain policy handle. */
1404         if (find_lsa_policy_by_hnd(&domain_pol) == -1)
1405                 return NT_STATUS_INVALID_HANDLE;
1406
1407         /* get a (unique) handle.  open a policy on it. */
1408         if (!open_lsa_policy_hnd(user_pol))
1409                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1410
1411         become_root();
1412         sam_pass = pdb_getsampwrid(user_rid);
1413         unbecome_root();
1414
1415         /* check that the RID exists in our domain. */
1416         if (sam_pass == NULL) {
1417                 close_lsa_policy_hnd(user_pol);
1418                 return NT_STATUS_NO_SUCH_USER;
1419         }
1420         
1421         /* Get the domain SID stored in the domain policy */
1422         if(!get_lsa_policy_samr_sid(&domain_pol, &sid)) {
1423                 close_lsa_policy_hnd(user_pol);
1424                 return NT_STATUS_INVALID_HANDLE;
1425         }
1426
1427         /* append the user's RID to it */
1428         if(!sid_append_rid(&sid, user_rid)) {
1429                 close_lsa_policy_hnd(user_pol);
1430                 return NT_STATUS_NO_SUCH_USER;
1431         }
1432
1433         /* associate the user's SID with the handle. */
1434         if (!set_lsa_policy_samr_sid(user_pol, &sid)) {
1435                 /* oh, whoops.  don't know what error message to return, here */
1436                 close_lsa_policy_hnd(user_pol);
1437                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1438         }
1439
1440         return NT_STATUS_NO_PROBLEMO;
1441 }
1442
1443 /*******************************************************************
1444  api_samr_open_user
1445  ********************************************************************/
1446 static BOOL api_samr_open_user(pipes_struct *p)
1447 {
1448         SAMR_Q_OPEN_USER q_u;
1449         SAMR_R_OPEN_USER r_u;
1450         prs_struct *data = &p->in_data.data;
1451         prs_struct *rdata = &p->out_data.rdata;
1452
1453         ZERO_STRUCT(q_u);
1454         ZERO_STRUCT(r_u);
1455
1456         /* grab the samr unknown 22 */
1457         if(!samr_io_q_open_user("", &q_u, data, 0))
1458                 return False;
1459
1460         r_u.status = _api_samr_open_user(q_u.domain_pol, q_u.user_rid, &r_u.user_pol);
1461
1462         /* store the response in the SMB stream */
1463         if(!samr_io_r_open_user("", &r_u, rdata, 0))
1464                 return False;
1465
1466         DEBUG(5,("samr_open_user: %d\n", __LINE__));
1467
1468         return True;
1469 }
1470
1471 /*************************************************************************
1472  get_user_info_10
1473  *************************************************************************/
1474 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1475 {
1476         SAM_ACCOUNT *sampass;
1477
1478         if (!pdb_rid_is_user(user_rid))
1479         {
1480                 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1481                 return False;
1482         }
1483
1484         become_root();
1485         sampass = pdb_getsampwrid(user_rid);
1486         unbecome_root();
1487
1488         if (sampass == NULL)
1489         {
1490                 DEBUG(4,("User 0x%x not found\n", user_rid));
1491                 return False;
1492         }
1493
1494         DEBUG(3,("User:[%s]\n", pdb_get_username(sampass)));
1495
1496         init_sam_user_info10(id10, pdb_get_acct_ctrl(sampass)); 
1497
1498         return True;
1499 }
1500
1501 /*************************************************************************
1502  get_user_info_21
1503  *************************************************************************/
1504 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1505 {
1506         SAM_ACCOUNT     *sam_pass;
1507
1508         if (!pdb_rid_is_user(user_rid))
1509         {
1510                 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1511                 return False;
1512         }
1513
1514         become_root();
1515         sam_pass = pdb_getsampwrid(user_rid);
1516         unbecome_root();
1517
1518         if (sam_pass == NULL)
1519         {
1520                 DEBUG(4,("User 0x%x not found\n", user_rid));
1521                 return False;
1522         }
1523
1524         DEBUG(3,("User:[%s]\n", pdb_get_username(sam_pass)));
1525
1526         init_sam_user_info21(id21, sam_pass);
1527
1528         return True;
1529 }
1530
1531 /*******************************************************************
1532  samr_reply_query_userinfo
1533  ********************************************************************/
1534 static BOOL samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
1535                                 prs_struct *rdata)
1536 {
1537         SAMR_R_QUERY_USERINFO r_u;
1538 #if 0
1539         SAM_USER_INFO_11 id11;
1540 #endif
1541         SAM_USER_INFO_10 id10;
1542         SAM_USER_INFO_21 id21;
1543         void *info = NULL;
1544
1545         uint32 status = 0x0;
1546         uint32 rid = 0x0;
1547
1548         DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1549
1550         /* search for the handle */
1551         if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1552         {
1553                 status = NT_STATUS_INVALID_HANDLE;
1554         }
1555
1556         /* find the user's rid */
1557         if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1558         {
1559                 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1560         }
1561
1562         DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
1563
1564         /* ok!  user info levels (there are lots: see MSDEV help), off we go... */
1565         if (status == 0x0)
1566         {
1567                 switch (q_u->switch_value)
1568                 {
1569                         case 0x10:
1570                         {
1571                                 info = (void*)&id10;
1572                                 status = get_user_info_10(&id10, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1573                                 break;
1574                         }
1575 #if 0
1576 /* whoops - got this wrong.  i think.  or don't understand what's happening. */
1577                         case 0x11:
1578                         {
1579                                 NTTIME expire;
1580                                 info = (void*)&id11;
1581                                 
1582                                 expire.low  = 0xffffffff;
1583                                 expire.high = 0x7fffffff;
1584
1585                                 make_sam_user_info11(&id11, &expire, "BROOKFIELDS$", 0x03ef, 0x201, 0x0080);
1586
1587                                 break;
1588                         }
1589 #endif
1590                         case 21:
1591                         {
1592                                 info = (void*)&id21;
1593                                 status = get_user_info_21(&id21, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1594                                 break;
1595                         }
1596
1597                         default:
1598                         {
1599                                 status = NT_STATUS_INVALID_INFO_CLASS;
1600
1601                                 break;
1602                         }
1603                 }
1604         }
1605
1606         init_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
1607
1608         /* store the response in the SMB stream */
1609         if(!samr_io_r_query_userinfo("", &r_u, rdata, 0))
1610                 return False;
1611
1612         DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1613
1614         return True;
1615 }
1616
1617 /*******************************************************************
1618  api_samr_query_userinfo
1619  ********************************************************************/
1620 static BOOL api_samr_query_userinfo(pipes_struct *p)
1621 {
1622         SAMR_Q_QUERY_USERINFO q_u;
1623         prs_struct *data = &p->in_data.data;
1624         prs_struct *rdata = &p->out_data.rdata;
1625
1626         /* grab the samr unknown 24 */
1627         if(!samr_io_q_query_userinfo("", &q_u, data, 0))
1628                 return False;
1629
1630         /* construct reply.  always indicate success */
1631         if(!samr_reply_query_userinfo(&q_u, rdata))
1632                 return False;
1633
1634         return True;
1635 }
1636
1637
1638 /*******************************************************************
1639  samr_reply_query_usergroups
1640  ********************************************************************/
1641 static BOOL samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
1642                                 prs_struct *rdata)
1643 {
1644         SAMR_R_QUERY_USERGROUPS r_u;
1645         uint32 status = 0x0;
1646
1647         SAM_ACCOUNT *sam_pass;
1648         DOM_GID *gids = NULL;
1649         int num_groups = 0;
1650         uint32 rid;
1651
1652         DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1653
1654         /* find the policy handle.  open a policy on it. */
1655         if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1656         {
1657                 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1658         }
1659
1660         /* find the user's rid */
1661         if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1662         {
1663                 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1664         }
1665
1666         if (status == 0x0)
1667         {
1668                 become_root();
1669                 sam_pass = pdb_getsampwrid(rid);
1670                 unbecome_root();
1671
1672                 if (sam_pass == NULL)
1673                 {
1674                         status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1675                 }
1676         }
1677
1678         if (status == 0x0)
1679         {
1680                 pstring groups;
1681                 get_domain_user_groups(groups, pdb_get_username(sam_pass));
1682                 gids = NULL;
1683                 num_groups = make_dom_gids(groups, &gids);
1684         }
1685
1686         /* construct the response.  lkclXXXX: gids are not copied! */
1687         init_samr_r_query_usergroups(&r_u, num_groups, gids, status);
1688
1689         /* store the response in the SMB stream */
1690         if(!samr_io_r_query_usergroups("", &r_u, rdata, 0)) {
1691                 if (gids)
1692                         free((char *)gids);
1693                 return False;
1694         }
1695
1696         if (gids)
1697                 free((char *)gids);
1698
1699         DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1700         
1701         return True;
1702 }
1703
1704 /*******************************************************************
1705  api_samr_query_usergroups
1706  ********************************************************************/
1707 static BOOL api_samr_query_usergroups(pipes_struct *p)
1708 {
1709         SAMR_Q_QUERY_USERGROUPS q_u;
1710         prs_struct *data = &p->in_data.data;
1711         prs_struct *rdata = &p->out_data.rdata;
1712
1713         /* grab the samr unknown 32 */
1714         if(!samr_io_q_query_usergroups("", &q_u, data, 0))
1715                 return False;
1716
1717         /* construct reply. */
1718         if(!samr_reply_query_usergroups(&q_u, rdata))
1719                 return False;
1720
1721         return True;
1722 }
1723
1724
1725 /*******************************************************************
1726  api_samr_query_dom_info
1727  ********************************************************************/
1728 static BOOL api_samr_query_dom_info(pipes_struct *p)
1729 {
1730         SAMR_Q_QUERY_DOMAIN_INFO q_u;
1731         SAMR_R_QUERY_DOMAIN_INFO r_u;
1732         SAM_UNK_CTR ctr;
1733         prs_struct *data = &p->in_data.data;
1734         prs_struct *rdata = &p->out_data.rdata;
1735
1736         uint16 switch_value = 0x0;
1737         uint32 status = 0x0;
1738
1739         ZERO_STRUCT(q_u);
1740         ZERO_STRUCT(r_u);
1741         ZERO_STRUCT(ctr);
1742
1743         DEBUG(5,("api_samr_query_dom_info: %d\n", __LINE__));
1744
1745         /* grab the samr unknown 8 command */
1746         if(!samr_io_q_query_dom_info("", &q_u, data, 0))
1747                 return False;
1748
1749         /* find the policy handle.  open a policy on it. */
1750         if (find_lsa_policy_by_hnd(&q_u.domain_pol) == -1) {
1751                 status = NT_STATUS_INVALID_HANDLE;
1752                 DEBUG(5,("api_samr_query_dom_info: invalid handle\n"));
1753         }
1754
1755         if (status == 0x0) {
1756                 switch (q_u.switch_value) {
1757                         case 0x01:
1758                                 switch_value = 0x1;
1759                                 init_unk_info1(&ctr.info.inf1);
1760                                 break;
1761                         case 0x02:
1762                                 switch_value = 0x2;
1763                                 init_unk_info2(&ctr.info.inf2, global_myworkgroup, global_myname);
1764                                 break;
1765                         case 0x03:
1766                                 switch_value = 0x3;
1767                                 init_unk_info3(&ctr.info.inf3);
1768                                 break;
1769                         case 0x06:
1770                                 switch_value = 0x6;
1771                                 init_unk_info6(&ctr.info.inf6);
1772                                 break;
1773                         case 0x07:
1774                                 switch_value = 0x7;
1775                                 init_unk_info7(&ctr.info.inf7);
1776                                 break;
1777                         case 0x0c:
1778                                 switch_value = 0xc;
1779                                 init_unk_info12(&ctr.info.inf12);
1780                                 break;
1781                         default:
1782                                 status = NT_STATUS_INVALID_INFO_CLASS;
1783                                 break;
1784                 }
1785         }
1786
1787         init_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
1788
1789         /* store the response in the SMB stream */
1790         if(!samr_io_r_query_dom_info("", &r_u, rdata, 0))
1791                 return False;
1792
1793         DEBUG(5,("api_samr_query_dom_info: %d\n", __LINE__));
1794
1795         return True;
1796 }
1797
1798
1799 /*******************************************************************
1800  _api_samr_create_user
1801  ********************************************************************/
1802 static BOOL _api_samr_create_user(POLICY_HND dom_pol, UNISTR2 user_account, uint32 acb_info, uint32 access_mask,
1803                                   POLICY_HND *user_pol, uint32 *unknown0, uint32 *user_rid)
1804 {
1805         SAM_ACCOUNT *sam_pass;
1806         fstring mach_acct;
1807         pstring err_str;
1808         pstring msg_str;
1809         int local_flags=0;
1810         DOM_SID sid;
1811         
1812         /* find the policy handle.  open a policy on it. */
1813         if (find_lsa_policy_by_hnd(&dom_pol) == -1)
1814                 return NT_STATUS_INVALID_HANDLE;
1815
1816         /* find the machine account: tell the caller if it exists.
1817            lkclXXXX i have *no* idea if this is a problem or not
1818            or even if you are supposed to construct a different
1819            reply if the account already exists...
1820          */
1821
1822         fstrcpy(mach_acct, dos_unistrn2(user_account.buffer, user_account.uni_str_len));
1823         strlower(mach_acct);
1824
1825         become_root();
1826         sam_pass = pdb_getsampwnam(mach_acct);
1827         unbecome_root();
1828         if (sam_pass != NULL) 
1829         {
1830                 /* machine account exists: say so */
1831                 return NT_STATUS_USER_EXISTS;
1832         }
1833
1834         /* get a (unique) handle.  open a policy on it. */
1835         if (!open_lsa_policy_hnd(user_pol))
1836                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1837
1838         local_flags=LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_SET_NO_PASSWORD;
1839         local_flags|= (acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0;
1840
1841         /*
1842          * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
1843          * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
1844          * that only people with write access to the smbpasswd file will be able
1845          * to create a user. JRA.
1846          */
1847
1848         /* add the user in the /etc/passwd file or the unix authority system */
1849         if (lp_adduser_script())
1850                 smb_create_user(mach_acct,NULL);
1851
1852         /* add the user in the smbpasswd file or the Samba authority database */
1853         if (!local_password_change(mach_acct, local_flags, NULL, err_str, 
1854              sizeof(err_str), msg_str, sizeof(msg_str))) 
1855         {
1856                 DEBUG(0, ("%s\n", err_str));
1857                 close_lsa_policy_hnd(user_pol);
1858                 return NT_STATUS_ACCESS_DENIED;
1859         }
1860
1861         become_root();
1862         sam_pass = pdb_getsampwnam(mach_acct);
1863         unbecome_root();
1864         if (sam_pass == NULL) {
1865                 /* account doesn't exist: say so */
1866                 close_lsa_policy_hnd(user_pol);
1867                 return NT_STATUS_ACCESS_DENIED;
1868         }
1869
1870         /* Get the domain SID stored in the domain policy */
1871         if(!get_lsa_policy_samr_sid(&dom_pol, &sid)) {
1872                 close_lsa_policy_hnd(user_pol);
1873                 return NT_STATUS_INVALID_HANDLE;
1874         }
1875
1876         /* append the user's RID to it */
1877         if(!sid_append_rid(&sid, sam_pass->user_rid)) {
1878                 close_lsa_policy_hnd(user_pol);
1879                 return NT_STATUS_NO_SUCH_USER;
1880         }
1881
1882         /* associate the RID with the (unique) handle. */
1883         if (!set_lsa_policy_samr_sid(user_pol, &sid)) {
1884                 /* oh, whoops.  don't know what error message to return, here */
1885                 close_lsa_policy_hnd(user_pol);
1886                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1887         }
1888
1889         *unknown0 = 0x000703ff;
1890         *user_rid = pdb_get_user_rid(sam_pass);
1891
1892         return NT_STATUS_NO_PROBLEMO;
1893 }
1894
1895 /*******************************************************************
1896  api_samr_create_user
1897  ********************************************************************/
1898 static BOOL api_samr_create_user(pipes_struct *p)
1899 {
1900         prs_struct *data = &p->in_data.data;
1901         prs_struct *rdata = &p->out_data.rdata;
1902
1903         SAMR_Q_CREATE_USER q_u;
1904         SAMR_R_CREATE_USER r_u;
1905
1906         ZERO_STRUCT(q_u);
1907         ZERO_STRUCT(r_u);
1908
1909         /* grab the samr create user */
1910         if (!samr_io_q_create_user("", &q_u, data, 0)) {
1911                 DEBUG(0,("api_samr_create_user: Unable to unmarshall SAMR_Q_CREATE_USER.\n"));
1912                 return False;
1913         }
1914
1915         r_u.status=_api_samr_create_user(q_u.pol, q_u.uni_mach_acct, q_u.acb_info, q_u.access_mask,
1916                                         &r_u.pol, &r_u.unknown_0, &r_u.user_rid);
1917
1918         /* store the response in the SMB stream */
1919         if(!samr_io_r_create_user("", &r_u, rdata, 0)) {
1920                 DEBUG(0,("api_samr_create_user: Unable to marshall SAMR_R_CREATE_USER.\n"));
1921                 return False;
1922         }
1923
1924         return True;
1925 }
1926
1927
1928 /*******************************************************************
1929  samr_reply_connect_anon
1930  ********************************************************************/
1931 static BOOL samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u, prs_struct *rdata)
1932 {
1933         SAMR_R_CONNECT_ANON r_u;
1934         BOOL pol_open = False;
1935
1936         /* set up the SAMR connect_anon response */
1937
1938         r_u.status = 0x0;
1939         /* get a (unique) handle.  open a policy on it. */
1940         if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1941         {
1942                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1943         }
1944
1945         /* associate the domain SID with the (unique) handle. */
1946         if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1947         {
1948                 /* oh, whoops.  don't know what error message to return, here */
1949                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1950         }
1951
1952         if (r_u.status != 0 && pol_open)
1953         {
1954                 close_lsa_policy_hnd(&(r_u.connect_pol));
1955         }
1956
1957         DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1958
1959         /* store the response in the SMB stream */
1960         if(!samr_io_r_connect_anon("", &r_u, rdata, 0))
1961                 return False;
1962
1963         DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1964
1965         return True;
1966 }
1967
1968 /*******************************************************************
1969  api_samr_connect_anon
1970  ********************************************************************/
1971 static BOOL api_samr_connect_anon(pipes_struct *p)
1972 {
1973         SAMR_Q_CONNECT_ANON q_u;
1974         prs_struct *data = &p->in_data.data;
1975         prs_struct *rdata = &p->out_data.rdata;
1976
1977         /* grab the samr open policy */
1978         if(!samr_io_q_connect_anon("", &q_u, data, 0))
1979                 return False;
1980
1981         /* construct reply.  always indicate success */
1982         if(!samr_reply_connect_anon(&q_u, rdata))
1983                 return False;
1984
1985         return True;
1986 }
1987
1988 /*******************************************************************
1989  samr_reply_connect
1990  ********************************************************************/
1991 static BOOL samr_reply_connect(SAMR_Q_CONNECT *q_u, prs_struct *rdata)
1992 {
1993         SAMR_R_CONNECT r_u;
1994         BOOL pol_open = False;
1995
1996         /* set up the SAMR connect response */
1997
1998         r_u.status = 0x0;
1999         /* get a (unique) handle.  open a policy on it. */
2000         if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
2001         {
2002                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2003         }
2004
2005         /* associate the domain SID with the (unique) handle. */
2006         if (r_u.status == 0x0 && 
2007             !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), 
2008                                             q_u->access_mask))
2009         {
2010                 /* oh, whoops.  don't know what error message to return, here */
2011                 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2012         }
2013
2014         if (r_u.status != 0 && pol_open)
2015         {
2016                 close_lsa_policy_hnd(&(r_u.connect_pol));
2017         }
2018
2019         DEBUG(5,("samr_connect: %d\n", __LINE__));
2020
2021         /* store the response in the SMB stream */
2022         if(!samr_io_r_connect("", &r_u, rdata, 0))
2023                 return False;
2024
2025         DEBUG(5,("samr_connect: %d\n", __LINE__));
2026
2027         return True;
2028 }
2029
2030 /*******************************************************************
2031  api_samr_connect
2032  ********************************************************************/
2033 static BOOL api_samr_connect(pipes_struct *p)
2034 {
2035         SAMR_Q_CONNECT q_u;
2036         prs_struct *data = &p->in_data.data;
2037         prs_struct *rdata = &p->out_data.rdata;
2038
2039         /* grab the samr open policy */
2040         if(!samr_io_q_connect("", &q_u, data, 0))
2041                 return False;
2042
2043         /* construct reply.  always indicate success */
2044         if(!samr_reply_connect(&q_u, rdata))
2045                 return False;
2046
2047         return True;
2048 }
2049
2050   
2051 /**********************************************************************
2052  api_samr_lookup_domain
2053  **********************************************************************/
2054 static BOOL api_samr_lookup_domain(pipes_struct *p)
2055 {
2056         SAMR_Q_LOOKUP_DOMAIN q_u;
2057         SAMR_R_LOOKUP_DOMAIN r_u;
2058         prs_struct *data = &p->in_data.data;
2059         prs_struct *rdata = &p->out_data.rdata;
2060   
2061         ZERO_STRUCT(q_u);
2062         ZERO_STRUCT(r_u);
2063
2064         if(!samr_io_q_lookup_domain("", &q_u, data, 0)) {
2065                 DEBUG(0,("api_samr_lookup_domain: Unable to unmarshall SAMR_Q_LOOKUP_DOMAIN.\n"));
2066                 return False;
2067         }
2068         
2069         r_u.status = 0x0;
2070
2071         if (find_lsa_policy_by_hnd(&q_u.connect_pol) == -1){
2072                 r_u.status = NT_STATUS_INVALID_HANDLE;
2073                 DEBUG(5,("api_samr_lookup_domain: invalid handle\n"));
2074         }
2075   
2076         /* assume the domain name sent is our global_myname and 
2077            send global_sam_sid */
2078         init_samr_r_lookup_domain(&r_u, &global_sam_sid, r_u.status);
2079   
2080         if(!samr_io_r_lookup_domain("", &r_u, rdata, 0)){
2081                 DEBUG(0,("api_samr_lookup_domain: Unable to marshall SAMR_R_LOOKUP_DOMAIN.\n"));
2082                 return False;
2083         }
2084         
2085         return True;
2086 }
2087
2088 /**********************************************************************
2089  api_samr_enum_domains
2090  **********************************************************************/
2091 static BOOL api_samr_enum_domains(pipes_struct *p)
2092 {
2093         SAMR_Q_ENUM_DOMAINS q_u;
2094         SAMR_R_ENUM_DOMAINS r_u;
2095         prs_struct *data = &p->in_data.data;
2096         prs_struct *rdata = &p->out_data.rdata;
2097   
2098         fstring dom[2];
2099
2100         ZERO_STRUCT(q_u);
2101         ZERO_STRUCT(r_u);
2102
2103         fstrcpy(dom[0],global_myworkgroup);
2104         fstrcpy(dom[1],"Builtin");
2105
2106         if(!samr_io_q_enum_domains("", &q_u, data, 0)) {
2107                 DEBUG(0,("api_samr_enum_domains: Unable to unmarshall SAMR_Q_ENUM_DOMAINS.\n"));
2108                 return False;
2109         }
2110
2111         r_u.status = NT_STATUS_NO_PROBLEMO;
2112    
2113         init_samr_r_enum_domains(&r_u, q_u.start_idx, dom, 2); 
2114
2115         if(!samr_io_r_enum_domains("", &r_u, rdata, 0)) {
2116                 DEBUG(0,("api_samr_enum_domains: Unable to marshall SAMR_R_ENUM_DOMAINS.\n"));
2117                 free(r_u.sam);
2118                 free(r_u.uni_dom_name);
2119                 return False;
2120         }
2121
2122         free(r_u.sam);
2123         free(r_u.uni_dom_name);
2124         
2125         return True;
2126 }
2127
2128
2129 /*******************************************************************
2130  api_samr_open_alias
2131  ********************************************************************/
2132 static uint32 _api_samr_open_alias(POLICY_HND domain_pol, uint32 alias_rid, POLICY_HND *alias_pol)
2133 {
2134         DOM_SID sid;
2135         
2136         /* get the domain policy. */
2137         if (find_lsa_policy_by_hnd(&domain_pol) == -1)
2138                 return NT_STATUS_INVALID_HANDLE;
2139
2140         /* get a (unique) handle.  open a policy on it. */
2141         if (!open_lsa_policy_hnd(alias_pol))
2142                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2143
2144         /* Get the domain SID stored in the domain policy */
2145         if(!get_lsa_policy_samr_sid(&domain_pol, &sid)) {
2146                 close_lsa_policy_hnd(alias_pol);
2147                 return NT_STATUS_INVALID_HANDLE;
2148         }
2149
2150         /* append the alias' RID to it */
2151         if(!sid_append_rid(&sid, alias_rid)) {
2152                 close_lsa_policy_hnd(alias_pol);
2153                 return NT_STATUS_NO_SUCH_USER;
2154         }
2155
2156         /* associate a RID with the (unique) handle. */
2157         if (!set_lsa_policy_samr_sid(alias_pol, &sid)) {
2158                 /* oh, whoops.  don't know what error message to return, here */
2159                 close_lsa_policy_hnd(alias_pol);
2160                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2161         }
2162
2163         return NT_STATUS_NO_PROBLEMO;
2164 }
2165
2166 /*******************************************************************
2167  api_samr_open_alias
2168  ********************************************************************/
2169 static BOOL api_samr_open_alias(pipes_struct *p)
2170 {
2171         SAMR_Q_OPEN_ALIAS q_u;
2172         SAMR_R_OPEN_ALIAS r_u;
2173         prs_struct *data = &p->in_data.data;
2174         prs_struct *rdata = &p->out_data.rdata;
2175
2176         ZERO_STRUCT(q_u);
2177         ZERO_STRUCT(r_u);
2178
2179         /* grab the samr open policy */
2180         if(!samr_io_q_open_alias("", &q_u, data, 0)) {
2181                 DEBUG(0,("api_samr_open_alias: Unable to unmarshall SAMR_Q_OPEN_ALIAS.\n"));
2182                 return False;
2183         }
2184
2185         r_u.status=_api_samr_open_alias(q_u.dom_pol, q_u.rid_alias, &r_u.pol);
2186
2187         /* store the response in the SMB stream */
2188         if(!samr_io_r_open_alias("", &r_u, rdata, 0)) {
2189                 DEBUG(0,("api_samr_open_alias: Unable to marshall SAMR_R_OPEN_ALIAS.\n"));
2190                 return False;
2191         }
2192         
2193         return True;
2194 }
2195
2196 /*******************************************************************
2197  set_user_info_10
2198  ********************************************************************/
2199 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid)
2200 {
2201         SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2202
2203         if (id10 == NULL) {
2204                 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2205                 return False;
2206         }
2207
2208         if (pwd == NULL)
2209                 return False;
2210
2211         pdb_set_acct_ctrl(pwd, id10->acb_info);
2212
2213         if(!pdb_update_sam_account(pwd, True))
2214                 return False;
2215
2216         return True;
2217 }
2218
2219 /*******************************************************************
2220  set_user_info_12
2221  ********************************************************************/
2222 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, uint32 rid)
2223 {
2224         SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2225
2226         if (pwd == NULL)
2227                 return False;
2228
2229         if (id12 == NULL) {
2230                 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2231                 return False;
2232         }
2233
2234         pdb_set_lanman_passwd (pwd, id12->lm_pwd); 
2235         pdb_set_nt_passwd     (pwd, id12->nt_pwd); 
2236
2237         if(!pdb_update_sam_account(pwd, True))
2238                 return False;
2239
2240         return True;
2241 }
2242
2243 /*******************************************************************
2244  set_user_info_21
2245  ********************************************************************/
2246 static BOOL set_user_info_21 (SAM_USER_INFO_21 *id21, uint32 rid)
2247 {
2248         SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2249         SAM_ACCOUNT new_pwd;
2250
2251         if (id21 == NULL) {
2252                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2253                 return False;
2254         }
2255
2256         if (pwd == NULL)
2257                 return False;
2258
2259         /* we make a copy so that we can modify stuff */        
2260         copy_sam_passwd(&new_pwd, pwd);
2261         copy_id21_to_sam_passwd(&new_pwd, id21);
2262         
2263         /*
2264          * The funny part about the previous two calls is 
2265          * that pwd still has the password hashes from the 
2266          * passdb entry.  These have not been updated from
2267          * id21.  I don't know if they need to be set.    --jerry
2268          */
2269
2270         /* write the change out */
2271         if(!pdb_update_sam_account(&new_pwd, True))
2272                 return False;
2273         
2274         return True;
2275 }
2276
2277 /*******************************************************************
2278  set_user_info_23
2279  ********************************************************************/
2280 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
2281 {
2282         SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2283         SAM_ACCOUNT new_pwd;
2284         BYTE nt_hash[16];
2285         BYTE lm_hash[16];
2286         pstring buf;
2287         uint32 len;
2288
2289         if (id23 == NULL) {
2290                 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2291                 return False;
2292         }
2293
2294         if (pwd == NULL)
2295                 return False;
2296
2297         copy_sam_passwd(&new_pwd, pwd);
2298         copy_id23_to_sam_passwd(&new_pwd, id23);
2299
2300         if (!decode_pw_buffer((char*)id23->pass, buf, 256, &len))
2301                 return False;
2302
2303         nt_lm_owf_gen(buf, nt_hash, lm_hash);
2304
2305         pdb_set_lanman_passwd (&new_pwd, lm_hash);
2306         pdb_set_nt_passwd     (&new_pwd, nt_hash);
2307
2308         /* update the UNIX password */
2309         if (lp_unix_password_sync())
2310                 if(!chgpasswd(pdb_get_username(&new_pwd), "", buf, True))
2311                         return False;
2312
2313         memset(buf, 0, sizeof(buf));
2314
2315         if(!pdb_update_sam_account(&new_pwd, True))
2316                 return False;
2317         
2318         return True;
2319 }
2320
2321 /*******************************************************************
2322  set_user_info_24
2323  ********************************************************************/
2324 static BOOL set_user_info_24(const SAM_USER_INFO_24 *id24, uint32 rid)
2325 {
2326         SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2327         uchar nt_hash[16];
2328         uchar lm_hash[16];
2329         uint32 len;
2330         pstring buf;
2331
2332         if (pwd == NULL)
2333                 return False;
2334
2335         memset(buf, 0, sizeof(buf));
2336
2337         if (!decode_pw_buffer((char*)id24->pass, buf, 256, &len))
2338                 return False;
2339
2340         DEBUG(0,("set_user_info_24:nt_lm_owf_gen\n"));
2341
2342         nt_lm_owf_gen(buf, nt_hash, lm_hash);
2343
2344         pdb_set_lanman_passwd (pwd, lm_hash);
2345         pdb_set_nt_passwd     (pwd, nt_hash);
2346
2347         /* update the UNIX password */
2348         if (lp_unix_password_sync())
2349                 if(!chgpasswd(pdb_get_username(pwd), "", buf, True))
2350                         return False;
2351
2352         memset(buf, 0, sizeof(buf));
2353         
2354         DEBUG(0,("set_user_info_24: pdb_update_sam_account()\n"));
2355
2356         /* update the SAMBA password */
2357         if(!pdb_update_sam_account(pwd, True))
2358                 return False;
2359
2360         return True;
2361 }
2362
2363 /*******************************************************************
2364  samr_reply_set_userinfo
2365  ********************************************************************/
2366 static uint32 _samr_set_userinfo(POLICY_HND *pol, uint16 switch_value, 
2367                                  SAM_USERINFO_CTR *ctr, pipes_struct *p)
2368 {
2369         uint32 rid = 0x0;
2370         DOM_SID sid;
2371         struct current_user user;
2372         SAM_ACCOUNT *sam_pass;
2373         unsigned char sess_key[16];
2374
2375         DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2376
2377         if (p->ntlmssp_auth_validated) 
2378         {
2379                 memcpy(&user, &p->pipe_user, sizeof(user));
2380         } 
2381         else 
2382         {
2383                 extern struct current_user current_user;
2384                 memcpy(&user, &current_user, sizeof(user));
2385         }
2386
2387         /* search for the handle */
2388         if (find_lsa_policy_by_hnd(pol) == -1)
2389                 return NT_STATUS_INVALID_HANDLE;
2390
2391         /* find the policy handle.  open a policy on it. */
2392         if (!get_lsa_policy_samr_sid(pol, &sid))
2393                 return NT_STATUS_INVALID_HANDLE;
2394
2395         sid_split_rid(&sid, &rid);
2396
2397         DEBUG(5, ("_samr_set_userinfo: rid:0x%x, level:%d\n", rid, switch_value));
2398
2399         if (ctr == NULL) {
2400                 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2401                 return NT_STATUS_INVALID_INFO_CLASS;
2402         }
2403
2404
2405         /* 
2406          * We need the NT hash of the user who is changing the user's password.
2407          * This NT hash is used to generate a "user session key"
2408          * This "user session key" is in turn used to encrypt/decrypt the user's password.
2409          */
2410
2411         become_root();
2412         sam_pass = pdb_getsampwuid(user.uid);
2413         unbecome_root();
2414         if(sam_pass == NULL) {
2415                 DEBUG(0,("_samr_set_userinfo: Unable to get passdb entry for uid %u\n", 
2416                         (unsigned int)pdb_get_uid(sam_pass) ));
2417                 return NT_STATUS_ACCESS_DENIED;
2418         }
2419                 
2420         memset(sess_key, '\0', 16);
2421         mdfour(sess_key, pdb_get_nt_passwd(sam_pass), 16);
2422
2423         /* ok!  user info levels (lots: see MSDEV help), off we go... */
2424         switch (switch_value) {
2425                 case 0x12:
2426                         if (!set_user_info_12(ctr->info.id12, rid))
2427                                 return NT_STATUS_ACCESS_DENIED;
2428                         break;
2429
2430                 case 24:
2431                         SamOEMhash(ctr->info.id24->pass, sess_key, 1);
2432                         if (!set_user_info_24(ctr->info.id24, rid))
2433                                 return NT_STATUS_ACCESS_DENIED;
2434                         break;
2435
2436                 case 23:
2437                         SamOEMhash(ctr->info.id23->pass, sess_key, 1);
2438                         if (!set_user_info_23(ctr->info.id23, rid))
2439                                 return NT_STATUS_ACCESS_DENIED;
2440                         break;
2441
2442                 default:
2443                         return NT_STATUS_INVALID_INFO_CLASS;
2444         }
2445
2446         return NT_STATUS_NOPROBLEMO;
2447 }
2448
2449 /*******************************************************************
2450  api_samr_set_userinfo
2451  ********************************************************************/
2452 static BOOL api_samr_set_userinfo(pipes_struct *p)
2453 {
2454         SAMR_Q_SET_USERINFO q_u;
2455         SAMR_R_SET_USERINFO r_u;
2456
2457         prs_struct *data = &p->in_data.data;
2458         prs_struct *rdata = &p->out_data.rdata;
2459
2460         SAM_USERINFO_CTR ctr;
2461
2462         ZERO_STRUCT(q_u);
2463         ZERO_STRUCT(r_u);
2464
2465         q_u.ctr = &ctr;
2466
2467         if (!samr_io_q_set_userinfo("", &q_u, data, 0)) {
2468                 DEBUG(0,("api_samr_set_userinfo: Unable to unmarshall SAMR_Q_SET_USERINFO.\n"));
2469                 return False;
2470         }
2471
2472         r_u.status = _samr_set_userinfo(&q_u.pol, q_u.switch_value, &ctr, p);
2473
2474         free_samr_q_set_userinfo(&q_u);
2475         
2476         if(!samr_io_r_set_userinfo("", &r_u, rdata, 0)) {
2477                 DEBUG(0,("api_samr_set_userinfo: Unable to marshall SAMR_R_SET_USERINFO.\n"));
2478                 return False;
2479         }
2480
2481         return True;
2482 }
2483
2484 /*******************************************************************
2485  samr_reply_set_userinfo2
2486  ********************************************************************/
2487 static uint32 _samr_set_userinfo2(POLICY_HND *pol, uint16 switch_value, SAM_USERINFO_CTR *ctr)
2488 {
2489         DOM_SID sid;
2490         uint32 rid = 0x0;
2491
2492         DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
2493
2494         /* search for the handle */
2495         if (find_lsa_policy_by_hnd(pol) == -1)
2496                 return NT_STATUS_INVALID_HANDLE;
2497
2498         /* find the policy handle.  open a policy on it. */
2499         if (!get_lsa_policy_samr_sid(pol, &sid))
2500                 return NT_STATUS_INVALID_HANDLE;
2501
2502         sid_split_rid(&sid, &rid);
2503
2504         DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid));
2505
2506         if (ctr == NULL) {
2507                 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
2508                 return NT_STATUS_INVALID_INFO_CLASS;
2509         }
2510
2511         ctr->switch_value = switch_value;
2512
2513         /* ok!  user info levels (lots: see MSDEV help), off we go... */
2514         switch (switch_value) {
2515                 case 21:
2516                         if (!set_user_info_21(ctr->info.id21, rid))
2517                                 return NT_STATUS_ACCESS_DENIED;
2518                         break;
2519                 case 16:
2520                         if (!set_user_info_10(ctr->info.id10, rid))
2521                                 return NT_STATUS_ACCESS_DENIED;
2522                         break;
2523                 default:
2524                         return NT_STATUS_INVALID_INFO_CLASS;
2525         }
2526
2527         return NT_STATUS_NOPROBLEMO;
2528 }
2529
2530 /*******************************************************************
2531  api_samr_set_userinfo2
2532  ********************************************************************/
2533 static BOOL api_samr_set_userinfo2(pipes_struct *p)
2534 {
2535         SAMR_Q_SET_USERINFO2 q_u;
2536         SAMR_R_SET_USERINFO2 r_u;
2537         SAM_USERINFO_CTR ctr;
2538
2539         prs_struct *data = &p->in_data.data;
2540         prs_struct *rdata = &p->out_data.rdata;
2541
2542         ZERO_STRUCT(q_u);
2543         ZERO_STRUCT(r_u);
2544
2545         q_u.ctr = &ctr;
2546
2547         if (!samr_io_q_set_userinfo2("", &q_u, data, 0)) {
2548                 DEBUG(0,("api_samr_set_userinfo2: Unable to unmarshall SAMR_Q_SET_USERINFO2.\n"));
2549                 return False;
2550         }
2551
2552         r_u.status = _samr_set_userinfo2(&q_u.pol, q_u.switch_value, &ctr);
2553
2554         free_samr_q_set_userinfo2(&q_u);
2555
2556         if(!samr_io_r_set_userinfo2("", &r_u, rdata, 0)) {
2557                 DEBUG(0,("api_samr_set_userinfo2: Unable to marshall SAMR_R_SET_USERINFO2.\n"));
2558                 return False;
2559         }
2560
2561         return True;
2562 }
2563
2564
2565 /*******************************************************************
2566  array of \PIPE\samr operations
2567  ********************************************************************/
2568 static struct api_struct api_samr_cmds [] =
2569 {
2570         { "SAMR_CLOSE_HND"        , SAMR_CLOSE_HND        , api_samr_close_hnd        },
2571         { "SAMR_CONNECT"          , SAMR_CONNECT          , api_samr_connect          },
2572         { "SAMR_CONNECT_ANON"     , SAMR_CONNECT_ANON     , api_samr_connect_anon     },
2573         { "SAMR_ENUM_DOM_USERS"   , SAMR_ENUM_DOM_USERS   , api_samr_enum_dom_users   },
2574         { "SAMR_ENUM_DOM_GROUPS"  , SAMR_ENUM_DOM_GROUPS  , api_samr_enum_dom_groups  },
2575         { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
2576         { "SAMR_LOOKUP_IDS"       , SAMR_LOOKUP_IDS       , api_samr_lookup_ids       },
2577         { "SAMR_LOOKUP_NAMES"     , SAMR_LOOKUP_NAMES     , api_samr_lookup_names     },
2578         { "SAMR_OPEN_USER"        , SAMR_OPEN_USER        , api_samr_open_user        },
2579         { "SAMR_QUERY_USERINFO"   , SAMR_QUERY_USERINFO   , api_samr_query_userinfo   },
2580         { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info   },
2581         { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
2582         { "SAMR_QUERY_DISPINFO"   , SAMR_QUERY_DISPINFO   , api_samr_query_dispinfo   },
2583         { "SAMR_QUERY_ALIASINFO"  , SAMR_QUERY_ALIASINFO  , api_samr_query_aliasinfo  },
2584         { "SAMR_CREATE_USER"      , SAMR_CREATE_USER      , api_samr_create_user      },
2585         { "SAMR_LOOKUP_RIDS"      , SAMR_LOOKUP_RIDS      , api_samr_lookup_rids      },
2586         { "SAMR_UNKNOWN_38"       , SAMR_UNKNOWN_38       , api_samr_unknown_38       },
2587         { "SAMR_CHGPASSWD_USER"   , SAMR_CHGPASSWD_USER   , api_samr_chgpasswd_user   },
2588         { "SAMR_OPEN_ALIAS"       , SAMR_OPEN_ALIAS       , api_samr_open_alias       },
2589         { "SAMR_OPEN_DOMAIN"      , SAMR_OPEN_DOMAIN      , api_samr_open_domain      },
2590         { "SAMR_UNKNOWN_3"        , SAMR_UNKNOWN_3        , api_samr_unknown_3        },
2591         { "SAMR_UNKNOWN_2C"       , SAMR_UNKNOWN_2C       , api_samr_unknown_2c       },
2592         { "SAMR_LOOKUP_DOMAIN"    , SAMR_LOOKUP_DOMAIN    , api_samr_lookup_domain    },
2593         { "SAMR_ENUM_DOMAINS"     , SAMR_ENUM_DOMAINS     , api_samr_enum_domains     },
2594         { "SAMR_SET_USERINFO"     , SAMR_SET_USERINFO     , api_samr_set_userinfo     },
2595         { "SAMR_SET_USERINFO2"    , SAMR_SET_USERINFO2    , api_samr_set_userinfo2    },
2596         { NULL                    , 0                     , NULL                      }
2597 };
2598
2599 /*******************************************************************
2600  receives a samr pipe and responds.
2601  ********************************************************************/
2602 BOOL api_samr_rpc(pipes_struct *p)
2603 {
2604         return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds);
2605 }
2606 #undef OLD_NTDOMAIN