Make smbd/posix_acls.c use abstract interface.
[Samba.git] / source / rpc_server / srv_samr.c
blobed3cf7df82779b2ce8c169da9b93b4697612a7ac
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.
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.
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.
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.
26 #include "includes.h"
28 extern int DEBUGLEVEL;
30 extern fstring global_myworkgroup;
31 extern pstring global_myname;
32 extern DOM_SID global_sam_sid;
34 extern rid_name domain_group_rids[];
35 extern rid_name domain_alias_rids[];
36 extern rid_name builtin_alias_rids[];
38 /*******************************************************************
39 This next function should be replaced with something that
40 dynamically returns the correct user info..... JRA.
41 ********************************************************************/
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)
47 SAM_ACCOUNT *pwd = NULL;
49 (*num_entries) = 0;
50 (*total_entries) = 0;
52 if (pw_buf == NULL)
53 return False;
55 if (!pdb_setsampwent(False))
57 DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n"));
58 return False;
61 while ( ((pwd=pdb_getsampwent()) != NULL) && ((*num_entries) < max_num_entries) )
63 int user_name_len;
65 if (start_idx > 0) {
66 /* skip the requested number of entries.
67 not very efficient, but hey...
69 start_idx--;
70 continue;
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);
79 /* Now check if the NT compatible password is available. */
80 if (pdb_get_nt_passwd(pwd) != NULL)
82 memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
85 pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
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)));
91 if (acb_mask == 0 || (pdb_get_acct_ctrl(pwd) & acb_mask))
93 DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
94 (*num_entries)++;
96 else
98 DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
101 (*total_entries)++;
104 pdb_endsampwent();
106 return (*num_entries) > 0;
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 ********************************************************************/
121 static char *unmap_unixname(char *unix_user_name, int name_idx)
123 char *mapfile = lp_username_map();
124 char **lines;
125 static pstring tok;
126 int i;
128 if (!*unix_user_name) return NULL;
129 if (!*mapfile) return NULL;
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;
137 DEBUG(5,("unmap_unixname: scanning username map %s, index: %d\n", mapfile, name_idx));
139 for (i=0; lines[i]; i++) {
140 char *unixname = lines[i];
141 char *dosname = strchr(unixname,'=');
143 if (!dosname)
144 continue;
146 *dosname++ = 0;
148 while (isspace(*unixname))
149 unixname++;
150 if ('!' == *unixname) {
151 unixname++;
152 while (*unixname && isspace(*unixname))
153 unixname++;
156 if (!*unixname || strchr("#;",*unixname))
157 continue;
159 if (strncmp(unixname, unix_user_name, strlen(unix_user_name)))
160 continue;
162 /* We have matched the UNIX user name */
164 while(next_token(&dosname, tok, LIST_SEP, sizeof(tok))) {
165 if (!strchr("@&+", *tok)) {
166 name_idx--;
167 if (name_idx < 0 ) {
168 break;
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;
183 DEBUG(0,("unmap_unixname: Couldn't find the UNIX user name\n"));
184 file_lines_free(lines);
185 return NULL;
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 ********************************************************************/
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)
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;
208 DEBUG(5, ("get_passwd_entries: retrieving a list of UNIX users\n"));
210 (*num_entries) = 0;
211 (*total_entries) = 0;
213 if (pw_buf == NULL) return False;
215 if (current_idx == 0) {
216 setpwent();
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;
228 if(!orig_done) {
229 if ((pwd = getpwent()) == NULL) break;
230 current_idx++;
231 orig_done = True;
234 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
235 (current_idx < start_idx)) {
236 current_idx++;
237 mapped_idx++;
240 if (unmap_name == NULL) {
241 orig_done = False;
242 mapped_idx = 0;
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;
255 if(!orig_done) {
256 if ((pwd = getpwent()) == NULL) break;
257 current_idx++;
258 orig_done = True;
261 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
262 (current_idx < start_idx)) {
263 current_idx++;
264 mapped_idx++;
267 if (unmap_name == NULL) {
268 orig_done = False;
269 mapped_idx = 0;
274 sep = lp_winbind_separator();
276 /* now current_idx == start_idx */
277 while ((*num_entries) < max_num_entries) {
278 int user_name_len;
279 char *unmap_name;
281 /* This does the original UNIX user itself */
282 if(!orig_done) {
283 if ((pwd = getpwent()) == NULL) break;
285 /* Don't enumerate winbind users as they are not local */
287 if (strchr(pwd->pw_name, *sep) != NULL) {
288 continue;
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);
299 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
301 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
303 (*num_entries)++;
304 (*total_entries)++;
305 current_idx++;
306 orig_done = True;
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);
319 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
321 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
323 (*num_entries)++;
324 (*total_entries)++;
325 current_idx++;
326 mapped_idx++;
329 if (unmap_name == NULL) {
330 /* done with 'aliases', go on to next UNIX user */
331 orig_done = False;
332 mapped_idx = 0;
336 if (pwd == NULL) {
337 /* totally done, reset everything */
338 endpwent();
339 current_idx = 0;
340 mapped_idx = 0;
343 return (*num_entries) > 0;
346 /*******************************************************************
347 samr_reply_unknown_1
348 ********************************************************************/
349 static BOOL samr_reply_close_hnd(SAMR_Q_CLOSE_HND *q_u,
350 prs_struct *rdata)
352 SAMR_R_CLOSE_HND r_u;
354 /* set up the SAMR unknown_1 response */
355 memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
357 /* close the policy handle */
358 if (close_lsa_policy_hnd(&(q_u->pol)))
360 r_u.status = 0;
362 else
364 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_INVALID;
367 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
369 /* store the response in the SMB stream */
370 if(!samr_io_r_close_hnd("", &r_u, rdata, 0))
371 return False;
373 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
375 return True;
378 /*******************************************************************
379 api_samr_close_hnd
380 ********************************************************************/
381 static BOOL api_samr_close_hnd(pipes_struct *p)
383 SAMR_Q_CLOSE_HND q_u;
384 prs_struct *data = &p->in_data.data;
385 prs_struct *rdata = &p->out_data.rdata;
387 /* grab the samr unknown 1 */
388 if(!samr_io_q_close_hnd("", &q_u, data, 0))
389 return False;
391 /* construct reply. always indicate success */
392 if(!samr_reply_close_hnd(&q_u, rdata))
393 return False;
395 return True;
399 /*******************************************************************
400 samr_reply_open_domain
401 ********************************************************************/
402 static BOOL samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
403 prs_struct *rdata)
405 SAMR_R_OPEN_DOMAIN r_u;
406 BOOL pol_open = False;
408 r_u.status = 0x0;
410 /* find the connection policy handle. */
411 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->connect_pol)) == -1))
413 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
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))))
419 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
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)))
425 /* oh, whoops. don't know what error message to return, here */
426 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
429 if (r_u.status != 0 && pol_open)
431 close_lsa_policy_hnd(&(r_u.domain_pol));
434 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
436 /* store the response in the SMB stream */
437 if(!samr_io_r_open_domain("", &r_u, rdata, 0))
438 return False;
440 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
442 return True;
445 /*******************************************************************
446 api_samr_open_domain
447 ********************************************************************/
448 static BOOL api_samr_open_domain(pipes_struct *p)
450 SAMR_Q_OPEN_DOMAIN q_u;
451 prs_struct *data = &p->in_data.data;
452 prs_struct *rdata = &p->out_data.rdata;
454 /* grab the samr open */
455 if(!samr_io_q_open_domain("", &q_u, data, 0))
456 return False;
458 /* construct reply. always indicate success */
459 if(!samr_reply_open_domain(&q_u, rdata))
460 return False;
462 return True;
466 /*******************************************************************
467 samr_reply_unknown_2c
468 ********************************************************************/
469 static BOOL samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u,
470 prs_struct *rdata)
472 SAMR_R_UNKNOWN_2C r_u;
473 uint32 status = 0x0;
475 /* find the policy handle. open a policy on it. */
476 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
478 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
481 /* find the user's rid */
482 if ((status == 0x0) && (get_lsa_policy_samr_rid(&(q_u->user_pol)) == 0xffffffff))
484 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
487 init_samr_r_unknown_2c(&r_u, status);
489 DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
491 /* store the response in the SMB stream */
492 if(!samr_io_r_unknown_2c("", &r_u, rdata, 0))
493 return False;
495 DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
497 return True;
500 /*******************************************************************
501 api_samr_unknown_2c
502 ********************************************************************/
503 static BOOL api_samr_unknown_2c(pipes_struct *p)
505 SAMR_Q_UNKNOWN_2C q_u;
506 prs_struct *data = &p->in_data.data;
507 prs_struct *rdata = &p->out_data.rdata;
509 /* grab the samr open */
510 if(!samr_io_q_unknown_2c("", &q_u, data, 0))
511 return False;
513 /* construct reply. always indicate success */
514 if(!samr_reply_unknown_2c(&q_u, rdata))
515 return False;
517 return True;
521 /*******************************************************************
522 samr_reply_unknown_3
523 ********************************************************************/
524 static BOOL samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
525 prs_struct *rdata)
527 SAMR_R_UNKNOWN_3 r_u;
528 DOM_SID3 sid[MAX_SAM_SIDS];
529 uint32 rid;
530 uint32 status;
532 status = 0x0;
534 /* find the policy handle. open a policy on it. */
535 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
537 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
540 /* find the user's rid */
541 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->user_pol))) == 0xffffffff)
543 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
546 if (status == 0x0)
548 DOM_SID user_sid;
549 DOM_SID everyone_sid;
551 user_sid = global_sam_sid;
553 SMB_ASSERT_ARRAY(user_sid.sub_auths, user_sid.num_auths+1);
556 * Add the user RID.
558 user_sid.sub_auths[user_sid.num_auths++] = rid;
560 string_to_sid(&everyone_sid, "S-1-1");
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);
568 init_samr_r_unknown_3(&r_u,
569 0x0001, 0x8004,
570 0x00000014, 0x0002, 0x0070,
571 2, sid, status);
573 DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
575 /* store the response in the SMB stream */
576 if(!samr_io_r_unknown_3("", &r_u, rdata, 0))
577 return False;
579 DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
581 return True;
584 /*******************************************************************
585 api_samr_unknown_3
586 ********************************************************************/
587 static BOOL api_samr_unknown_3(pipes_struct *p)
589 SAMR_Q_UNKNOWN_3 q_u;
590 prs_struct *data = &p->in_data.data;
591 prs_struct *rdata = &p->out_data.rdata;
593 /* grab the samr open */
594 if(!samr_io_q_unknown_3("", &q_u, data, 0))
595 return False;
597 /* construct reply. always indicate success */
598 if(!samr_reply_unknown_3(&q_u, rdata))
599 return False;
601 return True;
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)
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;
616 ZERO_STRUCT(r_e);
618 r_e.status = 0x0;
619 r_e.total_num_entries = 0;
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))
624 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
627 DEBUG(5,("samr_reply_enum_dom_users: %d\n", __LINE__));
629 become_root();
630 get_sampwd_entries(pass, 0, &total_entries, &num_entries, MAX_SAM_ENTRIES, q_u->acb_mask);
631 unbecome_root();
633 init_samr_r_enum_dom_users(&r_e, total_entries,
634 q_u->unknown_0, num_entries,
635 pass, r_e.status);
637 /* store the response in the SMB stream */
638 if(!samr_io_r_enum_dom_users("", &r_e, rdata, 0))
639 return False;
641 DEBUG(5,("samr_enum_dom_users: %d\n", __LINE__));
643 return True;
646 /*******************************************************************
647 api_samr_enum_dom_users
648 ********************************************************************/
649 static BOOL api_samr_enum_dom_users(pipes_struct *p)
651 SAMR_Q_ENUM_DOM_USERS q_e;
652 prs_struct *data = &p->in_data.data;
653 prs_struct *rdata = &p->out_data.rdata;
655 /* grab the samr open */
656 if(!samr_io_q_enum_dom_users("", &q_e, data, 0))
657 return False;
659 /* construct reply. */
660 if(!samr_reply_enum_dom_users(&q_e, rdata))
661 return False;
663 return True;
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)
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";
678 ZERO_STRUCT(r_e);
680 r_e.status = 0x0;
681 r_e.num_entries = 0;
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))
686 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
689 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
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;
697 if (r_e.status == 0 && got_grps)
699 init_samr_r_enum_dom_groups(&r_e, q_u->start_idx, num_entries, pass, r_e.status);
702 /* store the response in the SMB stream */
703 if(!samr_io_r_enum_dom_groups("", &r_e, rdata, 0))
704 return False;
706 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
708 return True;
711 /*******************************************************************
712 api_samr_enum_dom_groups
713 ********************************************************************/
714 static BOOL api_samr_enum_dom_groups(pipes_struct *p)
716 SAMR_Q_ENUM_DOM_GROUPS q_e;
717 prs_struct *data = &p->in_data.data;
718 prs_struct *rdata = &p->out_data.rdata;
720 /* grab the samr open */
721 if(!samr_io_q_enum_dom_groups("", &q_e, data, 0))
722 return False;
724 /* construct reply. */
725 if(!samr_reply_enum_dom_groups(&q_e, rdata))
726 return False;
728 return True;
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)
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;
745 ZERO_STRUCT(r_e);
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))
750 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
753 sid_to_string(sid_str, &sid);
754 sid_to_string(sam_sid_str, &global_sam_sid);
756 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
758 /* well-known aliases */
759 if (strequal(sid_str, "S-1-5-32"))
761 char *name;
762 while (num_entries < MAX_SAM_ENTRIES && ((name = builtin_alias_rids[num_entries].name) != NULL))
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++;
769 else if (strequal(sid_str, sam_sid_str))
771 char *name;
772 char *sep;
774 sep = lp_winbind_separator();
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();
782 while (num_entries < MAX_SAM_ENTRIES && ((grp = getgrent()) != NULL))
784 name = grp->gr_name;
786 /* Don't return winbind groups as they are not local! */
788 if (strchr(name, *sep) != NULL) {
789 continue;
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++;
797 endgrent();
800 init_samr_r_enum_dom_aliases(&r_e, num_entries, pass, r_e.status);
802 /* store the response in the SMB stream */
803 if(!samr_io_r_enum_dom_aliases("", &r_e, rdata, 0))
804 return False;
806 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
808 return True;
811 /*******************************************************************
812 api_samr_enum_dom_aliases
813 ********************************************************************/
814 static BOOL api_samr_enum_dom_aliases(pipes_struct *p)
816 SAMR_Q_ENUM_DOM_ALIASES q_e;
817 prs_struct *data = &p->in_data.data;
818 prs_struct *rdata = &p->out_data.rdata;
820 ZERO_STRUCT(q_e);
822 /* grab the samr open */
823 if(!samr_io_q_enum_dom_aliases("", &q_e, data, 0))
824 return False;
826 /* construct reply. */
827 if(!samr_reply_enum_dom_aliases(&q_e, rdata))
828 return False;
830 return True;
834 /*******************************************************************
835 samr_reply_query_dispinfo
836 ********************************************************************/
837 static BOOL samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u, prs_struct *rdata)
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;
849 ZERO_STRUCT(r_e);
851 DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
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))
856 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
857 DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n"));
860 if (r_e.status == 0x0)
862 /* decide how many entries to get depending on the max_entries
863 and max_size passed by client */
864 uint32 retsize;
866 if(q_u->max_entries > MAX_SAM_ENTRIES)
867 q_u->max_entries = MAX_SAM_ENTRIES;
869 retsize = (q_u->max_entries * (sizeof(SAM_ENTRY1)+sizeof(SAM_STR1)))
870 + 3*sizeof(uint32);
872 if(retsize > q_u->max_size)
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);
880 DEBUG(10,("samr_reply_query_dispinfo: Setting q_u->max_entries to %u\n",q_u->max_entries));
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();
886 /* more left - set resume handle */
887 if(total_entries > num_entries)
889 r_e.status = 0x105;
892 switch (q_u->switch_level)
894 case 0x1:
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);
903 ctr.sam.info1 = &info1;
905 break;
907 case 0x2:
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);
915 ctr.sam.info2 = &info2;
917 break;
922 /* more left - set resume handle */
923 if(total_entries > num_entries)
925 r_e.status = 0x105;
928 if (r_e.status == 0 || r_e.status == 0x105)
930 init_samr_r_query_dispinfo(&r_e, switch_level, &ctr, r_e.status);
933 /* store the response in the SMB stream */
934 if(!samr_io_r_query_dispinfo("", &r_e, rdata, 0))
935 return False;
937 DEBUG(5,("samr_query_dispinfo: %d\n", __LINE__));
939 return True;
942 /*******************************************************************
943 api_samr_query_dispinfo
944 ********************************************************************/
945 static BOOL api_samr_query_dispinfo(pipes_struct *p)
947 SAMR_Q_QUERY_DISPINFO q_e;
948 prs_struct *data = &p->in_data.data;
949 prs_struct *rdata = &p->out_data.rdata;
951 /* grab the samr open */
952 if(!samr_io_q_query_dispinfo("", &q_e, data, 0))
953 return False;
955 /* construct reply. */
956 if(!samr_reply_query_dispinfo(&q_e, rdata))
957 return False;
959 return True;
963 /*******************************************************************
964 samr_reply_query_aliasinfo
965 ********************************************************************/
966 static BOOL samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
967 prs_struct *rdata)
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;
975 ZERO_STRUCT(r_e);
977 DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__));
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))
982 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
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;
989 if(!local_lookup_rid(alias_rid, alias, &type))
991 r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
994 init_samr_r_query_aliasinfo(&r_e, q_u->switch_level, alias, alias_desc);
996 /* store the response in the SMB stream */
997 if(!samr_io_r_query_aliasinfo("", &r_e, rdata, 0))
998 return False;
1000 DEBUG(5,("samr_query_aliasinfo: %d\n", __LINE__));
1002 return True;
1005 /*******************************************************************
1006 api_samr_query_aliasinfo
1007 ********************************************************************/
1008 static BOOL api_samr_query_aliasinfo(pipes_struct *p)
1010 SAMR_Q_QUERY_ALIASINFO q_e;
1011 prs_struct *data = &p->in_data.data;
1012 prs_struct *rdata = &p->out_data.rdata;
1014 /* grab the samr open */
1015 if(!samr_io_q_query_aliasinfo("", &q_e, data, 0))
1016 return False;
1018 /* construct reply. */
1019 if(!samr_reply_query_aliasinfo(&q_e, rdata))
1020 return False;
1022 return True;
1026 /*******************************************************************
1027 samr_reply_lookup_ids
1028 ********************************************************************/
1029 static BOOL samr_reply_lookup_ids(SAMR_Q_LOOKUP_IDS *q_u,
1030 prs_struct *rdata)
1032 uint32 rid[MAX_SAM_ENTRIES];
1033 uint32 status = 0;
1034 int num_rids = q_u->num_sids1;
1036 SAMR_R_LOOKUP_IDS r_u;
1038 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
1040 if (num_rids > MAX_SAM_ENTRIES)
1042 num_rids = MAX_SAM_ENTRIES;
1043 DEBUG(5,("samr_lookup_ids: truncating entries to %d\n", num_rids));
1046 #if 0
1047 int i;
1048 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1050 for (i = 0; i < num_rids && status == 0; i++)
1052 SAM_ACCOUNT *sam_pass;
1053 fstring user_name;
1056 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1057 q_u->uni_user_name[i].uni_str_len));
1059 /* find the user account */
1060 become_root();
1061 sam_pass = pdb_getsampwnam(user_name);
1062 unbecome_root();
1064 if (sam_pass == NULL)
1066 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1067 rid[i] = 0;
1069 else
1071 rid[i] = pdb_get_user_rid(sam_pass);
1074 #endif
1076 num_rids = 1;
1077 rid[0] = BUILTIN_ALIAS_RID_USERS;
1079 init_samr_r_lookup_ids(&r_u, num_rids, rid, status);
1081 /* store the response in the SMB stream */
1082 if(!samr_io_r_lookup_ids("", &r_u, rdata, 0))
1083 return False;
1085 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
1087 return True;
1090 /*******************************************************************
1091 api_samr_lookup_ids
1092 ********************************************************************/
1093 static BOOL api_samr_lookup_ids(pipes_struct *p)
1095 SAMR_Q_LOOKUP_IDS q_u;
1096 prs_struct *data = &p->in_data.data;
1097 prs_struct *rdata = &p->out_data.rdata;
1099 /* grab the samr 0x10 */
1100 if(!samr_io_q_lookup_ids("", &q_u, data, 0))
1101 return False;
1103 /* construct reply. always indicate success */
1104 if(!samr_reply_lookup_ids(&q_u, rdata))
1105 return False;
1107 return True;
1110 /*******************************************************************
1111 samr_reply_lookup_names
1112 ********************************************************************/
1114 static BOOL samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
1115 prs_struct *rdata)
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;
1124 SAMR_R_LOOKUP_NAMES r_u;
1126 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1128 ZERO_ARRAY(rid);
1129 ZERO_ARRAY(type);
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;
1138 return True;
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));
1146 SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
1148 for (i = 0; i < num_rids; i++) {
1149 fstring name;
1151 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
1153 rid [i] = 0xffffffff;
1154 type[i] = SID_NAME_UNKNOWN;
1156 fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer,
1157 q_u->uni_name[i].uni_str_len));
1159 if(sid_equal(&pol_sid, &global_sam_sid))
1161 DOM_SID sid;
1162 if(local_lookup_name(global_myname, name,
1163 &sid, &type[i]))
1165 sid_split_rid( &sid, &rid[i]);
1166 status = 0;
1171 init_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
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;
1179 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1181 return True;
1184 /*******************************************************************
1185 api_samr_lookup_names
1186 ********************************************************************/
1188 static BOOL api_samr_lookup_names(pipes_struct *p)
1190 SAMR_Q_LOOKUP_NAMES q_u;
1191 prs_struct *data = &p->in_data.data;
1192 prs_struct *rdata = &p->out_data.rdata;
1194 memset(&q_u, '\0', sizeof(q_u));
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;
1202 /* construct reply. always indicate success */
1203 if(!samr_reply_lookup_names(&q_u, rdata))
1204 return False;
1206 return True;
1209 /*******************************************************************
1210 samr_reply_chgpasswd_user
1211 ********************************************************************/
1213 static BOOL samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
1214 prs_struct *rdata)
1216 SAMR_R_CHGPASSWD_USER r_u;
1217 uint32 status = 0x0;
1218 fstring user_name;
1219 fstring wks;
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));
1224 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
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))
1230 status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
1233 init_samr_r_chgpasswd_user(&r_u, status);
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;
1241 DEBUG(5,("samr_chgpasswd_user: %d\n", __LINE__));
1242 return True;
1245 /*******************************************************************
1246 api_samr_chgpasswd_user
1247 ********************************************************************/
1249 static BOOL api_samr_chgpasswd_user(pipes_struct *p)
1251 SAMR_Q_CHGPASSWD_USER q_u;
1252 prs_struct *data = &p->in_data.data;
1253 prs_struct *rdata = &p->out_data.rdata;
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;
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;
1267 return True;
1271 /*******************************************************************
1272 samr_reply_unknown_38
1273 ********************************************************************/
1274 static BOOL samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u, prs_struct *rdata)
1276 SAMR_R_UNKNOWN_38 r_u;
1278 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1280 init_samr_r_unknown_38(&r_u);
1282 /* store the response in the SMB stream */
1283 if(!samr_io_r_unknown_38("", &r_u, rdata, 0))
1284 return False;
1286 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1287 return True;
1290 /*******************************************************************
1291 api_samr_unknown_38
1292 ********************************************************************/
1293 static BOOL api_samr_unknown_38(pipes_struct *p)
1295 SAMR_Q_UNKNOWN_38 q_u;
1296 prs_struct *data = &p->in_data.data;
1297 prs_struct *rdata = &p->out_data.rdata;
1299 /* unknown 38 command */
1300 if(!samr_io_q_unknown_38("", &q_u, data, 0))
1301 return False;
1303 /* construct reply. always indicate success */
1304 if(!samr_reply_unknown_38(&q_u, rdata))
1305 return False;
1307 return True;
1311 /*******************************************************************
1312 samr_reply_lookup_rids
1313 ********************************************************************/
1314 static BOOL samr_reply_lookup_rids(SAMR_Q_LOOKUP_RIDS *q_u,
1315 prs_struct *rdata)
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;
1322 SAMR_R_LOOKUP_RIDS r_u;
1324 DEBUG(5,("samr_reply_lookup_rids: %d\n", __LINE__));
1326 /* find the policy handle. open a policy on it. */
1327 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1329 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1332 if (status == 0x0)
1334 int i;
1335 if (num_gids > MAX_SAM_ENTRIES)
1337 num_gids = MAX_SAM_ENTRIES;
1338 DEBUG(5,("samr_reply_lookup_rids: truncating entries to %d\n", num_gids));
1341 for (i = 0; i < num_gids && status == 0; i++)
1343 fstrcpy(group_names[i], "dummy group");
1344 group_attrs[i] = 0x2;
1348 init_samr_r_lookup_rids(&r_u, num_gids, group_names, group_attrs, status);
1350 /* store the response in the SMB stream */
1351 if(!samr_io_r_lookup_rids("", &r_u, rdata, 0))
1352 return False;
1354 DEBUG(5,("samr_reply_lookup_rids: %d\n", __LINE__));
1356 return True;
1359 /*******************************************************************
1360 api_samr_lookup_rids
1361 ********************************************************************/
1362 static BOOL api_samr_lookup_rids(pipes_struct *p)
1364 SAMR_Q_LOOKUP_RIDS q_u;
1365 prs_struct *data = &p->in_data.data;
1366 prs_struct *rdata = &p->out_data.rdata;
1368 /* grab the samr lookup names */
1369 if(!samr_io_q_lookup_rids("", &q_u, data, 0))
1370 return False;
1372 /* construct reply. always indicate success */
1373 if(!samr_reply_lookup_rids(&q_u, rdata))
1374 return False;
1376 return True;
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)
1385 SAM_ACCOUNT *sam_pass;
1386 DOM_SID sid;
1388 /* find the domain policy handle. */
1389 if (find_lsa_policy_by_hnd(&domain_pol) == -1)
1390 return NT_STATUS_INVALID_HANDLE;
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;
1396 become_root();
1397 sam_pass = pdb_getsampwrid(user_rid);
1398 unbecome_root();
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;
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;
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;
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;
1425 return NT_STATUS_NO_PROBLEMO;
1428 /*******************************************************************
1429 api_samr_open_user
1430 ********************************************************************/
1431 static BOOL api_samr_open_user(pipes_struct *p)
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;
1438 ZERO_STRUCT(q_u);
1439 ZERO_STRUCT(r_u);
1441 /* grab the samr unknown 22 */
1442 if(!samr_io_q_open_user("", &q_u, data, 0))
1443 return False;
1445 r_u.status = _api_samr_open_user(q_u.domain_pol, q_u.user_rid, &r_u.user_pol);
1447 /* store the response in the SMB stream */
1448 if(!samr_io_r_open_user("", &r_u, rdata, 0))
1449 return False;
1451 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1453 return True;
1456 /*************************************************************************
1457 get_user_info_10
1458 *************************************************************************/
1459 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1461 SAM_ACCOUNT *sampass;
1463 if (!pdb_rid_is_user(user_rid))
1465 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1466 return False;
1469 become_root();
1470 sampass = pdb_getsampwrid(user_rid);
1471 unbecome_root();
1473 if (sampass == NULL)
1475 DEBUG(4,("User 0x%x not found\n", user_rid));
1476 return False;
1479 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass)));
1481 init_sam_user_info10(id10, pdb_get_acct_ctrl(sampass));
1483 return True;
1486 /*************************************************************************
1487 get_user_info_21
1488 *************************************************************************/
1489 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1491 SAM_ACCOUNT *sam_pass;
1493 if (!pdb_rid_is_user(user_rid))
1495 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1496 return False;
1499 become_root();
1500 sam_pass = pdb_getsampwrid(user_rid);
1501 unbecome_root();
1503 if (sam_pass == NULL)
1505 DEBUG(4,("User 0x%x not found\n", user_rid));
1506 return False;
1509 DEBUG(3,("User:[%s]\n", pdb_get_username(sam_pass)));
1511 init_sam_user_info21(id21, sam_pass);
1513 return True;
1516 /*******************************************************************
1517 samr_reply_query_userinfo
1518 ********************************************************************/
1519 static BOOL samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
1520 prs_struct *rdata)
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;
1530 uint32 status = 0x0;
1531 uint32 rid = 0x0;
1533 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1535 /* search for the handle */
1536 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1538 status = NT_STATUS_INVALID_HANDLE;
1541 /* find the user's rid */
1542 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1544 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1547 DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
1549 /* ok! user info levels (there are lots: see MSDEV help), off we go... */
1550 if (status == 0x0)
1552 switch (q_u->switch_value)
1554 case 0x10:
1556 info = (void*)&id10;
1557 status = get_user_info_10(&id10, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1558 break;
1560 #if 0
1561 /* whoops - got this wrong. i think. or don't understand what's happening. */
1562 case 0x11:
1564 NTTIME expire;
1565 info = (void*)&id11;
1567 expire.low = 0xffffffff;
1568 expire.high = 0x7fffffff;
1570 make_sam_user_info11(&id11, &expire, "BROOKFIELDS$", 0x03ef, 0x201, 0x0080);
1572 break;
1574 #endif
1575 case 21:
1577 info = (void*)&id21;
1578 status = get_user_info_21(&id21, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1579 break;
1582 default:
1584 status = NT_STATUS_INVALID_INFO_CLASS;
1586 break;
1591 init_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
1593 /* store the response in the SMB stream */
1594 if(!samr_io_r_query_userinfo("", &r_u, rdata, 0))
1595 return False;
1597 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1599 return True;
1602 /*******************************************************************
1603 api_samr_query_userinfo
1604 ********************************************************************/
1605 static BOOL api_samr_query_userinfo(pipes_struct *p)
1607 SAMR_Q_QUERY_USERINFO q_u;
1608 prs_struct *data = &p->in_data.data;
1609 prs_struct *rdata = &p->out_data.rdata;
1611 /* grab the samr unknown 24 */
1612 if(!samr_io_q_query_userinfo("", &q_u, data, 0))
1613 return False;
1615 /* construct reply. always indicate success */
1616 if(!samr_reply_query_userinfo(&q_u, rdata))
1617 return False;
1619 return True;
1623 /*******************************************************************
1624 samr_reply_query_usergroups
1625 ********************************************************************/
1626 static BOOL samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
1627 prs_struct *rdata)
1629 SAMR_R_QUERY_USERGROUPS r_u;
1630 uint32 status = 0x0;
1632 SAM_ACCOUNT *sam_pass;
1633 DOM_GID *gids = NULL;
1634 int num_groups = 0;
1635 uint32 rid;
1637 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1639 /* find the policy handle. open a policy on it. */
1640 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1642 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1645 /* find the user's rid */
1646 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1648 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1651 if (status == 0x0)
1653 become_root();
1654 sam_pass = pdb_getsampwrid(rid);
1655 unbecome_root();
1657 if (sam_pass == NULL)
1659 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1663 if (status == 0x0)
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);
1671 /* construct the response. lkclXXXX: gids are not copied! */
1672 init_samr_r_query_usergroups(&r_u, num_groups, gids, status);
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;
1681 if (gids)
1682 free((char *)gids);
1684 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1686 return True;
1689 /*******************************************************************
1690 api_samr_query_usergroups
1691 ********************************************************************/
1692 static BOOL api_samr_query_usergroups(pipes_struct *p)
1694 SAMR_Q_QUERY_USERGROUPS q_u;
1695 prs_struct *data = &p->in_data.data;
1696 prs_struct *rdata = &p->out_data.rdata;
1698 /* grab the samr unknown 32 */
1699 if(!samr_io_q_query_usergroups("", &q_u, data, 0))
1700 return False;
1702 /* construct reply. */
1703 if(!samr_reply_query_usergroups(&q_u, rdata))
1704 return False;
1706 return True;
1710 /*******************************************************************
1711 api_samr_query_dom_info
1712 ********************************************************************/
1713 static BOOL api_samr_query_dom_info(pipes_struct *p)
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;
1721 uint16 switch_value = 0x0;
1722 uint32 status = 0x0;
1724 ZERO_STRUCT(q_u);
1725 ZERO_STRUCT(r_u);
1726 ZERO_STRUCT(ctr);
1728 DEBUG(5,("api_samr_query_dom_info: %d\n", __LINE__));
1730 /* grab the samr unknown 8 command */
1731 if(!samr_io_q_query_dom_info("", &q_u, data, 0))
1732 return False;
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"));
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;
1772 init_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
1774 /* store the response in the SMB stream */
1775 if(!samr_io_r_query_dom_info("", &r_u, rdata, 0))
1776 return False;
1778 DEBUG(5,("api_samr_query_dom_info: %d\n", __LINE__));
1780 return True;
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)
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;
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;
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...
1807 fstrcpy(mach_acct, dos_unistrn2(user_account.buffer, user_account.uni_str_len));
1808 strlower(mach_acct);
1810 become_root();
1811 sam_pass = pdb_getsampwnam(mach_acct);
1812 unbecome_root();
1813 if (sam_pass != NULL)
1815 /* machine account exists: say so */
1816 return NT_STATUS_USER_EXISTS;
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;
1823 local_flags=LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_SET_NO_PASSWORD;
1824 local_flags|= (acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0;
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.
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);
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)))
1841 DEBUG(0, ("%s\n", err_str));
1842 close_lsa_policy_hnd(user_pol);
1843 return NT_STATUS_ACCESS_DENIED;
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;
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;
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;
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;
1874 *unknown0 = 0x000703ff;
1875 *user_rid = pdb_get_user_rid(sam_pass);
1877 return NT_STATUS_NO_PROBLEMO;
1880 /*******************************************************************
1881 api_samr_create_user
1882 ********************************************************************/
1883 static BOOL api_samr_create_user(pipes_struct *p)
1885 prs_struct *data = &p->in_data.data;
1886 prs_struct *rdata = &p->out_data.rdata;
1888 SAMR_Q_CREATE_USER q_u;
1889 SAMR_R_CREATE_USER r_u;
1891 ZERO_STRUCT(q_u);
1892 ZERO_STRUCT(r_u);
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;
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);
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;
1909 return True;
1913 /*******************************************************************
1914 samr_reply_connect_anon
1915 ********************************************************************/
1916 static BOOL samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u, prs_struct *rdata)
1918 SAMR_R_CONNECT_ANON r_u;
1919 BOOL pol_open = False;
1921 /* set up the SAMR connect_anon response */
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))))
1927 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
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))
1933 /* oh, whoops. don't know what error message to return, here */
1934 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1937 if (r_u.status != 0 && pol_open)
1939 close_lsa_policy_hnd(&(r_u.connect_pol));
1942 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1944 /* store the response in the SMB stream */
1945 if(!samr_io_r_connect_anon("", &r_u, rdata, 0))
1946 return False;
1948 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1950 return True;
1953 /*******************************************************************
1954 api_samr_connect_anon
1955 ********************************************************************/
1956 static BOOL api_samr_connect_anon(pipes_struct *p)
1958 SAMR_Q_CONNECT_ANON q_u;
1959 prs_struct *data = &p->in_data.data;
1960 prs_struct *rdata = &p->out_data.rdata;
1962 /* grab the samr open policy */
1963 if(!samr_io_q_connect_anon("", &q_u, data, 0))
1964 return False;
1966 /* construct reply. always indicate success */
1967 if(!samr_reply_connect_anon(&q_u, rdata))
1968 return False;
1970 return True;
1973 /*******************************************************************
1974 samr_reply_connect
1975 ********************************************************************/
1976 static BOOL samr_reply_connect(SAMR_Q_CONNECT *q_u, prs_struct *rdata)
1978 SAMR_R_CONNECT r_u;
1979 BOOL pol_open = False;
1981 /* set up the SAMR connect response */
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))))
1987 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
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))
1993 /* oh, whoops. don't know what error message to return, here */
1994 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1997 if (r_u.status != 0 && pol_open)
1999 close_lsa_policy_hnd(&(r_u.connect_pol));
2002 DEBUG(5,("samr_connect: %d\n", __LINE__));
2004 /* store the response in the SMB stream */
2005 if(!samr_io_r_connect("", &r_u, rdata, 0))
2006 return False;
2008 DEBUG(5,("samr_connect: %d\n", __LINE__));
2010 return True;
2013 /*******************************************************************
2014 api_samr_connect
2015 ********************************************************************/
2016 static BOOL api_samr_connect(pipes_struct *p)
2018 SAMR_Q_CONNECT q_u;
2019 prs_struct *data = &p->in_data.data;
2020 prs_struct *rdata = &p->out_data.rdata;
2022 /* grab the samr open policy */
2023 if(!samr_io_q_connect("", &q_u, data, 0))
2024 return False;
2026 /* construct reply. always indicate success */
2027 if(!samr_reply_connect(&q_u, rdata))
2028 return False;
2030 return True;
2034 /**********************************************************************
2035 api_samr_lookup_domain
2036 **********************************************************************/
2037 static BOOL api_samr_lookup_domain(pipes_struct *p)
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;
2044 ZERO_STRUCT(q_u);
2045 ZERO_STRUCT(r_u);
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;
2052 r_u.status = 0x0;
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"));
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);
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;
2068 return True;
2071 /**********************************************************************
2072 api_samr_enum_domains
2073 **********************************************************************/
2074 static BOOL api_samr_enum_domains(pipes_struct *p)
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;
2081 fstring dom[2];
2083 ZERO_STRUCT(q_u);
2084 ZERO_STRUCT(r_u);
2086 fstrcpy(dom[0],global_myworkgroup);
2087 fstrcpy(dom[1],"Builtin");
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;
2094 r_u.status = NT_STATUS_NO_PROBLEMO;
2096 init_samr_r_enum_domains(&r_u, q_u.start_idx, dom, 2);
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;
2105 free(r_u.sam);
2106 free(r_u.uni_dom_name);
2108 return True;
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)
2117 DOM_SID sid;
2119 /* get the domain policy. */
2120 if (find_lsa_policy_by_hnd(&domain_pol) == -1)
2121 return NT_STATUS_INVALID_HANDLE;
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;
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;
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;
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;
2146 return NT_STATUS_NO_PROBLEMO;
2149 /*******************************************************************
2150 api_samr_open_alias
2151 ********************************************************************/
2152 static BOOL api_samr_open_alias(pipes_struct *p)
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;
2159 ZERO_STRUCT(q_u);
2160 ZERO_STRUCT(r_u);
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;
2168 r_u.status=_api_samr_open_alias(q_u.dom_pol, q_u.rid_alias, &r_u.pol);
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;
2176 return True;
2179 /*******************************************************************
2180 set_user_info_10
2181 ********************************************************************/
2182 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid)
2184 SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2186 if (id10 == NULL) {
2187 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2188 return False;
2191 if (pwd == NULL)
2192 return False;
2194 pdb_set_acct_ctrl(pwd, id10->acb_info);
2196 if(!pdb_update_sam_account(pwd, True))
2197 return False;
2199 return True;
2202 /*******************************************************************
2203 set_user_info_12
2204 ********************************************************************/
2205 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, uint32 rid)
2207 SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2209 if (pwd == NULL)
2210 return False;
2212 if (id12 == NULL) {
2213 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2214 return False;
2217 pdb_set_lanman_passwd (pwd, id12->lm_pwd);
2218 pdb_set_nt_passwd (pwd, id12->nt_pwd);
2220 if(!pdb_update_sam_account(pwd, True))
2221 return False;
2223 return True;
2226 /*******************************************************************
2227 set_user_info_21
2228 ********************************************************************/
2229 static BOOL set_user_info_21 (SAM_USER_INFO_21 *id21, uint32 rid)
2231 SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2232 SAM_ACCOUNT new_pwd;
2234 if (id21 == NULL) {
2235 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2236 return False;
2239 if (pwd == NULL)
2240 return False;
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);
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
2253 /* write the change out */
2254 if(!pdb_update_sam_account(&new_pwd, True))
2255 return False;
2257 return True;
2260 /*******************************************************************
2261 set_user_info_23
2262 ********************************************************************/
2263 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
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;
2272 if (id23 == NULL) {
2273 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2274 return False;
2277 if (pwd == NULL)
2278 return False;
2280 copy_sam_passwd(&new_pwd, pwd);
2281 copy_id23_to_sam_passwd(&new_pwd, id23);
2283 if (!decode_pw_buffer((char*)id23->pass, buf, 256, &len))
2284 return False;
2286 nt_lm_owf_gen(buf, nt_hash, lm_hash);
2288 pdb_set_lanman_passwd (&new_pwd, lm_hash);
2289 pdb_set_nt_passwd (&new_pwd, nt_hash);
2291 /* update the UNIX password */
2292 if (lp_unix_password_sync())
2293 if(!chgpasswd(pdb_get_username(&new_pwd), "", buf, True))
2294 return False;
2296 memset(buf, 0, sizeof(buf));
2298 if(!pdb_update_sam_account(&new_pwd, True))
2299 return False;
2301 return True;
2304 /*******************************************************************
2305 set_user_info_24
2306 ********************************************************************/
2307 static BOOL set_user_info_24(const SAM_USER_INFO_24 *id24, uint32 rid)
2309 SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2310 uchar nt_hash[16];
2311 uchar lm_hash[16];
2312 uint32 len;
2313 pstring buf;
2315 if (pwd == NULL)
2316 return False;
2318 memset(buf, 0, sizeof(buf));
2320 if (!decode_pw_buffer((char*)id24->pass, buf, 256, &len))
2321 return False;
2323 DEBUG(0,("set_user_info_24:nt_lm_owf_gen\n"));
2325 nt_lm_owf_gen(buf, nt_hash, lm_hash);
2327 pdb_set_lanman_passwd (pwd, lm_hash);
2328 pdb_set_nt_passwd (pwd, nt_hash);
2330 /* update the UNIX password */
2331 if (lp_unix_password_sync())
2332 if(!chgpasswd(pdb_get_username(pwd), "", buf, True))
2333 return False;
2335 memset(buf, 0, sizeof(buf));
2337 DEBUG(0,("set_user_info_24: pdb_update_sam_account()\n"));
2339 /* update the SAMBA password */
2340 if(!pdb_update_sam_account(pwd, True))
2341 return False;
2343 return True;
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)
2352 uint32 rid = 0x0;
2353 DOM_SID sid;
2354 struct current_user user;
2355 SAM_ACCOUNT *sam_pass;
2356 unsigned char sess_key[16];
2358 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2360 if (p->ntlmssp_auth_validated)
2362 memcpy(&user, &p->pipe_user, sizeof(user));
2364 else
2366 extern struct current_user current_user;
2367 memcpy(&user, &current_user, sizeof(user));
2370 /* search for the handle */
2371 if (find_lsa_policy_by_hnd(pol) == -1)
2372 return NT_STATUS_INVALID_HANDLE;
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;
2378 sid_split_rid(&sid, &rid);
2380 DEBUG(5, ("_samr_set_userinfo: rid:0x%x, level:%d\n", rid, switch_value));
2382 if (ctr == NULL) {
2383 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2384 return NT_STATUS_INVALID_INFO_CLASS;
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.
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;
2403 memset(sess_key, '\0', 16);
2404 mdfour(sess_key, pdb_get_nt_passwd(sam_pass), 16);
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;
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;
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;
2425 default:
2426 return NT_STATUS_INVALID_INFO_CLASS;
2429 return NT_STATUS_NOPROBLEMO;
2432 /*******************************************************************
2433 api_samr_set_userinfo
2434 ********************************************************************/
2435 static BOOL api_samr_set_userinfo(pipes_struct *p)
2437 SAMR_Q_SET_USERINFO q_u;
2438 SAMR_R_SET_USERINFO r_u;
2440 prs_struct *data = &p->in_data.data;
2441 prs_struct *rdata = &p->out_data.rdata;
2443 SAM_USERINFO_CTR ctr;
2445 ZERO_STRUCT(q_u);
2446 ZERO_STRUCT(r_u);
2448 q_u.ctr = &ctr;
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;
2455 r_u.status = _samr_set_userinfo(&q_u.pol, q_u.switch_value, &ctr, p);
2457 free_samr_q_set_userinfo(&q_u);
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;
2464 return True;
2467 /*******************************************************************
2468 samr_reply_set_userinfo2
2469 ********************************************************************/
2470 static uint32 _samr_set_userinfo2(POLICY_HND *pol, uint16 switch_value, SAM_USERINFO_CTR *ctr)
2472 DOM_SID sid;
2473 uint32 rid = 0x0;
2475 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
2477 /* search for the handle */
2478 if (find_lsa_policy_by_hnd(pol) == -1)
2479 return NT_STATUS_INVALID_HANDLE;
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;
2485 sid_split_rid(&sid, &rid);
2487 DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid));
2489 if (ctr == NULL) {
2490 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
2491 return NT_STATUS_INVALID_INFO_CLASS;
2494 ctr->switch_value = switch_value;
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;
2510 return NT_STATUS_NOPROBLEMO;
2513 /*******************************************************************
2514 api_samr_set_userinfo2
2515 ********************************************************************/
2516 static BOOL api_samr_set_userinfo2(pipes_struct *p)
2518 SAMR_Q_SET_USERINFO2 q_u;
2519 SAMR_R_SET_USERINFO2 r_u;
2520 SAM_USERINFO_CTR ctr;
2522 prs_struct *data = &p->in_data.data;
2523 prs_struct *rdata = &p->out_data.rdata;
2525 ZERO_STRUCT(q_u);
2526 ZERO_STRUCT(r_u);
2528 q_u.ctr = &ctr;
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;
2535 r_u.status = _samr_set_userinfo2(&q_u.pol, q_u.switch_value, &ctr);
2537 free_samr_q_set_userinfo2(&q_u);
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;
2544 return True;
2548 /*******************************************************************
2549 array of \PIPE\samr operations
2550 ********************************************************************/
2551 static struct api_struct api_samr_cmds [] =
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 }
2582 /*******************************************************************
2583 receives a samr pipe and responds.
2584 ********************************************************************/
2585 BOOL api_samr_rpc(pipes_struct *p)
2587 return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds);
2589 #undef OLD_NTDOMAIN