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(pipes_struct *p)
789 SAMR_Q_ENUM_DOM_ALIASES q_e;
790 prs_struct *data = &p->in_data.data;
791 prs_struct *rdata = &p->out_data.rdata;
793 /* grab the samr open */
794 if(!samr_io_q_enum_dom_aliases("", &q_e, data, 0))
797 /* construct reply. */
798 if(!samr_reply_enum_dom_aliases(&q_e, rdata))
805 /*******************************************************************
806 samr_reply_query_dispinfo
807 ********************************************************************/
808 static BOOL samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u, prs_struct *rdata)
810 SAMR_R_QUERY_DISPINFO r_e;
814 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
816 int total_entries = 0;
818 uint16 switch_level = 0x0;
824 DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
826 /* find the policy handle. open a policy on it. */
827 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
829 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
830 DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n"));
833 if (r_e.status == 0x0)
835 /* decide how many entries to get depending on the max_entries
836 and max_size passed by client */
839 if(q_u->max_entries > MAX_SAM_ENTRIES)
840 q_u->max_entries = MAX_SAM_ENTRIES;
842 retsize = (q_u->max_entries * (sizeof(SAM_ENTRY1)+sizeof(SAM_STR1)))
845 if(retsize > q_u->max_size)
847 /* determine max_entries based on max_size */
848 q_u->max_entries = (q_u->max_size - 3*sizeof(uint32)) /
849 (sizeof(SAM_ENTRY1)+sizeof(SAM_STR1));
850 q_u->max_entries = (q_u->max_entries>0?q_u->max_entries:1);
853 DEBUG(10,("samr_reply_query_dispinfo: Setting q_u->max_entries to %u\n",q_u->max_entries));
856 got_pwds = get_passwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, q_u->max_entries, 0);
859 /* more left - set resume handle */
860 if(total_entries > num_entries)
865 switch (q_u->switch_level)
870 /* query disp info is for users */
872 init_sam_info_1(&info1, ACB_NORMAL,
873 q_u->start_idx, num_entries, pass);
875 ctr.sam.info1 = &info1;
881 /* query disp info is for servers */
883 init_sam_info_2(&info2, ACB_WSTRUST,
884 q_u->start_idx, num_entries, pass);
886 ctr.sam.info2 = &info2;
893 /* more left - set resume handle */
894 if(total_entries > num_entries)
899 if (r_e.status == 0 || r_e.status == 0x105)
901 init_samr_r_query_dispinfo(&r_e, switch_level, &ctr, r_e.status);
904 /* store the response in the SMB stream */
905 if(!samr_io_r_query_dispinfo("", &r_e, rdata, 0))
908 DEBUG(5,("samr_query_dispinfo: %d\n", __LINE__));
913 /*******************************************************************
914 api_samr_query_dispinfo
915 ********************************************************************/
916 static BOOL api_samr_query_dispinfo(pipes_struct *p)
918 SAMR_Q_QUERY_DISPINFO q_e;
919 prs_struct *data = &p->in_data.data;
920 prs_struct *rdata = &p->out_data.rdata;
922 /* grab the samr open */
923 if(!samr_io_q_query_dispinfo("", &q_e, data, 0))
926 /* construct reply. */
927 if(!samr_reply_query_dispinfo(&q_e, rdata))
934 /*******************************************************************
935 samr_reply_query_aliasinfo
936 ********************************************************************/
937 static BOOL samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
940 SAMR_R_QUERY_ALIASINFO r_e;
941 fstring alias_desc = "Local Unix group";
948 DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__));
950 /* find the policy handle. open a policy on it. */
951 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
953 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
956 alias_rid = get_lsa_policy_samr_rid(&q_u->pol);
957 if(alias_rid == 0xffffffff)
958 r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
960 if(!lookup_local_rid(alias_rid, alias, &type))
962 r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
965 init_samr_r_query_aliasinfo(&r_e, q_u->switch_level, alias, alias_desc);
967 /* store the response in the SMB stream */
968 if(!samr_io_r_query_aliasinfo("", &r_e, rdata, 0))
971 DEBUG(5,("samr_query_aliasinfo: %d\n", __LINE__));
976 /*******************************************************************
977 api_samr_query_aliasinfo
978 ********************************************************************/
979 static BOOL api_samr_query_aliasinfo(pipes_struct *p)
981 SAMR_Q_QUERY_ALIASINFO q_e;
982 prs_struct *data = &p->in_data.data;
983 prs_struct *rdata = &p->out_data.rdata;
985 /* grab the samr open */
986 if(!samr_io_q_query_aliasinfo("", &q_e, data, 0))
989 /* construct reply. */
990 if(!samr_reply_query_aliasinfo(&q_e, rdata))
997 /*******************************************************************
998 samr_reply_lookup_ids
999 ********************************************************************/
1000 static BOOL samr_reply_lookup_ids(SAMR_Q_LOOKUP_IDS *q_u,
1003 uint32 rid[MAX_SAM_ENTRIES];
1005 int num_rids = q_u->num_sids1;
1007 SAMR_R_LOOKUP_IDS r_u;
1009 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
1011 if (num_rids > MAX_SAM_ENTRIES)
1013 num_rids = MAX_SAM_ENTRIES;
1014 DEBUG(5,("samr_lookup_ids: truncating entries to %d\n", num_rids));
1019 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1021 for (i = 0; i < num_rids && status == 0; i++)
1023 struct sam_passwd *sam_pass;
1027 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1028 q_u->uni_user_name[i].uni_str_len));
1030 /* find the user account */
1032 sam_pass = get_smb21pwd_entry(user_name, 0);
1035 if (sam_pass == NULL)
1037 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1042 rid[i] = sam_pass->user_rid;
1048 rid[0] = BUILTIN_ALIAS_RID_USERS;
1050 init_samr_r_lookup_ids(&r_u, num_rids, rid, status);
1052 /* store the response in the SMB stream */
1053 if(!samr_io_r_lookup_ids("", &r_u, rdata, 0))
1056 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
1061 /*******************************************************************
1063 ********************************************************************/
1064 static BOOL api_samr_lookup_ids(pipes_struct *p)
1066 SAMR_Q_LOOKUP_IDS q_u;
1067 prs_struct *data = &p->in_data.data;
1068 prs_struct *rdata = &p->out_data.rdata;
1070 /* grab the samr 0x10 */
1071 if(!samr_io_q_lookup_ids("", &q_u, data, 0))
1074 /* construct reply. always indicate success */
1075 if(!samr_reply_lookup_ids(&q_u, rdata))
1081 /*******************************************************************
1082 samr_reply_lookup_names
1083 ********************************************************************/
1085 static BOOL samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
1088 uint32 rid[MAX_SAM_ENTRIES];
1089 uint8 type[MAX_SAM_ENTRIES];
1092 int num_rids = q_u->num_names1;
1095 SAMR_R_LOOKUP_NAMES r_u;
1097 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1102 if (!get_lsa_policy_samr_sid(&q_u->pol, &pol_sid)) {
1103 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
1104 init_samr_r_lookup_names(&r_u, 0, rid, type, status);
1105 if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
1106 DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
1112 if (num_rids > MAX_SAM_ENTRIES) {
1113 num_rids = MAX_SAM_ENTRIES;
1114 DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
1117 SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
1119 for (i = 0; i < num_rids; i++) {
1122 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
1124 rid [i] = 0xffffffff;
1125 type[i] = SID_NAME_UNKNOWN;
1127 fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer,
1128 q_u->uni_name[i].uni_str_len));
1130 if(sid_equal(&pol_sid, &global_sam_sid))
1133 if(lookup_local_name(global_myname, name,
1136 sid_split_rid( &sid, &rid[i]);
1142 init_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
1144 /* store the response in the SMB stream */
1145 if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
1146 DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
1150 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1155 /*******************************************************************
1156 api_samr_lookup_names
1157 ********************************************************************/
1159 static BOOL api_samr_lookup_names(pipes_struct *p)
1161 SAMR_Q_LOOKUP_NAMES q_u;
1162 prs_struct *data = &p->in_data.data;
1163 prs_struct *rdata = &p->out_data.rdata;
1165 memset(&q_u, '\0', sizeof(q_u));
1167 /* grab the samr lookup names */
1168 if(!samr_io_q_lookup_names("", &q_u, data, 0)) {
1169 DEBUG(0,("api_samr_lookup_names: failed to unmarshall SAMR_Q_LOOKUP_NAMES.\n"));
1173 /* construct reply. always indicate success */
1174 if(!samr_reply_lookup_names(&q_u, rdata))
1180 /*******************************************************************
1181 samr_reply_chgpasswd_user
1182 ********************************************************************/
1184 static BOOL samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
1187 SAMR_R_CHGPASSWD_USER r_u;
1188 uint32 status = 0x0;
1192 fstrcpy(user_name, dos_unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len));
1193 fstrcpy(wks , dos_unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len));
1195 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1197 if (!pass_oem_change(user_name,
1198 q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1199 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1201 status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
1204 init_samr_r_chgpasswd_user(&r_u, status);
1206 /* store the response in the SMB stream */
1207 if(!samr_io_r_chgpasswd_user("", &r_u, rdata, 0)) {
1208 DEBUG(0,("samr_reply_chgpasswd_user: Failed to marshall SAMR_R_CHGPASSWD_USER struct.\n" ));
1212 DEBUG(5,("samr_chgpasswd_user: %d\n", __LINE__));
1216 /*******************************************************************
1217 api_samr_chgpasswd_user
1218 ********************************************************************/
1220 static BOOL api_samr_chgpasswd_user(pipes_struct *p)
1222 SAMR_Q_CHGPASSWD_USER q_u;
1223 prs_struct *data = &p->in_data.data;
1224 prs_struct *rdata = &p->out_data.rdata;
1226 /* unknown 38 command */
1227 if (!samr_io_q_chgpasswd_user("", &q_u, data, 0)) {
1228 DEBUG(0,("api_samr_chgpasswd_user: samr_io_q_chgpasswd_user failed to parse RPC packet.\n"));
1232 /* construct reply. */
1233 if(!samr_reply_chgpasswd_user(&q_u, rdata)) {
1234 DEBUG(0,("api_samr_chgpasswd_user: samr_reply_chgpasswd_user failed to create reply packet.\n"));
1242 /*******************************************************************
1243 samr_reply_unknown_38
1244 ********************************************************************/
1245 static BOOL samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u, prs_struct *rdata)
1247 SAMR_R_UNKNOWN_38 r_u;
1249 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1251 init_samr_r_unknown_38(&r_u);
1253 /* store the response in the SMB stream */
1254 if(!samr_io_r_unknown_38("", &r_u, rdata, 0))
1257 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1261 /*******************************************************************
1263 ********************************************************************/
1264 static BOOL api_samr_unknown_38(pipes_struct *p)
1266 SAMR_Q_UNKNOWN_38 q_u;
1267 prs_struct *data = &p->in_data.data;
1268 prs_struct *rdata = &p->out_data.rdata;
1270 /* unknown 38 command */
1271 if(!samr_io_q_unknown_38("", &q_u, data, 0))
1274 /* construct reply. always indicate success */
1275 if(!samr_reply_unknown_38(&q_u, rdata))
1282 /*******************************************************************
1283 samr_reply_unknown_12
1284 ********************************************************************/
1285 static BOOL samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
1288 fstring group_names[MAX_SAM_ENTRIES];
1289 uint32 group_attrs[MAX_SAM_ENTRIES];
1291 int num_gids = q_u->num_gids1;
1293 SAMR_R_UNKNOWN_12 r_u;
1295 DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
1297 /* find the policy handle. open a policy on it. */
1298 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1300 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1306 if (num_gids > MAX_SAM_ENTRIES)
1308 num_gids = MAX_SAM_ENTRIES;
1309 DEBUG(5,("samr_unknown_12: truncating entries to %d\n", num_gids));
1312 for (i = 0; i < num_gids && status == 0; i++)
1314 fstrcpy(group_names[i], "dummy group");
1315 group_attrs[i] = 0x2;
1319 init_samr_r_unknown_12(&r_u, num_gids, group_names, group_attrs, status);
1321 /* store the response in the SMB stream */
1322 if(!samr_io_r_unknown_12("", &r_u, rdata, 0))
1325 DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
1330 /*******************************************************************
1332 ********************************************************************/
1333 static BOOL api_samr_unknown_12(pipes_struct *p)
1335 SAMR_Q_UNKNOWN_12 q_u;
1336 prs_struct *data = &p->in_data.data;
1337 prs_struct *rdata = &p->out_data.rdata;
1339 /* grab the samr lookup names */
1340 if(!samr_io_q_unknown_12("", &q_u, data, 0))
1343 /* construct reply. always indicate success */
1344 if(!samr_reply_unknown_12(&q_u, rdata))
1351 /*******************************************************************
1352 samr_reply_open_user
1353 ********************************************************************/
1354 static BOOL samr_reply_open_user(SAMR_Q_OPEN_USER *q_u, prs_struct *rdata, int status)
1356 SAMR_R_OPEN_USER r_u;
1357 struct sam_passwd *sam_pass;
1358 BOOL pol_open = False;
1360 /* set up the SAMR open_user response */
1361 memset((char *)r_u.user_pol.data, '\0', POL_HND_SIZE);
1365 /* find the policy handle. open a policy on it. */
1366 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
1368 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1371 /* get a (unique) handle. open a policy on it. */
1372 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.user_pol))))
1374 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1378 sam_pass = getsam21pwrid(q_u->user_rid);
1381 /* check that the RID exists in our domain. */
1382 if (r_u.status == 0x0 && sam_pass == NULL)
1384 r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1387 /* associate the RID with the (unique) handle. */
1388 if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.user_pol), q_u->user_rid))
1390 /* oh, whoops. don't know what error message to return, here */
1391 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1394 if (r_u.status != 0 && pol_open)
1396 close_lsa_policy_hnd(&(r_u.user_pol));
1399 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1401 /* store the response in the SMB stream */
1402 if(!samr_io_r_open_user("", &r_u, rdata, 0))
1405 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1410 /*******************************************************************
1412 ********************************************************************/
1413 static BOOL api_samr_open_user(pipes_struct *p)
1415 SAMR_Q_OPEN_USER q_u;
1416 prs_struct *data = &p->in_data.data;
1417 prs_struct *rdata = &p->out_data.rdata;
1419 /* grab the samr unknown 22 */
1420 if(!samr_io_q_open_user("", &q_u, data, 0))
1423 /* construct reply. always indicate success */
1424 if(!samr_reply_open_user(&q_u, rdata, 0x0))
1431 /*************************************************************************
1433 *************************************************************************/
1434 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1436 struct smb_passwd *smb_pass;
1438 if (!pdb_rid_is_user(user_rid))
1440 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1445 smb_pass = getsmbpwrid(user_rid);
1448 if (smb_pass == NULL)
1450 DEBUG(4,("User 0x%x not found\n", user_rid));
1454 DEBUG(3,("User:[%s]\n", smb_pass->smb_name));
1456 init_sam_user_info10(id10, smb_pass->acct_ctrl);
1461 /*************************************************************************
1463 *************************************************************************/
1464 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1467 struct sam_passwd *sam_pass;
1471 if (!pdb_rid_is_user(user_rid))
1473 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1478 sam_pass = getsam21pwrid(user_rid);
1481 if (sam_pass == NULL)
1483 DEBUG(4,("User 0x%x not found\n", user_rid));
1487 DEBUG(3,("User:[%s]\n", sam_pass->smb_name));
1489 dummy_time.low = 0xffffffff;
1490 dummy_time.high = 0x7fffffff;
1492 DEBUG(5,("get_user_info_21 - TODO: convert unix times to NTTIMEs\n"));
1494 /* create a LOGON_HRS structure */
1495 hrs.len = sam_pass->hours_len;
1496 SMB_ASSERT_ARRAY(hrs.hours, hrs.len);
1497 for (i = 0; i < hrs.len; i++)
1499 hrs.hours[i] = sam_pass->hours[i];
1502 init_sam_user_info21(id21,
1504 &dummy_time, /* logon_time */
1505 &dummy_time, /* logoff_time */
1506 &dummy_time, /* kickoff_time */
1507 &dummy_time, /* pass_last_set_time */
1508 &dummy_time, /* pass_can_change_time */
1509 &dummy_time, /* pass_must_change_time */
1511 sam_pass->smb_name, /* user_name */
1512 sam_pass->full_name, /* full_name */
1513 sam_pass->home_dir, /* home_dir */
1514 sam_pass->dir_drive, /* dir_drive */
1515 sam_pass->logon_script, /* logon_script */
1516 sam_pass->profile_path, /* profile_path */
1517 sam_pass->acct_desc, /* description */
1518 sam_pass->workstations, /* workstations user can log in from */
1519 sam_pass->unknown_str, /* don't know, yet */
1520 sam_pass->munged_dial, /* dialin info. contains dialin path and tel no */
1522 sam_pass->user_rid, /* RID user_id */
1523 sam_pass->group_rid, /* RID group_id */
1524 sam_pass->acct_ctrl,
1526 sam_pass->unknown_3, /* unknown_3 */
1527 sam_pass->logon_divs, /* divisions per week */
1528 &hrs, /* logon hours */
1529 sam_pass->unknown_5,
1530 sam_pass->unknown_6);
1535 /*******************************************************************
1536 samr_reply_query_userinfo
1537 ********************************************************************/
1538 static BOOL samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
1541 SAMR_R_QUERY_USERINFO r_u;
1543 SAM_USER_INFO_11 id11;
1545 SAM_USER_INFO_10 id10;
1546 SAM_USER_INFO_21 id21;
1549 uint32 status = 0x0;
1552 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1554 /* search for the handle */
1555 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1557 status = NT_STATUS_INVALID_HANDLE;
1560 /* find the user's rid */
1561 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1563 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1566 DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
1568 /* ok! user info levels (there are lots: see MSDEV help), off we go... */
1571 switch (q_u->switch_value)
1575 info = (void*)&id10;
1576 status = get_user_info_10(&id10, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1580 /* whoops - got this wrong. i think. or don't understand what's happening. */
1584 info = (void*)&id11;
1586 expire.low = 0xffffffff;
1587 expire.high = 0x7fffffff;
1589 make_sam_user_info11(&id11, &expire, "BROOKFIELDS$", 0x03ef, 0x201, 0x0080);
1596 info = (void*)&id21;
1597 status = get_user_info_21(&id21, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1603 status = NT_STATUS_INVALID_INFO_CLASS;
1610 init_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
1612 /* store the response in the SMB stream */
1613 if(!samr_io_r_query_userinfo("", &r_u, rdata, 0))
1616 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1621 /*******************************************************************
1622 api_samr_query_userinfo
1623 ********************************************************************/
1624 static BOOL api_samr_query_userinfo(pipes_struct *p)
1626 SAMR_Q_QUERY_USERINFO q_u;
1627 prs_struct *data = &p->in_data.data;
1628 prs_struct *rdata = &p->out_data.rdata;
1630 /* grab the samr unknown 24 */
1631 if(!samr_io_q_query_userinfo("", &q_u, data, 0))
1634 /* construct reply. always indicate success */
1635 if(!samr_reply_query_userinfo(&q_u, rdata))
1642 /*******************************************************************
1643 samr_reply_query_usergroups
1644 ********************************************************************/
1645 static BOOL samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
1648 SAMR_R_QUERY_USERGROUPS r_u;
1649 uint32 status = 0x0;
1651 struct sam_passwd *sam_pass;
1652 DOM_GID *gids = NULL;
1656 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1658 /* find the policy handle. open a policy on it. */
1659 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1661 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1664 /* find the user's rid */
1665 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1667 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1673 sam_pass = getsam21pwrid(rid);
1676 if (sam_pass == NULL)
1678 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1685 get_domain_user_groups(groups, sam_pass->smb_name);
1687 num_groups = make_dom_gids(groups, &gids);
1690 /* construct the response. lkclXXXX: gids are not copied! */
1691 init_samr_r_query_usergroups(&r_u, num_groups, gids, status);
1693 /* store the response in the SMB stream */
1694 if(!samr_io_r_query_usergroups("", &r_u, rdata, 0)) {
1703 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1708 /*******************************************************************
1709 api_samr_query_usergroups
1710 ********************************************************************/
1711 static BOOL api_samr_query_usergroups(pipes_struct *p)
1713 SAMR_Q_QUERY_USERGROUPS q_u;
1714 prs_struct *data = &p->in_data.data;
1715 prs_struct *rdata = &p->out_data.rdata;
1717 /* grab the samr unknown 32 */
1718 if(!samr_io_q_query_usergroups("", &q_u, data, 0))
1721 /* construct reply. */
1722 if(!samr_reply_query_usergroups(&q_u, rdata))
1729 /*******************************************************************
1730 samr_reply_query_dom_info
1731 ********************************************************************/
1732 static BOOL samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_struct *rdata)
1734 SAMR_R_QUERY_DOMAIN_INFO r_u;
1736 uint16 switch_value = 0x0;
1737 uint32 status = 0x0;
1744 DEBUG(5,("samr_reply_query_dom_info: %d\n", __LINE__));
1746 /* find the policy handle. open a policy on it. */
1747 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
1749 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1750 DEBUG(5,("samr_reply_query_dom_info: invalid handle\n"));
1755 switch (q_u->switch_value)
1760 init_unk_info2(&ctr.info.inf2, global_myworkgroup, global_myname);
1766 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
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))
1778 DEBUG(5,("samr_query_dom_info: %d\n", __LINE__));
1783 /*******************************************************************
1784 api_samr_query_dom_info
1785 ********************************************************************/
1786 static BOOL api_samr_query_dom_info(pipes_struct *p)
1788 SAMR_Q_QUERY_DOMAIN_INFO q_e;
1789 prs_struct *data = &p->in_data.data;
1790 prs_struct *rdata = &p->out_data.rdata;
1792 /* grab the samr unknown 8 command */
1793 if(!samr_io_q_query_dom_info("", &q_e, data, 0))
1796 /* construct reply. */
1797 if(!samr_reply_query_dom_info(&q_e, rdata))
1803 /*******************************************************************
1804 samr_reply_unknown_32
1805 ********************************************************************/
1806 static BOOL samr_reply_unknown_32(SAMR_Q_UNKNOWN_32 *q_u,
1811 SAMR_R_UNKNOWN_32 r_u;
1813 /* set up the SAMR unknown_32 response */
1814 memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
1817 for (i = 4; i < POL_HND_SIZE; i++)
1819 r_u.pol.data[i] = i+1;
1823 init_dom_rid4(&(r_u.rid4), 0x0030, 0, 0);
1824 r_u.status = status;
1826 DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
1828 /* store the response in the SMB stream */
1829 if(!samr_io_r_unknown_32("", &r_u, rdata, 0))
1832 DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
1837 /*******************************************************************
1839 ********************************************************************/
1840 static BOOL api_samr_unknown_32(pipes_struct *p)
1843 struct sam_passwd *sam_pass;
1845 prs_struct *data = &p->in_data.data;
1846 prs_struct *rdata = &p->out_data.rdata;
1848 SAMR_Q_UNKNOWN_32 q_u;
1850 /* grab the samr unknown 32 */
1851 samr_io_q_unknown_32("", &q_u, data, 0);
1853 /* find the machine account: tell the caller if it exists.
1854 lkclXXXX i have *no* idea if this is a problem or not
1855 or even if you are supposed to construct a different
1856 reply if the account already exists...
1859 fstrcpy(mach_acct, dos_unistrn2(q_u.uni_mach_acct.buffer,
1860 q_u.uni_mach_acct.uni_str_len));
1863 sam_pass = getsam21pwnam(mach_acct);
1866 if (sam_pass != NULL)
1868 /* machine account exists: say so */
1869 status = 0xC0000000 | NT_STATUS_USER_EXISTS;
1873 /* this could cause trouble... */
1874 DEBUG(0,("trouble!\n"));
1878 /* construct reply. */
1879 if(!samr_reply_unknown_32(&q_u, rdata, status))
1886 /*******************************************************************
1887 samr_reply_connect_anon
1888 ********************************************************************/
1889 static BOOL samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u, prs_struct *rdata)
1891 SAMR_R_CONNECT_ANON r_u;
1892 BOOL pol_open = False;
1894 /* set up the SAMR connect_anon response */
1897 /* get a (unique) handle. open a policy on it. */
1898 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1900 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1903 /* associate the domain SID with the (unique) handle. */
1904 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1906 /* oh, whoops. don't know what error message to return, here */
1907 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1910 if (r_u.status != 0 && pol_open)
1912 close_lsa_policy_hnd(&(r_u.connect_pol));
1915 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1917 /* store the response in the SMB stream */
1918 if(!samr_io_r_connect_anon("", &r_u, rdata, 0))
1921 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1926 /*******************************************************************
1927 api_samr_connect_anon
1928 ********************************************************************/
1929 static BOOL api_samr_connect_anon(pipes_struct *p)
1931 SAMR_Q_CONNECT_ANON q_u;
1932 prs_struct *data = &p->in_data.data;
1933 prs_struct *rdata = &p->out_data.rdata;
1935 /* grab the samr open policy */
1936 if(!samr_io_q_connect_anon("", &q_u, data, 0))
1939 /* construct reply. always indicate success */
1940 if(!samr_reply_connect_anon(&q_u, rdata))
1946 /*******************************************************************
1948 ********************************************************************/
1949 static BOOL samr_reply_connect(SAMR_Q_CONNECT *q_u, prs_struct *rdata)
1952 BOOL pol_open = False;
1954 /* set up the SAMR connect response */
1957 /* get a (unique) handle. open a policy on it. */
1958 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1960 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1963 /* associate the domain SID with the (unique) handle. */
1964 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1966 /* oh, whoops. don't know what error message to return, here */
1967 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1970 if (r_u.status != 0 && pol_open)
1972 close_lsa_policy_hnd(&(r_u.connect_pol));
1975 DEBUG(5,("samr_connect: %d\n", __LINE__));
1977 /* store the response in the SMB stream */
1978 if(!samr_io_r_connect("", &r_u, rdata, 0))
1981 DEBUG(5,("samr_connect: %d\n", __LINE__));
1986 /*******************************************************************
1988 ********************************************************************/
1989 static BOOL api_samr_connect(pipes_struct *p)
1992 prs_struct *data = &p->in_data.data;
1993 prs_struct *rdata = &p->out_data.rdata;
1995 /* grab the samr open policy */
1996 if(!samr_io_q_connect("", &q_u, data, 0))
1999 /* construct reply. always indicate success */
2000 if(!samr_reply_connect(&q_u, rdata))
2006 /**********************************************************************
2007 api_reply_lookup_domain
2008 **********************************************************************/
2009 static BOOL samr_reply_lookup_domain(SAMR_Q_LOOKUP_DOMAIN* q_u, prs_struct* rdata)
2011 SAMR_R_LOOKUP_DOMAIN r_u;
2014 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->connect_pol)) == -1))
2016 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
2017 DEBUG(5,("samr_reply_lookup_domain: invalid handle\n"));
2020 /* assume the domain name sent is our global_myname and
2021 send global_sam_sid */
2022 init_samr_r_lookup_domain(&r_u, &global_sam_sid, r_u.status);
2024 if(!samr_io_r_lookup_domain("", &r_u, rdata, 0))
2027 DEBUG(5,("samr_reply_lookup_domain: %d\n", __LINE__));
2032 /**********************************************************************
2033 api_samr_lookup_domain
2034 **********************************************************************/
2035 static BOOL api_samr_lookup_domain(pipes_struct *p)
2037 SAMR_Q_LOOKUP_DOMAIN q_u;
2038 prs_struct *data = &p->in_data.data;
2039 prs_struct *rdata = &p->out_data.rdata;
2041 if(!samr_io_q_lookup_domain("", &q_u, data, 0))
2044 if(!samr_reply_lookup_domain(&q_u, rdata))
2050 /**********************************************************************
2051 samr_reply_enum_domains
2052 **********************************************************************/
2053 static BOOL samr_reply_enum_domains(SAMR_Q_ENUM_DOMAINS* q_u, prs_struct* rdata)
2055 SAMR_R_ENUM_DOMAINS r_u;
2058 fstrcpy(dom[0],global_myname);
2059 fstrcpy(dom[1],"Builtin");
2062 init_samr_r_enum_domains(&r_u, q_u->start_idx, dom, 2);
2063 if(!samr_io_r_enum_domains("", &r_u, rdata, 0)) {
2065 free(r_u.uni_dom_name);
2070 free(r_u.uni_dom_name);
2075 /**********************************************************************
2076 api_samr_enum_domains
2077 **********************************************************************/
2078 static BOOL api_samr_enum_domains(pipes_struct *p)
2080 SAMR_Q_ENUM_DOMAINS q_u;
2081 prs_struct *data = &p->in_data.data;
2082 prs_struct *rdata = &p->out_data.rdata;
2084 if(!samr_io_q_enum_domains("", &q_u, data, 0))
2087 if(!samr_reply_enum_domains(&q_u, rdata))
2093 /*******************************************************************
2094 samr_reply_open_alias
2095 ********************************************************************/
2096 static BOOL samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u, prs_struct *rdata)
2098 SAMR_R_OPEN_ALIAS r_u;
2099 BOOL pol_open = False;
2101 /* set up the SAMR open_alias response */
2104 /* get a (unique) handle. open a policy on it. */
2105 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.pol))))
2107 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2110 /* associate a RID with the (unique) handle. */
2111 if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.pol), q_u->rid_alias))
2113 /* oh, whoops. don't know what error message to return, here */
2114 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2117 if (r_u.status != 0 && pol_open)
2119 close_lsa_policy_hnd(&(r_u.pol));
2122 DEBUG(5,("samr_open_alias: %d\n", __LINE__));
2124 /* store the response in the SMB stream */
2125 if(!samr_io_r_open_alias("", &r_u, rdata, 0))
2128 DEBUG(5,("samr_open_alias: %d\n", __LINE__));
2133 /*******************************************************************
2135 ********************************************************************/
2136 static BOOL api_samr_open_alias(pipes_struct *p)
2138 SAMR_Q_OPEN_ALIAS q_u;
2139 prs_struct *data = &p->in_data.data;
2140 prs_struct *rdata = &p->out_data.rdata;
2142 /* grab the samr open policy */
2143 if(!samr_io_q_open_alias("", &q_u, data, 0))
2146 /* construct reply. always indicate success */
2147 if(!samr_reply_open_alias(&q_u, rdata))
2153 /*******************************************************************
2154 array of \PIPE\samr operations
2155 ********************************************************************/
2156 static struct api_struct api_samr_cmds [] =
2158 { "SAMR_CLOSE_HND" , SAMR_CLOSE_HND , api_samr_close_hnd },
2159 { "SAMR_CONNECT" , SAMR_CONNECT , api_samr_connect },
2160 { "SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON , api_samr_connect_anon },
2161 { "SAMR_ENUM_DOM_USERS" , SAMR_ENUM_DOM_USERS , api_samr_enum_dom_users },
2162 { "SAMR_ENUM_DOM_GROUPS" , SAMR_ENUM_DOM_GROUPS , api_samr_enum_dom_groups },
2163 { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
2164 { "SAMR_LOOKUP_IDS" , SAMR_LOOKUP_IDS , api_samr_lookup_ids },
2165 { "SAMR_LOOKUP_NAMES" , SAMR_LOOKUP_NAMES , api_samr_lookup_names },
2166 { "SAMR_OPEN_USER" , SAMR_OPEN_USER , api_samr_open_user },
2167 { "SAMR_QUERY_USERINFO" , SAMR_QUERY_USERINFO , api_samr_query_userinfo },
2168 { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
2169 { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
2170 { "SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo },
2171 { "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo },
2172 { "SAMR_0x32" , 0x32 , api_samr_unknown_32 },
2173 { "SAMR_UNKNOWN_12" , SAMR_UNKNOWN_12 , api_samr_unknown_12 },
2174 { "SAMR_UNKNOWN_38" , SAMR_UNKNOWN_38 , api_samr_unknown_38 },
2175 { "SAMR_CHGPASSWD_USER" , SAMR_CHGPASSWD_USER , api_samr_chgpasswd_user },
2176 { "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias },
2177 { "SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain },
2178 { "SAMR_UNKNOWN_3" , SAMR_UNKNOWN_3 , api_samr_unknown_3 },
2179 { "SAMR_UNKNOWN_2C" , SAMR_UNKNOWN_2C , api_samr_unknown_2c },
2180 { "SAMR_LOOKUP_DOMAIN" , SAMR_LOOKUP_DOMAIN , api_samr_lookup_domain },
2181 { "SAMR_ENUM_DOMAINS" , SAMR_ENUM_DOMAINS , api_samr_enum_domains },
2185 /*******************************************************************
2186 receives a samr pipe and responds.
2187 ********************************************************************/
2188 BOOL api_samr_rpc(pipes_struct *p)
2190 return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds);