4 * Unix SMB/Netbios implementation.
6 * RPC Pipe client / server routines
7 * Copyright (C) Andrew Tridgell 1992-1997,
8 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
9 * Copyright (C) Paul Ashton 1997.
10 * Copyright (C) Hewlett-Packard Company 1999.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 extern int DEBUGLEVEL;
31 extern fstring global_myworkgroup;
32 extern pstring global_myname;
33 extern DOM_SID global_sam_sid;
35 extern rid_name domain_group_rids[];
36 extern rid_name domain_alias_rids[];
37 extern rid_name builtin_alias_rids[];
39 /*******************************************************************
40 This next function should be replaced with something that
41 dynamically returns the correct user info..... JRA.
42 ********************************************************************/
44 static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf,
46 int *total_entries, int *num_entries,
51 struct sam_passwd *pwd = NULL;
56 if (pw_buf == NULL) return False;
58 vp = startsmbpwent(False);
60 DEBUG(0, ("get_sampwd_entries: Unable to open SMB password database.\n"));
64 while (((pwd = getsam21pwent(vp)) != NULL) && (*num_entries) < max_num_entries) {
68 /* skip the requested number of entries.
69 not very efficient, but hey...
75 user_name_len = strlen(pwd->smb_name);
76 init_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->smb_name, user_name_len);
77 init_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
78 pw_buf[(*num_entries)].user_rid = pwd->user_rid;
79 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
81 /* Now check if the NT compatible password is available. */
82 if (pwd->smb_nt_passwd != NULL) {
83 memcpy( pw_buf[(*num_entries)].nt_pwd , pwd->smb_nt_passwd, 16);
86 pw_buf[(*num_entries)].acb_info = (uint16)pwd->acct_ctrl;
88 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
89 (*num_entries), pwd->smb_name,
90 pwd->user_rid, pwd->acct_ctrl));
92 if (acb_mask == 0 || IS_BITS_SET_SOME(pwd->acct_ctrl, acb_mask)) {
93 DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
96 DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
104 return (*num_entries) > 0;
107 /*******************************************************************
108 This function uses the username map file and tries to map a UNIX
109 user name to an DOS name. (Sort of the reverse of the
110 map_username() function.) Since more than one DOS name can map
111 to the UNIX name, to reverse the mapping you have to specify
112 which corresponding DOS name you want; that's where the name_idx
113 parameter comes in. Returns the string requested or NULL if it
114 fails or can't complete the request for any reason. This doesn't
115 handle group names (starting with '@') or names starting with
116 '+' or '&'. If they are encountered, they are skipped.
117 ********************************************************************/
119 static char *unmap_unixname(char *unix_user_name, int name_idx)
121 char *mapfile = lp_username_map();
126 if (!*unix_user_name) return NULL;
127 if (!*mapfile) return NULL;
129 lines = file_lines_load(mapfile, NULL);
131 DEBUG(0,("unmap_unixname: can't open username map %s\n", mapfile));
135 DEBUG(5,("unmap_unixname: scanning username map %s, index: %d\n", mapfile, name_idx));
137 for (i=0; lines[i]; i++) {
138 char *unixname = lines[i];
139 char *dosname = strchr(unixname,'=');
146 while (isspace(*unixname))
148 if ('!' == *unixname) {
150 while (*unixname && isspace(*unixname))
154 if (!*unixname || strchr("#;",*unixname))
157 if (strncmp(unixname, unix_user_name, strlen(unix_user_name)))
160 /* We have matched the UNIX user name */
162 while(next_token(&dosname, tok, LIST_SEP, sizeof(tok))) {
163 if (!strchr("@&+", *tok)) {
172 DEBUG(0,("unmap_unixname: index too high - not that many DOS names\n"));
173 file_lines_free(lines);
176 file_lines_free(lines);
181 DEBUG(0,("unmap_unixname: Couldn't find the UNIX user name\n"));
182 file_lines_free(lines);
186 /*******************************************************************
187 This function sets up a list of users taken from the list of
188 users that UNIX knows about, as well as all the user names that
189 Samba maps to a valid UNIX user name. (This should work with
191 ********************************************************************/
193 static BOOL get_passwd_entries(SAM_USER_INFO_21 *pw_buf,
195 int *total_entries, int *num_entries,
199 static struct passwd *pwd = NULL;
200 static uint32 pw_rid;
201 static BOOL orig_done = False;
202 static int current_idx = 0;
203 static int mapped_idx = 0;
205 DEBUG(5, ("get_passwd_entries: retrieving a list of UNIX users\n"));
208 (*total_entries) = 0;
210 if (pw_buf == NULL) return False;
212 if (current_idx == 0) {
216 /* These two cases are inefficient, but should be called very rarely */
217 /* they are the cases where the starting index isn't picking up */
218 /* where we left off last time. It is efficient when it starts over */
219 /* at zero though. */
220 if (start_idx > current_idx) {
221 /* We aren't far enough; advance to start_idx */
222 while (current_idx < start_idx) {
226 if ((pwd = getpwent()) == NULL) break;
231 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
232 (current_idx < start_idx)) {
237 if (unmap_name == NULL) {
242 } else if (start_idx < current_idx) {
243 /* We are already too far; start over and advance to start_idx */
249 while (current_idx < start_idx) {
253 if ((pwd = getpwent()) == NULL) break;
258 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
259 (current_idx < start_idx)) {
264 if (unmap_name == NULL) {
271 /* now current_idx == start_idx */
272 while ((*num_entries) < max_num_entries) {
276 /* This does the original UNIX user itself */
278 if ((pwd = getpwent()) == NULL) break;
279 user_name_len = strlen(pwd->pw_name);
280 pw_rid = pdb_uid_to_user_rid(pwd->pw_uid);
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 init_unistr2(&(pw_buf[(*num_entries)].uni_user_name), unmap_name, user_name_len);
301 init_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
302 pw_buf[(*num_entries)].user_rid = pw_rid;
303 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
305 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
307 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
315 if (unmap_name == NULL) {
316 /* done with 'aliases', go on to next UNIX user */
323 /* totally done, reset everything */
329 return (*num_entries) > 0;
332 /*******************************************************************
334 ********************************************************************/
335 static void samr_reply_close_hnd(SAMR_Q_CLOSE_HND *q_u,
338 SAMR_R_CLOSE_HND r_u;
340 /* set up the SAMR unknown_1 response */
341 memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
343 /* close the policy handle */
344 if (close_lsa_policy_hnd(&(q_u->pol)))
350 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_INVALID;
353 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
355 /* store the response in the SMB stream */
356 samr_io_r_close_hnd("", &r_u, rdata, 0);
358 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
362 /*******************************************************************
364 ********************************************************************/
365 static BOOL api_samr_close_hnd(prs_struct *data, prs_struct *rdata)
367 SAMR_Q_CLOSE_HND q_u;
369 /* grab the samr unknown 1 */
370 samr_io_q_close_hnd("", &q_u, data, 0);
372 /* construct reply. always indicate success */
373 samr_reply_close_hnd(&q_u, rdata);
379 /*******************************************************************
380 samr_reply_open_domain
381 ********************************************************************/
382 static void samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
385 SAMR_R_OPEN_DOMAIN r_u;
386 BOOL pol_open = False;
390 /* find the connection policy handle. */
391 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->connect_pol)) == -1))
393 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
396 /* get a (unique) handle. open a policy on it. */
397 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.domain_pol))))
399 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
402 /* associate the domain SID with the (unique) handle. */
403 if (r_u.status == 0x0 && !set_lsa_policy_samr_sid(&(r_u.domain_pol), &(q_u->dom_sid.sid)))
405 /* oh, whoops. don't know what error message to return, here */
406 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
409 if (r_u.status != 0 && pol_open)
411 close_lsa_policy_hnd(&(r_u.domain_pol));
414 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
416 /* store the response in the SMB stream */
417 samr_io_r_open_domain("", &r_u, rdata, 0);
419 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
423 /*******************************************************************
425 ********************************************************************/
426 static BOOL api_samr_open_domain(prs_struct *data, prs_struct *rdata)
428 SAMR_Q_OPEN_DOMAIN q_u;
430 /* grab the samr open */
431 samr_io_q_open_domain("", &q_u, data, 0);
433 /* construct reply. always indicate success */
434 samr_reply_open_domain(&q_u, rdata);
440 /*******************************************************************
441 samr_reply_unknown_2c
442 ********************************************************************/
443 static void samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u,
446 SAMR_R_UNKNOWN_2C r_u;
449 /* find the policy handle. open a policy on it. */
450 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
452 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
455 /* find the user's rid */
456 if ((status == 0x0) && (get_lsa_policy_samr_rid(&(q_u->user_pol)) == 0xffffffff))
458 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
461 init_samr_r_unknown_2c(&r_u, status);
463 DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
465 /* store the response in the SMB stream */
466 samr_io_r_unknown_2c("", &r_u, rdata, 0);
468 DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
472 /*******************************************************************
474 ********************************************************************/
475 static BOOL api_samr_unknown_2c(prs_struct *data, prs_struct *rdata)
477 SAMR_Q_UNKNOWN_2C q_u;
479 /* grab the samr open */
480 samr_io_q_unknown_2c("", &q_u, data, 0);
482 /* construct reply. always indicate success */
483 samr_reply_unknown_2c(&q_u, rdata);
489 /*******************************************************************
491 ********************************************************************/
492 static void samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
495 SAMR_R_UNKNOWN_3 r_u;
496 DOM_SID3 sid[MAX_SAM_SIDS];
502 /* find the policy handle. open a policy on it. */
503 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
505 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
508 /* find the user's rid */
509 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->user_pol))) == 0xffffffff)
511 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
517 DOM_SID everyone_sid;
519 user_sid = global_sam_sid;
521 SMB_ASSERT_ARRAY(user_sid.sub_auths, user_sid.num_auths+1);
526 user_sid.sub_auths[user_sid.num_auths++] = rid;
528 string_to_sid(&everyone_sid, "S-1-1");
530 /* maybe need another 1 or 2 (S-1-5-0x20-0x220 and S-1-5-20-0x224) */
531 /* these two are DOMAIN_ADMIN and DOMAIN_ACCT_OP group RIDs */
532 init_dom_sid3(&(sid[0]), 0x035b, 0x0002, &everyone_sid);
533 init_dom_sid3(&(sid[1]), 0x0044, 0x0002, &user_sid);
536 init_samr_r_unknown_3(&r_u,
538 0x00000014, 0x0002, 0x0070,
541 DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
543 /* store the response in the SMB stream */
544 samr_io_r_unknown_3("", &r_u, rdata, 0);
546 DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
550 /*******************************************************************
552 ********************************************************************/
553 static BOOL api_samr_unknown_3(prs_struct *data, prs_struct *rdata)
555 SAMR_Q_UNKNOWN_3 q_u;
557 /* grab the samr open */
558 samr_io_q_unknown_3("", &q_u, data, 0);
560 /* construct reply. always indicate success */
561 samr_reply_unknown_3(&q_u, rdata);
567 /*******************************************************************
568 samr_reply_enum_dom_users
569 ********************************************************************/
570 static void samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
573 SAMR_R_ENUM_DOM_USERS r_e;
574 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
579 r_e.total_num_entries = 0;
581 /* find the policy handle. open a policy on it. */
582 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
584 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
587 DEBUG(5,("samr_reply_enum_dom_users: %d\n", __LINE__));
590 get_sampwd_entries(pass, 0, &total_entries, &num_entries, MAX_SAM_ENTRIES, q_u->acb_mask);
593 init_samr_r_enum_dom_users(&r_e, total_entries,
594 q_u->unknown_0, num_entries,
597 /* store the response in the SMB stream */
598 samr_io_r_enum_dom_users("", &r_e, rdata, 0);
600 DEBUG(5,("samr_enum_dom_users: %d\n", __LINE__));
604 /*******************************************************************
605 api_samr_enum_dom_users
606 ********************************************************************/
607 static BOOL api_samr_enum_dom_users(prs_struct *data, prs_struct *rdata)
609 SAMR_Q_ENUM_DOM_USERS q_e;
611 /* grab the samr open */
612 samr_io_q_enum_dom_users("", &q_e, data, 0);
614 /* construct reply. */
615 samr_reply_enum_dom_users(&q_e, rdata);
621 /*******************************************************************
622 samr_reply_enum_dom_groups
623 ********************************************************************/
624 static void samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u,
627 SAMR_R_ENUM_DOM_GROUPS r_e;
628 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
631 char *dummy_group = "Domain Admins";
636 /* find the policy handle. open a policy on it. */
637 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
639 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
642 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
646 init_unistr2(&(pass[0].uni_user_name), dummy_group, strlen(dummy_group));
647 pass[0].user_rid = DOMAIN_GROUP_RID_ADMINS;
649 if (r_e.status == 0 && got_grps)
651 init_samr_r_enum_dom_groups(&r_e, q_u->start_idx, num_entries, pass, r_e.status);
654 /* store the response in the SMB stream */
655 samr_io_r_enum_dom_groups("", &r_e, rdata, 0);
657 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
661 /*******************************************************************
662 api_samr_enum_dom_groups
663 ********************************************************************/
664 static BOOL api_samr_enum_dom_groups(prs_struct *data, prs_struct *rdata)
666 SAMR_Q_ENUM_DOM_GROUPS q_e;
668 /* grab the samr open */
669 samr_io_q_enum_dom_groups("", &q_e, data, 0);
671 /* construct reply. */
672 samr_reply_enum_dom_groups(&q_e, rdata);
677 /*******************************************************************
678 samr_reply_enum_dom_aliases
679 ********************************************************************/
680 static void samr_reply_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_u,
683 SAMR_R_ENUM_DOM_ALIASES r_e;
684 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
694 /* find the policy handle. open a policy on it. */
695 if (r_e.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &sid))
697 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
700 sid_to_string(sid_str, &sid);
701 sid_to_string(sam_sid_str, &global_sam_sid);
703 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
705 /* well-known aliases */
706 if (strequal(sid_str, "S-1-5-32"))
709 while (num_entries < MAX_SAM_ENTRIES && ((name = builtin_alias_rids[num_entries].name) != NULL))
711 init_unistr2(&(pass[num_entries].uni_user_name), name, strlen(name));
712 pass[num_entries].user_rid = builtin_alias_rids[num_entries].rid;
716 else if (strequal(sid_str, sam_sid_str))
720 /* we return the UNIX groups here. This seems to be the right */
721 /* thing to do, since NT member servers return their local */
722 /* groups in the same situation. */
725 while (num_entries < MAX_SAM_ENTRIES && ((grp = getgrent()) != NULL))
728 init_unistr2(&(pass[num_entries].uni_user_name), name, strlen(name));
729 pass[num_entries].user_rid = pdb_gid_to_group_rid(grp->gr_gid);
736 init_samr_r_enum_dom_aliases(&r_e, num_entries, pass, r_e.status);
738 /* store the response in the SMB stream */
739 samr_io_r_enum_dom_aliases("", &r_e, rdata, 0);
741 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
745 /*******************************************************************
746 api_samr_enum_dom_aliases
747 ********************************************************************/
748 static BOOL api_samr_enum_dom_aliases(prs_struct *data, prs_struct *rdata)
750 SAMR_Q_ENUM_DOM_ALIASES q_e;
752 /* grab the samr open */
753 samr_io_q_enum_dom_aliases("", &q_e, data, 0);
755 /* construct reply. */
756 samr_reply_enum_dom_aliases(&q_e, rdata);
762 /*******************************************************************
763 samr_reply_query_dispinfo
764 ********************************************************************/
765 static void samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u,
768 SAMR_R_QUERY_DISPINFO r_e;
772 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
774 int total_entries = 0;
776 uint16 switch_level = 0x0;
782 DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
784 /* find the policy handle. open a policy on it. */
785 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
787 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
788 DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n"));
791 if (r_e.status == 0x0)
794 got_pwds = get_passwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, MAX_SAM_ENTRIES, 0);
797 switch (q_u->switch_level)
802 /* query disp info is for users */
804 init_sam_info_1(&info1, ACB_NORMAL,
805 q_u->start_idx, num_entries, pass);
807 ctr.sam.info1 = &info1;
813 /* query disp info is for servers */
815 init_sam_info_2(&info2, ACB_WSTRUST,
816 q_u->start_idx, num_entries, pass);
818 ctr.sam.info2 = &info2;
827 init_samr_r_query_dispinfo(&r_e, switch_level, &ctr, r_e.status);
830 /* store the response in the SMB stream */
831 samr_io_r_query_dispinfo("", &r_e, rdata, 0);
833 DEBUG(5,("samr_query_dispinfo: %d\n", __LINE__));
837 /*******************************************************************
838 api_samr_query_dispinfo
839 ********************************************************************/
840 static BOOL api_samr_query_dispinfo(prs_struct *data, prs_struct *rdata)
842 SAMR_Q_QUERY_DISPINFO q_e;
844 /* grab the samr open */
845 samr_io_q_query_dispinfo("", &q_e, data, 0);
847 /* construct reply. */
848 samr_reply_query_dispinfo(&q_e, rdata);
854 /*******************************************************************
855 samr_reply_query_aliasinfo
856 ********************************************************************/
857 static void samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
860 SAMR_R_QUERY_ALIASINFO r_e;
865 /* find the policy handle. open a policy on it. */
866 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
868 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
871 DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__));
873 if (r_e.status == 0x0)
875 if (q_u->switch_level != 3)
877 r_e.status = NT_STATUS_INVALID_INFO_CLASS;
881 init_samr_r_query_aliasinfo(&r_e, q_u->switch_level,
885 /* store the response in the SMB stream */
886 samr_io_r_query_aliasinfo("", &r_e, rdata, 0);
888 DEBUG(5,("samr_query_aliasinfo: %d\n", __LINE__));
892 /*******************************************************************
893 api_samr_query_aliasinfo
894 ********************************************************************/
895 static BOOL api_samr_query_aliasinfo(prs_struct *data, prs_struct *rdata)
897 SAMR_Q_QUERY_ALIASINFO q_e;
899 /* grab the samr open */
900 samr_io_q_query_aliasinfo("", &q_e, data, 0);
902 /* construct reply. */
903 samr_reply_query_aliasinfo(&q_e, rdata);
909 /*******************************************************************
910 samr_reply_lookup_ids
911 ********************************************************************/
912 static void samr_reply_lookup_ids(SAMR_Q_LOOKUP_IDS *q_u,
915 uint32 rid[MAX_SAM_ENTRIES];
917 int num_rids = q_u->num_sids1;
919 SAMR_R_LOOKUP_IDS r_u;
921 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
923 if (num_rids > MAX_SAM_ENTRIES)
925 num_rids = MAX_SAM_ENTRIES;
926 DEBUG(5,("samr_lookup_ids: truncating entries to %d\n", num_rids));
931 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
933 for (i = 0; i < num_rids && status == 0; i++)
935 struct sam_passwd *sam_pass;
939 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
940 q_u->uni_user_name[i].uni_str_len));
942 /* find the user account */
944 sam_pass = get_smb21pwd_entry(user_name, 0);
947 if (sam_pass == NULL)
949 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
954 rid[i] = sam_pass->user_rid;
960 rid[0] = BUILTIN_ALIAS_RID_USERS;
962 init_samr_r_lookup_ids(&r_u, num_rids, rid, status);
964 /* store the response in the SMB stream */
965 samr_io_r_lookup_ids("", &r_u, rdata, 0);
967 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
971 /*******************************************************************
973 ********************************************************************/
974 static BOOL api_samr_lookup_ids(prs_struct *data, prs_struct *rdata)
976 SAMR_Q_LOOKUP_IDS q_u;
978 /* grab the samr 0x10 */
979 samr_io_q_lookup_ids("", &q_u, data, 0);
981 /* construct reply. always indicate success */
982 samr_reply_lookup_ids(&q_u, rdata);
987 /*******************************************************************
988 samr_reply_lookup_names
989 ********************************************************************/
991 static BOOL samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
994 uint32 rid[MAX_SAM_ENTRIES];
995 uint8 type[MAX_SAM_ENTRIES];
998 int num_rids = q_u->num_names1;
1001 SAMR_R_LOOKUP_NAMES r_u;
1003 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1008 if (!get_lsa_policy_samr_sid(&q_u->pol, &pol_sid)) {
1009 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
1010 init_samr_r_lookup_names(&r_u, 0, rid, type, status);
1011 if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
1012 DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
1018 if (num_rids > MAX_SAM_ENTRIES) {
1019 num_rids = MAX_SAM_ENTRIES;
1020 DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
1023 SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
1025 for (i = 0; i < num_rids; i++) {
1028 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
1030 rid [i] = 0xffffffff;
1031 type[i] = SID_NAME_UNKNOWN;
1033 fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer,
1034 q_u->uni_name[i].uni_str_len));
1036 if(sid_equal(&pol_sid, &global_sam_sid)) {
1039 if(lookup_local_name(global_myname, name, &sid, &type[i])) {
1040 sid_split_rid( &sid, &rid[i]);
1046 init_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
1048 /* store the response in the SMB stream */
1049 if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
1050 DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
1054 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1059 /*******************************************************************
1060 api_samr_lookup_names
1061 ********************************************************************/
1063 static BOOL api_samr_lookup_names(prs_struct *data, prs_struct *rdata)
1065 SAMR_Q_LOOKUP_NAMES q_u;
1067 memset(&q_u, '\0', sizeof(q_u));
1069 /* grab the samr lookup names */
1070 if(!samr_io_q_lookup_names("", &q_u, data, 0)) {
1071 DEBUG(0,("api_samr_lookup_names: failed to unmarshall SAMR_Q_LOOKUP_NAMES.\n"));
1075 /* construct reply. always indicate success */
1076 if(!samr_reply_lookup_names(&q_u, rdata))
1082 /*******************************************************************
1083 samr_reply_chgpasswd_user
1084 ********************************************************************/
1086 static BOOL samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
1089 SAMR_R_CHGPASSWD_USER r_u;
1090 uint32 status = 0x0;
1094 fstrcpy(user_name, dos_unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len));
1095 fstrcpy(wks , dos_unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len));
1097 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1099 if (!pass_oem_change(user_name,
1100 q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1101 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1103 status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
1106 init_samr_r_chgpasswd_user(&r_u, status);
1108 /* store the response in the SMB stream */
1109 if(!samr_io_r_chgpasswd_user("", &r_u, rdata, 0)) {
1110 DEBUG(0,("samr_reply_chgpasswd_user: Failed to marshall SAMR_R_CHGPASSWD_USER struct.\n" ));
1114 DEBUG(5,("samr_chgpasswd_user: %d\n", __LINE__));
1118 /*******************************************************************
1119 api_samr_chgpasswd_user
1120 ********************************************************************/
1122 static BOOL api_samr_chgpasswd_user(prs_struct *data, prs_struct *rdata)
1124 SAMR_Q_CHGPASSWD_USER q_u;
1126 /* unknown 38 command */
1127 if (!samr_io_q_chgpasswd_user("", &q_u, data, 0)) {
1128 DEBUG(0,("api_samr_chgpasswd_user: samr_io_q_chgpasswd_user failed to parse RPC packet.\n"));
1132 /* construct reply. */
1133 if(!samr_reply_chgpasswd_user(&q_u, rdata)) {
1134 DEBUG(0,("api_samr_chgpasswd_user: samr_reply_chgpasswd_user failed to create reply packet.\n"));
1142 /*******************************************************************
1143 samr_reply_unknown_38
1144 ********************************************************************/
1145 static void samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u,
1148 SAMR_R_UNKNOWN_38 r_u;
1150 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1152 init_samr_r_unknown_38(&r_u);
1154 /* store the response in the SMB stream */
1155 samr_io_r_unknown_38("", &r_u, rdata, 0);
1157 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1160 /*******************************************************************
1162 ********************************************************************/
1163 static BOOL api_samr_unknown_38(prs_struct *data, prs_struct *rdata)
1165 SAMR_Q_UNKNOWN_38 q_u;
1167 /* unknown 38 command */
1168 samr_io_q_unknown_38("", &q_u, data, 0);
1170 /* construct reply. always indicate success */
1171 samr_reply_unknown_38(&q_u, rdata);
1177 /*******************************************************************
1178 samr_reply_unknown_12
1179 ********************************************************************/
1180 static void samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
1183 fstring group_names[MAX_SAM_ENTRIES];
1184 uint32 group_attrs[MAX_SAM_ENTRIES];
1186 int num_gids = q_u->num_gids1;
1188 SAMR_R_UNKNOWN_12 r_u;
1190 DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
1192 /* find the policy handle. open a policy on it. */
1193 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1195 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1201 if (num_gids > MAX_SAM_ENTRIES)
1203 num_gids = MAX_SAM_ENTRIES;
1204 DEBUG(5,("samr_unknown_12: truncating entries to %d\n", num_gids));
1207 for (i = 0; i < num_gids && status == 0; i++)
1209 fstrcpy(group_names[i], "dummy group");
1210 group_attrs[i] = 0x2;
1214 init_samr_r_unknown_12(&r_u, num_gids, group_names, group_attrs, status);
1216 /* store the response in the SMB stream */
1217 samr_io_r_unknown_12("", &r_u, rdata, 0);
1219 DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
1223 /*******************************************************************
1225 ********************************************************************/
1226 static BOOL api_samr_unknown_12(prs_struct *data, prs_struct *rdata)
1228 SAMR_Q_UNKNOWN_12 q_u;
1230 /* grab the samr lookup names */
1231 samr_io_q_unknown_12("", &q_u, data, 0);
1233 /* construct reply. always indicate success */
1234 samr_reply_unknown_12(&q_u, rdata);
1240 /*******************************************************************
1241 samr_reply_open_user
1242 ********************************************************************/
1243 static void samr_reply_open_user(SAMR_Q_OPEN_USER *q_u,
1247 SAMR_R_OPEN_USER r_u;
1248 struct sam_passwd *sam_pass;
1249 BOOL pol_open = False;
1251 /* set up the SAMR open_user response */
1252 memset((char *)r_u.user_pol.data, '\0', POL_HND_SIZE);
1256 /* find the policy handle. open a policy on it. */
1257 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
1259 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1262 /* get a (unique) handle. open a policy on it. */
1263 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.user_pol))))
1265 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1269 sam_pass = getsam21pwrid(q_u->user_rid);
1270 unbecome_root(True);
1272 /* check that the RID exists in our domain. */
1273 if (r_u.status == 0x0 && sam_pass == NULL)
1275 r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1278 /* associate the RID with the (unique) handle. */
1279 if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.user_pol), q_u->user_rid))
1281 /* oh, whoops. don't know what error message to return, here */
1282 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1285 if (r_u.status != 0 && pol_open)
1287 close_lsa_policy_hnd(&(r_u.user_pol));
1290 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1292 /* store the response in the SMB stream */
1293 samr_io_r_open_user("", &r_u, rdata, 0);
1295 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1299 /*******************************************************************
1301 ********************************************************************/
1302 static BOOL api_samr_open_user(prs_struct *data, prs_struct *rdata)
1304 SAMR_Q_OPEN_USER q_u;
1306 /* grab the samr unknown 22 */
1307 samr_io_q_open_user("", &q_u, data, 0);
1309 /* construct reply. always indicate success */
1310 samr_reply_open_user(&q_u, rdata, 0x0);
1316 /*************************************************************************
1318 *************************************************************************/
1319 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1321 struct smb_passwd *smb_pass;
1323 if (!pdb_rid_is_user(user_rid))
1325 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1330 smb_pass = getsmbpwrid(user_rid);
1331 unbecome_root(True);
1333 if (smb_pass == NULL)
1335 DEBUG(4,("User 0x%x not found\n", user_rid));
1339 DEBUG(3,("User:[%s]\n", smb_pass->smb_name));
1341 init_sam_user_info10(id10, smb_pass->acct_ctrl);
1346 /*************************************************************************
1348 *************************************************************************/
1349 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1352 struct sam_passwd *sam_pass;
1356 if (!pdb_rid_is_user(user_rid))
1358 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1363 sam_pass = getsam21pwrid(user_rid);
1364 unbecome_root(True);
1366 if (sam_pass == NULL)
1368 DEBUG(4,("User 0x%x not found\n", user_rid));
1372 DEBUG(3,("User:[%s]\n", sam_pass->smb_name));
1374 dummy_time.low = 0xffffffff;
1375 dummy_time.high = 0x7fffffff;
1377 DEBUG(5,("get_user_info_21 - TODO: convert unix times to NTTIMEs\n"));
1379 /* create a LOGON_HRS structure */
1380 hrs.len = sam_pass->hours_len;
1381 SMB_ASSERT_ARRAY(hrs.hours, hrs.len);
1382 for (i = 0; i < hrs.len; i++)
1384 hrs.hours[i] = sam_pass->hours[i];
1387 init_sam_user_info21(id21,
1389 &dummy_time, /* logon_time */
1390 &dummy_time, /* logoff_time */
1391 &dummy_time, /* kickoff_time */
1392 &dummy_time, /* pass_last_set_time */
1393 &dummy_time, /* pass_can_change_time */
1394 &dummy_time, /* pass_must_change_time */
1396 sam_pass->smb_name, /* user_name */
1397 sam_pass->full_name, /* full_name */
1398 sam_pass->home_dir, /* home_dir */
1399 sam_pass->dir_drive, /* dir_drive */
1400 sam_pass->logon_script, /* logon_script */
1401 sam_pass->profile_path, /* profile_path */
1402 sam_pass->acct_desc, /* description */
1403 sam_pass->workstations, /* workstations user can log in from */
1404 sam_pass->unknown_str, /* don't know, yet */
1405 sam_pass->munged_dial, /* dialin info. contains dialin path and tel no */
1407 sam_pass->user_rid, /* RID user_id */
1408 sam_pass->group_rid, /* RID group_id */
1409 sam_pass->acct_ctrl,
1411 sam_pass->unknown_3, /* unknown_3 */
1412 sam_pass->logon_divs, /* divisions per week */
1413 &hrs, /* logon hours */
1414 sam_pass->unknown_5,
1415 sam_pass->unknown_6);
1420 /*******************************************************************
1421 samr_reply_query_userinfo
1422 ********************************************************************/
1423 static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
1426 SAMR_R_QUERY_USERINFO r_u;
1428 SAM_USER_INFO_11 id11;
1430 SAM_USER_INFO_10 id10;
1431 SAM_USER_INFO_21 id21;
1434 uint32 status = 0x0;
1437 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1439 /* search for the handle */
1440 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1442 status = NT_STATUS_INVALID_HANDLE;
1445 /* find the user's rid */
1446 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1448 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1451 DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
1453 /* ok! user info levels (there are lots: see MSDEV help), off we go... */
1456 switch (q_u->switch_value)
1460 info = (void*)&id10;
1461 status = get_user_info_10(&id10, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1465 /* whoops - got this wrong. i think. or don't understand what's happening. */
1469 info = (void*)&id11;
1471 expire.low = 0xffffffff;
1472 expire.high = 0x7fffffff;
1474 make_sam_user_info11(&id11, &expire, "BROOKFIELDS$", 0x03ef, 0x201, 0x0080);
1481 info = (void*)&id21;
1482 status = get_user_info_21(&id21, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1488 status = NT_STATUS_INVALID_INFO_CLASS;
1495 init_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
1497 /* store the response in the SMB stream */
1498 samr_io_r_query_userinfo("", &r_u, rdata, 0);
1500 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1504 /*******************************************************************
1505 api_samr_query_userinfo
1506 ********************************************************************/
1507 static BOOL api_samr_query_userinfo(prs_struct *data, prs_struct *rdata)
1509 SAMR_Q_QUERY_USERINFO q_u;
1511 /* grab the samr unknown 24 */
1512 samr_io_q_query_userinfo("", &q_u, data, 0);
1514 /* construct reply. always indicate success */
1515 samr_reply_query_userinfo(&q_u, rdata);
1521 /*******************************************************************
1522 samr_reply_query_usergroups
1523 ********************************************************************/
1524 static void samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
1527 SAMR_R_QUERY_USERGROUPS r_u;
1528 uint32 status = 0x0;
1530 struct sam_passwd *sam_pass;
1531 DOM_GID *gids = NULL;
1535 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1537 /* find the policy handle. open a policy on it. */
1538 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1540 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1543 /* find the user's rid */
1544 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1546 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1552 sam_pass = getsam21pwrid(rid);
1553 unbecome_root(True);
1555 if (sam_pass == NULL)
1557 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1564 get_domain_user_groups(groups, sam_pass->smb_name);
1566 num_groups = make_dom_gids(groups, &gids);
1569 /* construct the response. lkclXXXX: gids are not copied! */
1570 init_samr_r_query_usergroups(&r_u, num_groups, gids, status);
1572 /* store the response in the SMB stream */
1573 samr_io_r_query_usergroups("", &r_u, rdata, 0);
1580 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1584 /*******************************************************************
1585 api_samr_query_usergroups
1586 ********************************************************************/
1587 static BOOL api_samr_query_usergroups(prs_struct *data, prs_struct *rdata)
1589 SAMR_Q_QUERY_USERGROUPS q_u;
1590 /* grab the samr unknown 32 */
1591 samr_io_q_query_usergroups("", &q_u, data, 0);
1593 /* construct reply. */
1594 samr_reply_query_usergroups(&q_u, rdata);
1600 /*******************************************************************
1601 samr_reply_query_dom_info
1602 ********************************************************************/
1603 static void samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
1606 SAMR_R_QUERY_DOMAIN_INFO r_u;
1608 uint16 switch_value = 0x0;
1609 uint32 status = 0x0;
1616 DEBUG(5,("samr_reply_query_dom_info: %d\n", __LINE__));
1618 /* find the policy handle. open a policy on it. */
1619 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
1621 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1622 DEBUG(5,("samr_reply_query_dom_info: invalid handle\n"));
1627 switch (q_u->switch_value)
1632 init_unk_info2(&ctr.info.inf2, global_myworkgroup, global_myname);
1638 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
1644 init_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
1646 /* store the response in the SMB stream */
1647 samr_io_r_query_dom_info("", &r_u, rdata, 0);
1649 DEBUG(5,("samr_query_dom_info: %d\n", __LINE__));
1653 /*******************************************************************
1654 api_samr_query_dom_info
1655 ********************************************************************/
1656 static BOOL api_samr_query_dom_info(prs_struct *data, prs_struct *rdata)
1658 SAMR_Q_QUERY_DOMAIN_INFO q_e;
1660 /* grab the samr unknown 8 command */
1661 samr_io_q_query_dom_info("", &q_e, data, 0);
1663 /* construct reply. */
1664 samr_reply_query_dom_info(&q_e, rdata);
1671 /*******************************************************************
1672 samr_reply_unknown_32
1673 ********************************************************************/
1674 static void samr_reply_unknown_32(SAMR_Q_UNKNOWN_32 *q_u,
1679 SAMR_R_UNKNOWN_32 r_u;
1681 /* set up the SAMR unknown_32 response */
1682 memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
1685 for (i = 4; i < POL_HND_SIZE; i++)
1687 r_u.pol.data[i] = i+1;
1691 init_dom_rid4(&(r_u.rid4), 0x0030, 0, 0);
1692 r_u.status = status;
1694 DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
1696 /* store the response in the SMB stream */
1697 samr_io_r_unknown_32("", &r_u, rdata, 0);
1699 DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
1703 /*******************************************************************
1705 ********************************************************************/
1706 static BOOL api_samr_unknown_32(prs_struct *data, prs_struct *rdata)
1709 struct sam_passwd *sam_pass;
1712 SAMR_Q_UNKNOWN_32 q_u;
1714 /* grab the samr unknown 32 */
1715 samr_io_q_unknown_32("", &q_u, data, 0);
1717 /* find the machine account: tell the caller if it exists.
1718 lkclXXXX i have *no* idea if this is a problem or not
1719 or even if you are supposed to construct a different
1720 reply if the account already exists...
1723 fstrcpy(mach_acct, dos_unistrn2(q_u.uni_mach_acct.buffer,
1724 q_u.uni_mach_acct.uni_str_len));
1727 sam_pass = getsam21pwnam(mach_acct);
1728 unbecome_root(True);
1730 if (sam_pass != NULL)
1732 /* machine account exists: say so */
1733 status = 0xC0000000 | NT_STATUS_USER_EXISTS;
1737 /* this could cause trouble... */
1738 DEBUG(0,("trouble!\n"));
1742 /* construct reply. */
1743 samr_reply_unknown_32(&q_u, rdata, status);
1749 /*******************************************************************
1750 samr_reply_connect_anon
1751 ********************************************************************/
1752 static void samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u,
1755 SAMR_R_CONNECT_ANON r_u;
1756 BOOL pol_open = False;
1758 /* set up the SAMR connect_anon response */
1761 /* get a (unique) handle. open a policy on it. */
1762 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1764 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1767 /* associate the domain SID with the (unique) handle. */
1768 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1770 /* oh, whoops. don't know what error message to return, here */
1771 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1774 if (r_u.status != 0 && pol_open)
1776 close_lsa_policy_hnd(&(r_u.connect_pol));
1779 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1781 /* store the response in the SMB stream */
1782 samr_io_r_connect_anon("", &r_u, rdata, 0);
1784 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1788 /*******************************************************************
1789 api_samr_connect_anon
1790 ********************************************************************/
1791 static BOOL api_samr_connect_anon(prs_struct *data, prs_struct *rdata)
1793 SAMR_Q_CONNECT_ANON q_u;
1795 /* grab the samr open policy */
1796 samr_io_q_connect_anon("", &q_u, data, 0);
1798 /* construct reply. always indicate success */
1799 samr_reply_connect_anon(&q_u, rdata);
1804 /*******************************************************************
1806 ********************************************************************/
1807 static void samr_reply_connect(SAMR_Q_CONNECT *q_u,
1811 BOOL pol_open = False;
1813 /* set up the SAMR connect response */
1816 /* get a (unique) handle. open a policy on it. */
1817 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1819 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1822 /* associate the domain SID with the (unique) handle. */
1823 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1825 /* oh, whoops. don't know what error message to return, here */
1826 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1829 if (r_u.status != 0 && pol_open)
1831 close_lsa_policy_hnd(&(r_u.connect_pol));
1834 DEBUG(5,("samr_connect: %d\n", __LINE__));
1836 /* store the response in the SMB stream */
1837 samr_io_r_connect("", &r_u, rdata, 0);
1839 DEBUG(5,("samr_connect: %d\n", __LINE__));
1843 /*******************************************************************
1845 ********************************************************************/
1846 static BOOL api_samr_connect(prs_struct *data, prs_struct *rdata)
1850 /* grab the samr open policy */
1851 samr_io_q_connect("", &q_u, data, 0);
1853 /* construct reply. always indicate success */
1854 samr_reply_connect(&q_u, rdata);
1859 /*******************************************************************
1860 samr_reply_open_alias
1861 ********************************************************************/
1862 static void samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
1865 SAMR_R_OPEN_ALIAS r_u;
1866 BOOL pol_open = False;
1868 /* set up the SAMR open_alias response */
1871 /* get a (unique) handle. open a policy on it. */
1872 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.pol))))
1874 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1877 /* associate a RID with the (unique) handle. */
1878 if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.pol), q_u->rid_alias))
1880 /* oh, whoops. don't know what error message to return, here */
1881 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1884 if (r_u.status != 0 && pol_open)
1886 close_lsa_policy_hnd(&(r_u.pol));
1889 DEBUG(5,("samr_open_alias: %d\n", __LINE__));
1891 /* store the response in the SMB stream */
1892 samr_io_r_open_alias("", &r_u, rdata, 0);
1894 DEBUG(5,("samr_open_alias: %d\n", __LINE__));
1898 /*******************************************************************
1900 ********************************************************************/
1901 static BOOL api_samr_open_alias(prs_struct *data, prs_struct *rdata)
1904 SAMR_Q_OPEN_ALIAS q_u;
1906 /* grab the samr open policy */
1907 samr_io_q_open_alias("", &q_u, data, 0);
1909 /* construct reply. always indicate success */
1910 samr_reply_open_alias(&q_u, rdata);
1915 /*******************************************************************
1916 array of \PIPE\samr operations
1917 ********************************************************************/
1918 static struct api_struct api_samr_cmds [] =
1920 { "SAMR_CLOSE_HND" , SAMR_CLOSE_HND , api_samr_close_hnd },
1921 { "SAMR_CONNECT" , SAMR_CONNECT , api_samr_connect },
1922 { "SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON , api_samr_connect_anon },
1923 { "SAMR_ENUM_DOM_USERS" , SAMR_ENUM_DOM_USERS , api_samr_enum_dom_users },
1924 { "SAMR_ENUM_DOM_GROUPS" , SAMR_ENUM_DOM_GROUPS , api_samr_enum_dom_groups },
1925 { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
1926 { "SAMR_LOOKUP_IDS" , SAMR_LOOKUP_IDS , api_samr_lookup_ids },
1927 { "SAMR_LOOKUP_NAMES" , SAMR_LOOKUP_NAMES , api_samr_lookup_names },
1928 { "SAMR_OPEN_USER" , SAMR_OPEN_USER , api_samr_open_user },
1929 { "SAMR_QUERY_USERINFO" , SAMR_QUERY_USERINFO , api_samr_query_userinfo },
1930 { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
1931 { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
1932 { "SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo },
1933 { "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo },
1934 { "SAMR_0x32" , 0x32 , api_samr_unknown_32 },
1935 { "SAMR_UNKNOWN_12" , SAMR_UNKNOWN_12 , api_samr_unknown_12 },
1936 { "SAMR_UNKNOWN_38" , SAMR_UNKNOWN_38 , api_samr_unknown_38 },
1937 { "SAMR_CHGPASSWD_USER" , SAMR_CHGPASSWD_USER , api_samr_chgpasswd_user },
1938 { "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias },
1939 { "SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain },
1940 { "SAMR_UNKNOWN_3" , SAMR_UNKNOWN_3 , api_samr_unknown_3 },
1941 { "SAMR_UNKNOWN_2C" , SAMR_UNKNOWN_2C , api_samr_unknown_2c },
1945 /*******************************************************************
1946 receives a samr pipe and responds.
1947 ********************************************************************/
1948 BOOL api_samr_rpc(pipes_struct *p, prs_struct *data)
1950 return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds, data);