3 * Unix SMB/Netbios implementation.
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.
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,
45 int *total_entries, int *num_entries,
50 struct sam_passwd *pwd = NULL;
55 if (pw_buf == NULL) return False;
57 vp = startsmbpwent(False);
59 DEBUG(0, ("get_sampwd_entries: Unable to open SMB password database.\n"));
63 while (((pwd = getsam21pwent(vp)) != NULL) && (*num_entries) < max_num_entries) {
67 /* skip the requested number of entries.
68 not very efficient, but hey...
74 user_name_len = strlen(pwd->smb_name);
75 init_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->smb_name, user_name_len);
76 init_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
77 pw_buf[(*num_entries)].user_rid = pwd->user_rid;
78 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
80 /* Now check if the NT compatible password is available. */
81 if (pwd->smb_nt_passwd != NULL) {
82 memcpy( pw_buf[(*num_entries)].nt_pwd , pwd->smb_nt_passwd, 16);
85 pw_buf[(*num_entries)].acb_info = (uint16)pwd->acct_ctrl;
87 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
88 (*num_entries), pwd->smb_name,
89 pwd->user_rid, pwd->acct_ctrl));
91 if (acb_mask == 0 || IS_BITS_SET_SOME(pwd->acct_ctrl, acb_mask)) {
92 DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
95 DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
103 return (*num_entries) > 0;
106 /*******************************************************************
107 This function uses the username map file and tries to map a UNIX
108 user name to an DOS name. (Sort of the reverse of the
109 map_username() function.) Since more than one DOS name can map
110 to the UNIX name, to reverse the mapping you have to specify
111 which corresponding DOS name you want; that's where the name_idx
112 parameter comes in. Returns the string requested or NULL if it
113 fails or can't complete the request for any reason. This doesn't
114 handle group names (starting with '@') or names starting with
115 '+' or '&'. If they are encountered, they are skipped.
116 ********************************************************************/
118 static char *unmap_unixname(char *unix_user_name, int name_idx)
120 char *mapfile = lp_username_map();
125 if (!*unix_user_name) return NULL;
126 if (!*mapfile) return NULL;
128 lines = file_lines_load(mapfile, NULL);
130 DEBUG(0,("unmap_unixname: can't open username map %s\n", mapfile));
134 DEBUG(5,("unmap_unixname: scanning username map %s, index: %d\n", mapfile, name_idx));
136 for (i=0; lines[i]; i++) {
137 char *unixname = lines[i];
138 char *dosname = strchr(unixname,'=');
145 while (isspace(*unixname))
147 if ('!' == *unixname) {
149 while (*unixname && isspace(*unixname))
153 if (!*unixname || strchr("#;",*unixname))
156 if (strncmp(unixname, unix_user_name, strlen(unix_user_name)))
159 /* We have matched the UNIX user name */
161 while(next_token(&dosname, tok, LIST_SEP, sizeof(tok))) {
162 if (!strchr("@&+", *tok)) {
171 DEBUG(0,("unmap_unixname: index too high - not that many DOS names\n"));
172 file_lines_free(lines);
175 file_lines_free(lines);
180 DEBUG(0,("unmap_unixname: Couldn't find the UNIX user name\n"));
181 file_lines_free(lines);
185 /*******************************************************************
186 This function sets up a list of users taken from the list of
187 users that UNIX knows about, as well as all the user names that
188 Samba maps to a valid UNIX user name. (This should work with
190 ********************************************************************/
192 static BOOL get_passwd_entries(SAM_USER_INFO_21 *pw_buf,
194 int *total_entries, int *num_entries,
198 static struct passwd *pwd = NULL;
199 static uint32 pw_rid;
200 static BOOL orig_done = False;
201 static int current_idx = 0;
202 static int mapped_idx = 0;
204 DEBUG(5, ("get_passwd_entries: retrieving a list of UNIX users\n"));
207 (*total_entries) = 0;
209 if (pw_buf == NULL) return False;
211 if (current_idx == 0) {
215 /* These two cases are inefficient, but should be called very rarely */
216 /* they are the cases where the starting index isn't picking up */
217 /* where we left off last time. It is efficient when it starts over */
218 /* at zero though. */
219 if (start_idx > current_idx) {
220 /* We aren't far enough; advance to start_idx */
221 while (current_idx < start_idx) {
225 if ((pwd = getpwent()) == NULL) break;
230 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
231 (current_idx < start_idx)) {
236 if (unmap_name == NULL) {
241 } else if (start_idx < current_idx) {
242 /* We are already too far; start over and advance to start_idx */
248 while (current_idx < start_idx) {
252 if ((pwd = getpwent()) == NULL) break;
257 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
258 (current_idx < start_idx)) {
263 if (unmap_name == NULL) {
270 /* now current_idx == start_idx */
271 while ((*num_entries) < max_num_entries) {
275 /* This does the original UNIX user itself */
277 if ((pwd = getpwent()) == NULL) break;
278 user_name_len = strlen(pwd->pw_name);
279 pw_rid = pdb_uid_to_user_rid(pwd->pw_uid);
280 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
281 init_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->pw_name, user_name_len);
282 init_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
283 pw_buf[(*num_entries)].user_rid = pw_rid;
284 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
286 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
288 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
296 /* This does all the user names that map to the UNIX user */
297 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
298 (*num_entries < max_num_entries)) {
299 user_name_len = strlen(unmap_name);
300 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
301 init_unistr2(&(pw_buf[(*num_entries)].uni_user_name), unmap_name, user_name_len);
302 init_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
303 pw_buf[(*num_entries)].user_rid = pw_rid;
304 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
306 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
308 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
316 if (unmap_name == NULL) {
317 /* done with 'aliases', go on to next UNIX user */
324 /* totally done, reset everything */
330 return (*num_entries) > 0;
333 /*******************************************************************
335 ********************************************************************/
336 static BOOL samr_reply_close_hnd(SAMR_Q_CLOSE_HND *q_u,
339 SAMR_R_CLOSE_HND r_u;
341 /* set up the SAMR unknown_1 response */
342 memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
344 /* close the policy handle */
345 if (close_lsa_policy_hnd(&(q_u->pol)))
351 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_INVALID;
354 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
356 /* store the response in the SMB stream */
357 if(!samr_io_r_close_hnd("", &r_u, rdata, 0))
360 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
365 /*******************************************************************
367 ********************************************************************/
368 static BOOL api_samr_close_hnd(pipes_struct *p)
370 SAMR_Q_CLOSE_HND q_u;
371 prs_struct *data = &p->in_data.data;
372 prs_struct *rdata = &p->out_data.rdata;
374 /* grab the samr unknown 1 */
375 if(!samr_io_q_close_hnd("", &q_u, data, 0))
378 /* construct reply. always indicate success */
379 if(!samr_reply_close_hnd(&q_u, rdata))
386 /*******************************************************************
387 samr_reply_open_domain
388 ********************************************************************/
389 static BOOL samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
392 SAMR_R_OPEN_DOMAIN r_u;
393 BOOL pol_open = False;
397 /* find the connection policy handle. */
398 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->connect_pol)) == -1))
400 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
403 /* get a (unique) handle. open a policy on it. */
404 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.domain_pol))))
406 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
409 /* associate the domain SID with the (unique) handle. */
410 if (r_u.status == 0x0 && !set_lsa_policy_samr_sid(&(r_u.domain_pol), &(q_u->dom_sid.sid)))
412 /* oh, whoops. don't know what error message to return, here */
413 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
416 if (r_u.status != 0 && pol_open)
418 close_lsa_policy_hnd(&(r_u.domain_pol));
421 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
423 /* store the response in the SMB stream */
424 if(!samr_io_r_open_domain("", &r_u, rdata, 0))
427 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
432 /*******************************************************************
434 ********************************************************************/
435 static BOOL api_samr_open_domain(pipes_struct *p)
437 SAMR_Q_OPEN_DOMAIN q_u;
438 prs_struct *data = &p->in_data.data;
439 prs_struct *rdata = &p->out_data.rdata;
441 /* grab the samr open */
442 if(!samr_io_q_open_domain("", &q_u, data, 0))
445 /* construct reply. always indicate success */
446 if(!samr_reply_open_domain(&q_u, rdata))
453 /*******************************************************************
454 samr_reply_unknown_2c
455 ********************************************************************/
456 static BOOL samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u,
459 SAMR_R_UNKNOWN_2C r_u;
462 /* find the policy handle. open a policy on it. */
463 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
465 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
468 /* find the user's rid */
469 if ((status == 0x0) && (get_lsa_policy_samr_rid(&(q_u->user_pol)) == 0xffffffff))
471 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
474 init_samr_r_unknown_2c(&r_u, status);
476 DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
478 /* store the response in the SMB stream */
479 if(!samr_io_r_unknown_2c("", &r_u, rdata, 0))
482 DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
487 /*******************************************************************
489 ********************************************************************/
490 static BOOL api_samr_unknown_2c(pipes_struct *p)
492 SAMR_Q_UNKNOWN_2C q_u;
493 prs_struct *data = &p->in_data.data;
494 prs_struct *rdata = &p->out_data.rdata;
496 /* grab the samr open */
497 if(!samr_io_q_unknown_2c("", &q_u, data, 0))
500 /* construct reply. always indicate success */
501 if(!samr_reply_unknown_2c(&q_u, rdata))
508 /*******************************************************************
510 ********************************************************************/
511 static BOOL samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
514 SAMR_R_UNKNOWN_3 r_u;
515 DOM_SID3 sid[MAX_SAM_SIDS];
521 /* find the policy handle. open a policy on it. */
522 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
524 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
527 /* find the user's rid */
528 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->user_pol))) == 0xffffffff)
530 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
536 DOM_SID everyone_sid;
538 user_sid = global_sam_sid;
540 SMB_ASSERT_ARRAY(user_sid.sub_auths, user_sid.num_auths+1);
545 user_sid.sub_auths[user_sid.num_auths++] = rid;
547 string_to_sid(&everyone_sid, "S-1-1");
549 /* maybe need another 1 or 2 (S-1-5-0x20-0x220 and S-1-5-20-0x224) */
550 /* these two are DOMAIN_ADMIN and DOMAIN_ACCT_OP group RIDs */
551 init_dom_sid3(&(sid[0]), 0x035b, 0x0002, &everyone_sid);
552 init_dom_sid3(&(sid[1]), 0x0044, 0x0002, &user_sid);
555 init_samr_r_unknown_3(&r_u,
557 0x00000014, 0x0002, 0x0070,
560 DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
562 /* store the response in the SMB stream */
563 if(!samr_io_r_unknown_3("", &r_u, rdata, 0))
566 DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
571 /*******************************************************************
573 ********************************************************************/
574 static BOOL api_samr_unknown_3(pipes_struct *p)
576 SAMR_Q_UNKNOWN_3 q_u;
577 prs_struct *data = &p->in_data.data;
578 prs_struct *rdata = &p->out_data.rdata;
580 /* grab the samr open */
581 if(!samr_io_q_unknown_3("", &q_u, data, 0))
584 /* construct reply. always indicate success */
585 if(!samr_reply_unknown_3(&q_u, rdata))
592 /*******************************************************************
593 samr_reply_enum_dom_users
594 ********************************************************************/
595 static BOOL samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
598 SAMR_R_ENUM_DOM_USERS r_e;
599 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
604 r_e.total_num_entries = 0;
606 /* find the policy handle. open a policy on it. */
607 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
609 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
612 DEBUG(5,("samr_reply_enum_dom_users: %d\n", __LINE__));
615 get_sampwd_entries(pass, 0, &total_entries, &num_entries, MAX_SAM_ENTRIES, q_u->acb_mask);
618 init_samr_r_enum_dom_users(&r_e, total_entries,
619 q_u->unknown_0, num_entries,
622 /* store the response in the SMB stream */
623 if(!samr_io_r_enum_dom_users("", &r_e, rdata, 0))
626 DEBUG(5,("samr_enum_dom_users: %d\n", __LINE__));
631 /*******************************************************************
632 api_samr_enum_dom_users
633 ********************************************************************/
634 static BOOL api_samr_enum_dom_users(pipes_struct *p)
636 SAMR_Q_ENUM_DOM_USERS q_e;
637 prs_struct *data = &p->in_data.data;
638 prs_struct *rdata = &p->out_data.rdata;
640 /* grab the samr open */
641 if(!samr_io_q_enum_dom_users("", &q_e, data, 0))
644 /* construct reply. */
645 if(!samr_reply_enum_dom_users(&q_e, rdata))
651 /*******************************************************************
652 samr_reply_enum_dom_groups
653 ********************************************************************/
654 static BOOL samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u,
657 SAMR_R_ENUM_DOM_GROUPS r_e;
658 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
661 char *dummy_group = "Domain Admins";
666 /* find the policy handle. open a policy on it. */
667 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
669 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
672 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
676 ZERO_STRUCTP(&pass[0]);
677 init_unistr2(&(pass[0].uni_user_name), dummy_group, strlen(dummy_group));
678 pass[0].user_rid = DOMAIN_GROUP_RID_ADMINS;
680 if (r_e.status == 0 && got_grps)
682 init_samr_r_enum_dom_groups(&r_e, q_u->start_idx, num_entries, pass, r_e.status);
685 /* store the response in the SMB stream */
686 if(!samr_io_r_enum_dom_groups("", &r_e, rdata, 0))
689 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
694 /*******************************************************************
695 api_samr_enum_dom_groups
696 ********************************************************************/
697 static BOOL api_samr_enum_dom_groups(pipes_struct *p)
699 SAMR_Q_ENUM_DOM_GROUPS q_e;
700 prs_struct *data = &p->in_data.data;
701 prs_struct *rdata = &p->out_data.rdata;
703 /* grab the samr open */
704 if(!samr_io_q_enum_dom_groups("", &q_e, data, 0))
707 /* construct reply. */
708 if(!samr_reply_enum_dom_groups(&q_e, rdata))
714 /*******************************************************************
715 samr_reply_enum_dom_aliases
716 ********************************************************************/
717 static BOOL samr_reply_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_u,
720 SAMR_R_ENUM_DOM_ALIASES r_e;
721 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
731 /* find the policy handle. open a policy on it. */
732 if (r_e.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &sid))
734 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
737 sid_to_string(sid_str, &sid);
738 sid_to_string(sam_sid_str, &global_sam_sid);
740 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
742 /* well-known aliases */
743 if (strequal(sid_str, "S-1-5-32"))
746 while (num_entries < MAX_SAM_ENTRIES && ((name = builtin_alias_rids[num_entries].name) != NULL))
748 init_unistr2(&(pass[num_entries].uni_user_name), name, strlen(name));
749 pass[num_entries].user_rid = builtin_alias_rids[num_entries].rid;
753 else if (strequal(sid_str, sam_sid_str))
757 /* we return the UNIX groups here. This seems to be the right */
758 /* thing to do, since NT member servers return their local */
759 /* groups in the same situation. */
762 while (num_entries < MAX_SAM_ENTRIES && ((grp = getgrent()) != NULL))
765 init_unistr2(&(pass[num_entries].uni_user_name), name, strlen(name));
766 pass[num_entries].user_rid = pdb_gid_to_group_rid(grp->gr_gid);
773 init_samr_r_enum_dom_aliases(&r_e, num_entries, pass, r_e.status);
775 /* store the response in the SMB stream */
776 if(!samr_io_r_enum_dom_aliases("", &r_e, rdata, 0))
779 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
784 /*******************************************************************
785 api_samr_enum_dom_aliases
786 ********************************************************************/
787 static BOOL api_samr_enum_dom_aliases(prs_struct *data, prs_struct *rdata)
789 SAMR_Q_ENUM_DOM_ALIASES q_e;
791 /* grab the samr open */
792 if(!samr_io_q_enum_dom_aliases("", &q_e, data, 0))
795 /* construct reply. */
796 if(!samr_reply_enum_dom_aliases(&q_e, rdata))
803 /*******************************************************************
804 samr_reply_query_dispinfo
805 ********************************************************************/
806 static BOOL samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u, prs_struct *rdata)
808 SAMR_R_QUERY_DISPINFO r_e;
812 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
814 int total_entries = 0;
816 uint16 switch_level = 0x0;
822 DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
824 /* find the policy handle. open a policy on it. */
825 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
827 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
828 DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n"));
831 if (r_e.status == 0x0)
833 /* decide how many entries to get depending on the max_entries
834 and max_size passed by client */
837 if(q_u->max_entries > MAX_SAM_ENTRIES)
838 q_u->max_entries = MAX_SAM_ENTRIES;
840 retsize = (q_u->max_entries * (sizeof(SAM_ENTRY1)+sizeof(SAM_STR1)))
843 if(retsize > q_u->max_size)
845 /* determine max_entries based on max_size */
846 q_u->max_entries = (q_u->max_size - 3*sizeof(uint32)) /
847 (sizeof(SAM_ENTRY1)+sizeof(SAM_STR1));
848 q_u->max_entries = (q_u->max_entries>0?q_u->max_entries:1);
851 DEBUG(10,("samr_reply_query_dispinfo: Setting q_u->max_entries to %u\n",q_u->max_entries));
854 got_pwds = get_passwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, q_u->max_entries, 0);
857 /* more left - set resume handle */
858 if(total_entries > num_entries)
863 switch (q_u->switch_level)
868 /* query disp info is for users */
870 init_sam_info_1(&info1, ACB_NORMAL,
871 q_u->start_idx, num_entries, pass);
873 ctr.sam.info1 = &info1;
879 /* query disp info is for servers */
881 init_sam_info_2(&info2, ACB_WSTRUST,
882 q_u->start_idx, num_entries, pass);
884 ctr.sam.info2 = &info2;
891 /* more left - set resume handle */
892 if(total_entries > num_entries)
897 if (r_e.status == 0 || r_e.status == 0x105)
899 init_samr_r_query_dispinfo(&r_e, switch_level, &ctr, r_e.status);
902 /* store the response in the SMB stream */
903 if(!samr_io_r_query_dispinfo("", &r_e, rdata, 0))
906 DEBUG(5,("samr_query_dispinfo: %d\n", __LINE__));
911 /*******************************************************************
912 api_samr_query_dispinfo
913 ********************************************************************/
914 static BOOL api_samr_query_dispinfo(pipes_struct *p)
916 SAMR_Q_QUERY_DISPINFO q_e;
917 prs_struct *data = &p->in_data.data;
918 prs_struct *rdata = &p->out_data.rdata;
920 /* grab the samr open */
921 if(!samr_io_q_query_dispinfo("", &q_e, data, 0))
924 /* construct reply. */
925 if(!samr_reply_query_dispinfo(&q_e, rdata))
932 /*******************************************************************
933 samr_reply_query_aliasinfo
934 ********************************************************************/
935 static BOOL samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
938 SAMR_R_QUERY_ALIASINFO r_e;
939 fstring alias_desc = "Local Unix group";
946 DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__));
948 /* find the policy handle. open a policy on it. */
949 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
951 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
954 alias_rid = get_lsa_policy_samr_rid(&q_u->pol);
955 if(alias_rid == 0xffffffff)
956 r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
958 if(!lookup_local_rid(alias_rid, alias, &type))
960 r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
963 init_samr_r_query_aliasinfo(&r_e, q_u->switch_level, alias, alias_desc);
965 /* store the response in the SMB stream */
966 if(!samr_io_r_query_aliasinfo("", &r_e, rdata, 0))
969 DEBUG(5,("samr_query_aliasinfo: %d\n", __LINE__));
974 /*******************************************************************
975 api_samr_query_aliasinfo
976 ********************************************************************/
977 static BOOL api_samr_query_aliasinfo(pipes_struct *p)
979 SAMR_Q_QUERY_ALIASINFO q_e;
980 prs_struct *data = &p->in_data.data;
981 prs_struct *rdata = &p->out_data.rdata;
983 /* grab the samr open */
984 if(!samr_io_q_query_aliasinfo("", &q_e, data, 0))
987 /* construct reply. */
988 if(!samr_reply_query_aliasinfo(&q_e, rdata))
995 /*******************************************************************
996 samr_reply_lookup_ids
997 ********************************************************************/
998 static BOOL samr_reply_lookup_ids(SAMR_Q_LOOKUP_IDS *q_u,
1001 uint32 rid[MAX_SAM_ENTRIES];
1003 int num_rids = q_u->num_sids1;
1005 SAMR_R_LOOKUP_IDS r_u;
1007 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
1009 if (num_rids > MAX_SAM_ENTRIES)
1011 num_rids = MAX_SAM_ENTRIES;
1012 DEBUG(5,("samr_lookup_ids: truncating entries to %d\n", num_rids));
1017 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1019 for (i = 0; i < num_rids && status == 0; i++)
1021 struct sam_passwd *sam_pass;
1025 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1026 q_u->uni_user_name[i].uni_str_len));
1028 /* find the user account */
1030 sam_pass = get_smb21pwd_entry(user_name, 0);
1031 unbecome_root(True);
1033 if (sam_pass == NULL)
1035 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1040 rid[i] = sam_pass->user_rid;
1046 rid[0] = BUILTIN_ALIAS_RID_USERS;
1048 init_samr_r_lookup_ids(&r_u, num_rids, rid, status);
1050 /* store the response in the SMB stream */
1051 if(!samr_io_r_lookup_ids("", &r_u, rdata, 0))
1054 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
1059 /*******************************************************************
1061 ********************************************************************/
1062 static BOOL api_samr_lookup_ids(pipes_struct *p)
1064 SAMR_Q_LOOKUP_IDS q_u;
1065 prs_struct *data = &p->in_data.data;
1066 prs_struct *rdata = &p->out_data.rdata;
1068 /* grab the samr 0x10 */
1069 if(!samr_io_q_lookup_ids("", &q_u, data, 0))
1072 /* construct reply. always indicate success */
1073 if(!samr_reply_lookup_ids(&q_u, rdata))
1079 /*******************************************************************
1080 samr_reply_lookup_names
1081 ********************************************************************/
1083 static BOOL samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
1086 uint32 rid[MAX_SAM_ENTRIES];
1087 uint8 type[MAX_SAM_ENTRIES];
1090 int num_rids = q_u->num_names1;
1093 SAMR_R_LOOKUP_NAMES r_u;
1095 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1100 if (!get_lsa_policy_samr_sid(&q_u->pol, &pol_sid)) {
1101 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
1102 init_samr_r_lookup_names(&r_u, 0, rid, type, status);
1103 if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
1104 DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
1110 if (num_rids > MAX_SAM_ENTRIES) {
1111 num_rids = MAX_SAM_ENTRIES;
1112 DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
1115 SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
1117 for (i = 0; i < num_rids; i++) {
1120 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
1122 rid [i] = 0xffffffff;
1123 type[i] = SID_NAME_UNKNOWN;
1125 fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer,
1126 q_u->uni_name[i].uni_str_len));
1128 if(sid_equal(&pol_sid, &global_sam_sid))
1131 if(lookup_local_name(global_myname, name,
1134 sid_split_rid( &sid, &rid[i]);
1140 init_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
1142 /* store the response in the SMB stream */
1143 if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
1144 DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
1148 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1153 /*******************************************************************
1154 api_samr_lookup_names
1155 ********************************************************************/
1157 static BOOL api_samr_lookup_names(pipes_struct *p)
1159 SAMR_Q_LOOKUP_NAMES q_u;
1160 prs_struct *data = &p->in_data.data;
1161 prs_struct *rdata = &p->out_data.rdata;
1163 memset(&q_u, '\0', sizeof(q_u));
1165 /* grab the samr lookup names */
1166 if(!samr_io_q_lookup_names("", &q_u, data, 0)) {
1167 DEBUG(0,("api_samr_lookup_names: failed to unmarshall SAMR_Q_LOOKUP_NAMES.\n"));
1171 /* construct reply. always indicate success */
1172 if(!samr_reply_lookup_names(&q_u, rdata))
1178 /*******************************************************************
1179 samr_reply_chgpasswd_user
1180 ********************************************************************/
1182 static BOOL samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
1185 SAMR_R_CHGPASSWD_USER r_u;
1186 uint32 status = 0x0;
1190 fstrcpy(user_name, dos_unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len));
1191 fstrcpy(wks , dos_unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len));
1193 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1195 if (!pass_oem_change(user_name,
1196 q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1197 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1199 status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
1202 init_samr_r_chgpasswd_user(&r_u, status);
1204 /* store the response in the SMB stream */
1205 if(!samr_io_r_chgpasswd_user("", &r_u, rdata, 0)) {
1206 DEBUG(0,("samr_reply_chgpasswd_user: Failed to marshall SAMR_R_CHGPASSWD_USER struct.\n" ));
1210 DEBUG(5,("samr_chgpasswd_user: %d\n", __LINE__));
1214 /*******************************************************************
1215 api_samr_chgpasswd_user
1216 ********************************************************************/
1218 static BOOL api_samr_chgpasswd_user(pipes_struct *p)
1220 SAMR_Q_CHGPASSWD_USER q_u;
1221 prs_struct *data = &p->in_data.data;
1222 prs_struct *rdata = &p->out_data.rdata;
1224 /* unknown 38 command */
1225 if (!samr_io_q_chgpasswd_user("", &q_u, data, 0)) {
1226 DEBUG(0,("api_samr_chgpasswd_user: samr_io_q_chgpasswd_user failed to parse RPC packet.\n"));
1230 /* construct reply. */
1231 if(!samr_reply_chgpasswd_user(&q_u, rdata)) {
1232 DEBUG(0,("api_samr_chgpasswd_user: samr_reply_chgpasswd_user failed to create reply packet.\n"));
1240 /*******************************************************************
1241 samr_reply_unknown_38
1242 ********************************************************************/
1243 static BOOL samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u, prs_struct *rdata)
1245 SAMR_R_UNKNOWN_38 r_u;
1247 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1249 init_samr_r_unknown_38(&r_u);
1251 /* store the response in the SMB stream */
1252 if(!samr_io_r_unknown_38("", &r_u, rdata, 0))
1255 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1259 /*******************************************************************
1261 ********************************************************************/
1262 static BOOL api_samr_unknown_38(pipes_struct *p)
1264 SAMR_Q_UNKNOWN_38 q_u;
1265 prs_struct *data = &p->in_data.data;
1266 prs_struct *rdata = &p->out_data.rdata;
1268 /* unknown 38 command */
1269 if(!samr_io_q_unknown_38("", &q_u, data, 0))
1272 /* construct reply. always indicate success */
1273 if(!samr_reply_unknown_38(&q_u, rdata))
1280 /*******************************************************************
1281 samr_reply_unknown_12
1282 ********************************************************************/
1283 static BOOL samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
1286 fstring group_names[MAX_SAM_ENTRIES];
1287 uint32 group_attrs[MAX_SAM_ENTRIES];
1289 int num_gids = q_u->num_gids1;
1291 SAMR_R_UNKNOWN_12 r_u;
1293 DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
1295 /* find the policy handle. open a policy on it. */
1296 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1298 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1304 if (num_gids > MAX_SAM_ENTRIES)
1306 num_gids = MAX_SAM_ENTRIES;
1307 DEBUG(5,("samr_unknown_12: truncating entries to %d\n", num_gids));
1310 for (i = 0; i < num_gids && status == 0; i++)
1312 fstrcpy(group_names[i], "dummy group");
1313 group_attrs[i] = 0x2;
1317 init_samr_r_unknown_12(&r_u, num_gids, group_names, group_attrs, status);
1319 /* store the response in the SMB stream */
1320 if(!samr_io_r_unknown_12("", &r_u, rdata, 0))
1323 DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
1328 /*******************************************************************
1330 ********************************************************************/
1331 static BOOL api_samr_unknown_12(pipes_struct *p)
1333 SAMR_Q_UNKNOWN_12 q_u;
1334 prs_struct *data = &p->in_data.data;
1335 prs_struct *rdata = &p->out_data.rdata;
1337 /* grab the samr lookup names */
1338 if(!samr_io_q_unknown_12("", &q_u, data, 0))
1341 /* construct reply. always indicate success */
1342 if(!samr_reply_unknown_12(&q_u, rdata))
1349 /*******************************************************************
1350 samr_reply_open_user
1351 ********************************************************************/
1352 static BOOL samr_reply_open_user(SAMR_Q_OPEN_USER *q_u, prs_struct *rdata, int status)
1354 SAMR_R_OPEN_USER r_u;
1355 struct sam_passwd *sam_pass;
1356 BOOL pol_open = False;
1358 /* set up the SAMR open_user response */
1359 memset((char *)r_u.user_pol.data, '\0', POL_HND_SIZE);
1363 /* find the policy handle. open a policy on it. */
1364 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
1366 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1369 /* get a (unique) handle. open a policy on it. */
1370 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.user_pol))))
1372 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1376 sam_pass = getsam21pwrid(q_u->user_rid);
1377 unbecome_root(True);
1379 /* check that the RID exists in our domain. */
1380 if (r_u.status == 0x0 && sam_pass == NULL)
1382 r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1385 /* associate the RID with the (unique) handle. */
1386 if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.user_pol), q_u->user_rid))
1388 /* oh, whoops. don't know what error message to return, here */
1389 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1392 if (r_u.status != 0 && pol_open)
1394 close_lsa_policy_hnd(&(r_u.user_pol));
1397 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1399 /* store the response in the SMB stream */
1400 if(!samr_io_r_open_user("", &r_u, rdata, 0))
1403 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1408 /*******************************************************************
1410 ********************************************************************/
1411 static BOOL api_samr_open_user(pipes_struct *p)
1413 SAMR_Q_OPEN_USER q_u;
1414 prs_struct *data = &p->in_data.data;
1415 prs_struct *rdata = &p->out_data.rdata;
1417 /* grab the samr unknown 22 */
1418 if(!samr_io_q_open_user("", &q_u, data, 0))
1421 /* construct reply. always indicate success */
1422 if(!samr_reply_open_user(&q_u, rdata, 0x0))
1429 /*************************************************************************
1431 *************************************************************************/
1432 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1434 struct smb_passwd *smb_pass;
1436 if (!pdb_rid_is_user(user_rid))
1438 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1443 smb_pass = getsmbpwrid(user_rid);
1444 unbecome_root(True);
1446 if (smb_pass == NULL)
1448 DEBUG(4,("User 0x%x not found\n", user_rid));
1452 DEBUG(3,("User:[%s]\n", smb_pass->smb_name));
1454 init_sam_user_info10(id10, smb_pass->acct_ctrl);
1459 /*************************************************************************
1461 *************************************************************************/
1462 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1465 struct sam_passwd *sam_pass;
1469 if (!pdb_rid_is_user(user_rid))
1471 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1476 sam_pass = getsam21pwrid(user_rid);
1477 unbecome_root(True);
1479 if (sam_pass == NULL)
1481 DEBUG(4,("User 0x%x not found\n", user_rid));
1485 DEBUG(3,("User:[%s]\n", sam_pass->smb_name));
1487 dummy_time.low = 0xffffffff;
1488 dummy_time.high = 0x7fffffff;
1490 DEBUG(5,("get_user_info_21 - TODO: convert unix times to NTTIMEs\n"));
1492 /* create a LOGON_HRS structure */
1493 hrs.len = sam_pass->hours_len;
1494 SMB_ASSERT_ARRAY(hrs.hours, hrs.len);
1495 for (i = 0; i < hrs.len; i++)
1497 hrs.hours[i] = sam_pass->hours[i];
1500 init_sam_user_info21(id21,
1502 &dummy_time, /* logon_time */
1503 &dummy_time, /* logoff_time */
1504 &dummy_time, /* kickoff_time */
1505 &dummy_time, /* pass_last_set_time */
1506 &dummy_time, /* pass_can_change_time */
1507 &dummy_time, /* pass_must_change_time */
1509 sam_pass->smb_name, /* user_name */
1510 sam_pass->full_name, /* full_name */
1511 sam_pass->home_dir, /* home_dir */
1512 sam_pass->dir_drive, /* dir_drive */
1513 sam_pass->logon_script, /* logon_script */
1514 sam_pass->profile_path, /* profile_path */
1515 sam_pass->acct_desc, /* description */
1516 sam_pass->workstations, /* workstations user can log in from */
1517 sam_pass->unknown_str, /* don't know, yet */
1518 sam_pass->munged_dial, /* dialin info. contains dialin path and tel no */
1520 sam_pass->user_rid, /* RID user_id */
1521 sam_pass->group_rid, /* RID group_id */
1522 sam_pass->acct_ctrl,
1524 sam_pass->unknown_3, /* unknown_3 */
1525 sam_pass->logon_divs, /* divisions per week */
1526 &hrs, /* logon hours */
1527 sam_pass->unknown_5,
1528 sam_pass->unknown_6);
1533 /*******************************************************************
1534 samr_reply_query_userinfo
1535 ********************************************************************/
1536 static BOOL samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
1539 SAMR_R_QUERY_USERINFO r_u;
1541 SAM_USER_INFO_11 id11;
1543 SAM_USER_INFO_10 id10;
1544 SAM_USER_INFO_21 id21;
1547 uint32 status = 0x0;
1550 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1552 /* search for the handle */
1553 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1555 status = NT_STATUS_INVALID_HANDLE;
1558 /* find the user's rid */
1559 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1561 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1564 DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
1566 /* ok! user info levels (there are lots: see MSDEV help), off we go... */
1569 switch (q_u->switch_value)
1573 info = (void*)&id10;
1574 status = get_user_info_10(&id10, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1578 /* whoops - got this wrong. i think. or don't understand what's happening. */
1582 info = (void*)&id11;
1584 expire.low = 0xffffffff;
1585 expire.high = 0x7fffffff;
1587 make_sam_user_info11(&id11, &expire, "BROOKFIELDS$", 0x03ef, 0x201, 0x0080);
1594 info = (void*)&id21;
1595 status = get_user_info_21(&id21, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1601 status = NT_STATUS_INVALID_INFO_CLASS;
1608 init_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
1610 /* store the response in the SMB stream */
1611 if(!samr_io_r_query_userinfo("", &r_u, rdata, 0))
1614 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1619 /*******************************************************************
1620 api_samr_query_userinfo
1621 ********************************************************************/
1622 static BOOL api_samr_query_userinfo(pipes_struct *p)
1624 SAMR_Q_QUERY_USERINFO q_u;
1625 prs_struct *data = &p->in_data.data;
1626 prs_struct *rdata = &p->out_data.rdata;
1628 /* grab the samr unknown 24 */
1629 if(!samr_io_q_query_userinfo("", &q_u, data, 0))
1632 /* construct reply. always indicate success */
1633 if(!samr_reply_query_userinfo(&q_u, rdata))
1640 /*******************************************************************
1641 samr_reply_query_usergroups
1642 ********************************************************************/
1643 static BOOL samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
1646 SAMR_R_QUERY_USERGROUPS r_u;
1647 uint32 status = 0x0;
1649 struct sam_passwd *sam_pass;
1650 DOM_GID *gids = NULL;
1654 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1656 /* find the policy handle. open a policy on it. */
1657 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1659 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1662 /* find the user's rid */
1663 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1665 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1671 sam_pass = getsam21pwrid(rid);
1672 unbecome_root(True);
1674 if (sam_pass == NULL)
1676 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1683 get_domain_user_groups(groups, sam_pass->smb_name);
1685 num_groups = make_dom_gids(groups, &gids);
1688 /* construct the response. lkclXXXX: gids are not copied! */
1689 init_samr_r_query_usergroups(&r_u, num_groups, gids, status);
1691 /* store the response in the SMB stream */
1692 if(!samr_io_r_query_usergroups("", &r_u, rdata, 0)) {
1701 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1706 /*******************************************************************
1707 api_samr_query_usergroups
1708 ********************************************************************/
1709 static BOOL api_samr_query_usergroups(pipes_struct *p)
1711 SAMR_Q_QUERY_USERGROUPS q_u;
1712 prs_struct *data = &p->in_data.data;
1713 prs_struct *rdata = &p->out_data.rdata;
1715 /* grab the samr unknown 32 */
1716 if(!samr_io_q_query_usergroups("", &q_u, data, 0))
1719 /* construct reply. */
1720 if(!samr_reply_query_usergroups(&q_u, rdata))
1727 /*******************************************************************
1728 samr_reply_query_dom_info
1729 ********************************************************************/
1730 static BOOL samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_struct *rdata)
1732 SAMR_R_QUERY_DOMAIN_INFO r_u;
1734 uint16 switch_value = 0x0;
1735 uint32 status = 0x0;
1742 DEBUG(5,("samr_reply_query_dom_info: %d\n", __LINE__));
1744 /* find the policy handle. open a policy on it. */
1745 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
1747 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1748 DEBUG(5,("samr_reply_query_dom_info: invalid handle\n"));
1753 switch (q_u->switch_value)
1758 init_unk_info2(&ctr.info.inf2, global_myworkgroup, global_myname);
1764 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
1770 init_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
1772 /* store the response in the SMB stream */
1773 if(!samr_io_r_query_dom_info("", &r_u, rdata, 0))
1776 DEBUG(5,("samr_query_dom_info: %d\n", __LINE__));
1781 /*******************************************************************
1782 api_samr_query_dom_info
1783 ********************************************************************/
1784 static BOOL api_samr_query_dom_info(pipes_struct *p)
1786 SAMR_Q_QUERY_DOMAIN_INFO q_e;
1787 prs_struct *data = &p->in_data.data;
1788 prs_struct *rdata = &p->out_data.rdata;
1790 /* grab the samr unknown 8 command */
1791 if(!samr_io_q_query_dom_info("", &q_e, data, 0))
1794 /* construct reply. */
1795 if(!samr_reply_query_dom_info(&q_e, rdata))
1801 /*******************************************************************
1802 samr_reply_unknown_32
1803 ********************************************************************/
1804 static BOOL samr_reply_unknown_32(SAMR_Q_UNKNOWN_32 *q_u,
1809 SAMR_R_UNKNOWN_32 r_u;
1811 /* set up the SAMR unknown_32 response */
1812 memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
1815 for (i = 4; i < POL_HND_SIZE; i++)
1817 r_u.pol.data[i] = i+1;
1821 init_dom_rid4(&(r_u.rid4), 0x0030, 0, 0);
1822 r_u.status = status;
1824 DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
1826 /* store the response in the SMB stream */
1827 if(!samr_io_r_unknown_32("", &r_u, rdata, 0))
1830 DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
1835 /*******************************************************************
1837 ********************************************************************/
1838 static BOOL api_samr_unknown_32(pipes_struct *p)
1841 struct sam_passwd *sam_pass;
1843 prs_struct *data = &p->in_data.data;
1844 prs_struct *rdata = &p->out_data.rdata;
1846 SAMR_Q_UNKNOWN_32 q_u;
1848 /* grab the samr unknown 32 */
1849 samr_io_q_unknown_32("", &q_u, data, 0);
1851 /* find the machine account: tell the caller if it exists.
1852 lkclXXXX i have *no* idea if this is a problem or not
1853 or even if you are supposed to construct a different
1854 reply if the account already exists...
1857 fstrcpy(mach_acct, dos_unistrn2(q_u.uni_mach_acct.buffer,
1858 q_u.uni_mach_acct.uni_str_len));
1861 sam_pass = getsam21pwnam(mach_acct);
1862 unbecome_root(True);
1864 if (sam_pass != NULL)
1866 /* machine account exists: say so */
1867 status = 0xC0000000 | NT_STATUS_USER_EXISTS;
1871 /* this could cause trouble... */
1872 DEBUG(0,("trouble!\n"));
1876 /* construct reply. */
1877 if(!samr_reply_unknown_32(&q_u, rdata, status))
1884 /*******************************************************************
1885 samr_reply_connect_anon
1886 ********************************************************************/
1887 static BOOL samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u, prs_struct *rdata)
1889 SAMR_R_CONNECT_ANON r_u;
1890 BOOL pol_open = False;
1892 /* set up the SAMR connect_anon response */
1895 /* get a (unique) handle. open a policy on it. */
1896 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1898 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1901 /* associate the domain SID with the (unique) handle. */
1902 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1904 /* oh, whoops. don't know what error message to return, here */
1905 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1908 if (r_u.status != 0 && pol_open)
1910 close_lsa_policy_hnd(&(r_u.connect_pol));
1913 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1915 /* store the response in the SMB stream */
1916 if(!samr_io_r_connect_anon("", &r_u, rdata, 0))
1919 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1924 /*******************************************************************
1925 api_samr_connect_anon
1926 ********************************************************************/
1927 static BOOL api_samr_connect_anon(pipes_struct *p)
1929 SAMR_Q_CONNECT_ANON q_u;
1930 prs_struct *data = &p->in_data.data;
1931 prs_struct *rdata = &p->out_data.rdata;
1933 /* grab the samr open policy */
1934 if(!samr_io_q_connect_anon("", &q_u, data, 0))
1937 /* construct reply. always indicate success */
1938 if(!samr_reply_connect_anon(&q_u, rdata))
1944 /*******************************************************************
1946 ********************************************************************/
1947 static BOOL samr_reply_connect(SAMR_Q_CONNECT *q_u, prs_struct *rdata)
1950 BOOL pol_open = False;
1952 /* set up the SAMR connect response */
1955 /* get a (unique) handle. open a policy on it. */
1956 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1958 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1961 /* associate the domain SID with the (unique) handle. */
1962 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1964 /* oh, whoops. don't know what error message to return, here */
1965 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1968 if (r_u.status != 0 && pol_open)
1970 close_lsa_policy_hnd(&(r_u.connect_pol));
1973 DEBUG(5,("samr_connect: %d\n", __LINE__));
1975 /* store the response in the SMB stream */
1976 if(!samr_io_r_connect("", &r_u, rdata, 0))
1979 DEBUG(5,("samr_connect: %d\n", __LINE__));
1984 /*******************************************************************
1986 ********************************************************************/
1987 static BOOL api_samr_connect(pipes_struct *p)
1990 prs_struct *data = &p->in_data.data;
1991 prs_struct *rdata = &p->out_data.rdata;
1993 /* grab the samr open policy */
1994 if(!samr_io_q_connect("", &q_u, data, 0))
1997 /* construct reply. always indicate success */
1998 if(!samr_reply_connect(&q_u, rdata))
2004 /**********************************************************************
2005 api_reply_lookup_domain
2006 **********************************************************************/
2007 static BOOL samr_reply_lookup_domain(SAMR_Q_LOOKUP_DOMAIN* q_u, prs_struct* rdata)
2009 SAMR_R_LOOKUP_DOMAIN r_u;
2012 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->connect_pol)) == -1))
2014 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
2015 DEBUG(5,("samr_reply_lookup_domain: invalid handle\n"));
2018 /* assume the domain name sent is our global_myname and
2019 send global_sam_sid */
2020 init_samr_r_lookup_domain(&r_u, &global_sam_sid, r_u.status);
2022 if(!samr_io_r_lookup_domain("", &r_u, rdata, 0))
2025 DEBUG(5,("samr_reply_lookup_domain: %d\n", __LINE__));
2030 /**********************************************************************
2031 api_samr_lookup_domain
2032 **********************************************************************/
2033 static BOOL api_samr_lookup_domain(pipes_struct *p)
2035 SAMR_Q_LOOKUP_DOMAIN q_u;
2036 prs_struct *data = &p->in_data.data;
2037 prs_struct *rdata = &p->out_data.rdata;
2039 if(!samr_io_q_lookup_domain("", &q_u, data, 0))
2042 if(!samr_reply_lookup_domain(&q_u, rdata))
2048 /**********************************************************************
2049 samr_reply_enum_domains
2050 **********************************************************************/
2051 static BOOL samr_reply_enum_domains(SAMR_Q_ENUM_DOMAINS* q_u, prs_struct* rdata)
2053 SAMR_R_ENUM_DOMAINS r_u;
2056 fstrcpy(dom[0],global_myname);
2057 fstrcpy(dom[1],"Builtin");
2060 init_samr_r_enum_domains(&r_u, q_u->start_idx, dom, 2);
2061 if(!samr_io_r_enum_domains("", &r_u, rdata, 0)) {
2063 free(r_u.uni_dom_name);
2068 free(r_u.uni_dom_name);
2073 /**********************************************************************
2074 api_samr_enum_domains
2075 **********************************************************************/
2076 static BOOL api_samr_enum_domains(pipes_struct *p)
2078 SAMR_Q_ENUM_DOMAINS q_u;
2079 prs_struct *data = &p->in_data.data;
2080 prs_struct *rdata = &p->out_data.rdata;
2082 if(!samr_io_q_enum_domains("", &q_u, data, 0))
2085 if(!samr_reply_enum_domains(&q_u, rdata))
2091 /*******************************************************************
2092 samr_reply_open_alias
2093 ********************************************************************/
2094 static BOOL samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u, prs_struct *rdata)
2096 SAMR_R_OPEN_ALIAS r_u;
2097 BOOL pol_open = False;
2099 /* set up the SAMR open_alias response */
2102 /* get a (unique) handle. open a policy on it. */
2103 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.pol))))
2105 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2108 /* associate a RID with the (unique) handle. */
2109 if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.pol), q_u->rid_alias))
2111 /* oh, whoops. don't know what error message to return, here */
2112 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2115 if (r_u.status != 0 && pol_open)
2117 close_lsa_policy_hnd(&(r_u.pol));
2120 DEBUG(5,("samr_open_alias: %d\n", __LINE__));
2122 /* store the response in the SMB stream */
2123 if(!samr_io_r_open_alias("", &r_u, rdata, 0))
2126 DEBUG(5,("samr_open_alias: %d\n", __LINE__));
2131 /*******************************************************************
2133 ********************************************************************/
2134 static BOOL api_samr_open_alias(pipes_struct *p)
2136 SAMR_Q_OPEN_ALIAS q_u;
2137 prs_struct *data = &p->in_data.data;
2138 prs_struct *rdata = &p->out_data.rdata;
2140 /* grab the samr open policy */
2141 if(!samr_io_q_open_alias("", &q_u, data, 0))
2144 /* construct reply. always indicate success */
2145 if(!samr_reply_open_alias(&q_u, rdata))
2151 /*******************************************************************
2152 array of \PIPE\samr operations
2153 ********************************************************************/
2154 static struct api_struct api_samr_cmds [] =
2156 { "SAMR_CLOSE_HND" , SAMR_CLOSE_HND , api_samr_close_hnd },
2157 { "SAMR_CONNECT" , SAMR_CONNECT , api_samr_connect },
2158 { "SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON , api_samr_connect_anon },
2159 { "SAMR_ENUM_DOM_USERS" , SAMR_ENUM_DOM_USERS , api_samr_enum_dom_users },
2160 { "SAMR_ENUM_DOM_GROUPS" , SAMR_ENUM_DOM_GROUPS , api_samr_enum_dom_groups },
2161 { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
2162 { "SAMR_LOOKUP_IDS" , SAMR_LOOKUP_IDS , api_samr_lookup_ids },
2163 { "SAMR_LOOKUP_NAMES" , SAMR_LOOKUP_NAMES , api_samr_lookup_names },
2164 { "SAMR_OPEN_USER" , SAMR_OPEN_USER , api_samr_open_user },
2165 { "SAMR_QUERY_USERINFO" , SAMR_QUERY_USERINFO , api_samr_query_userinfo },
2166 { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
2167 { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
2168 { "SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo },
2169 { "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo },
2170 { "SAMR_0x32" , 0x32 , api_samr_unknown_32 },
2171 { "SAMR_UNKNOWN_12" , SAMR_UNKNOWN_12 , api_samr_unknown_12 },
2172 { "SAMR_UNKNOWN_38" , SAMR_UNKNOWN_38 , api_samr_unknown_38 },
2173 { "SAMR_CHGPASSWD_USER" , SAMR_CHGPASSWD_USER , api_samr_chgpasswd_user },
2174 { "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias },
2175 { "SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain },
2176 { "SAMR_UNKNOWN_3" , SAMR_UNKNOWN_3 , api_samr_unknown_3 },
2177 { "SAMR_UNKNOWN_2C" , SAMR_UNKNOWN_2C , api_samr_unknown_2c },
2178 { "SAMR_LOOKUP_DOMAIN" , SAMR_LOOKUP_DOMAIN , api_samr_lookup_domain },
2179 { "SAMR_ENUM_DOMAINS" , SAMR_ENUM_DOMAINS , api_samr_enum_domains },
2183 /*******************************************************************
2184 receives a samr pipe and responds.
2185 ********************************************************************/
2186 BOOL api_samr_rpc(pipes_struct *p)
2188 return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds);