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