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();
127 if (!*unix_user_name) return NULL;
128 if (!*mapfile) return NULL;
130 lines = file_lines_load(mapfile, NULL);
132 DEBUG(0,("unmap_unixname: can't open username map %s\n", mapfile));
136 DEBUG(5,("unmap_unixname: scanning username map %s, index: %d\n", mapfile, name_idx));
138 for (i=0; lines[i]; i++) {
140 char *dosname = strchr(unixname,'=');
147 while (isspace(*unixname))
149 if ('!' == *unixname) {
151 while (*unixname && isspace(*unixname))
155 if (!*unixname || strchr("#;",*unixname))
158 if (strncmp(unixname, unix_user_name, strlen(unix_user_name)))
161 /* We have matched the UNIX user name */
163 while(next_token(&dosname, tok, LIST_SEP, sizeof(tok))) {
164 if (!strchr("@&+", *tok)) {
173 DEBUG(0,("unmap_unixname: index too high - not that many DOS names\n"));
174 file_lines_free(lines);
177 file_lines_free(lines);
182 DEBUG(0,("unmap_unixname: Couldn't find the UNIX user name\n"));
183 file_lines_free(lines);
187 /*******************************************************************
188 This function sets up a list of users taken from the list of
189 users that UNIX knows about, as well as all the user names that
190 Samba maps to a valid UNIX user name. (This should work with
192 ********************************************************************/
194 static BOOL get_passwd_entries(SAM_USER_INFO_21 *pw_buf,
196 int *total_entries, int *num_entries,
200 static struct passwd *pwd = NULL;
201 static uint32 pw_rid;
202 static BOOL orig_done = False;
203 static int current_idx = 0;
204 static int mapped_idx = 0;
206 DEBUG(5, ("get_passwd_entries: retrieving a list of UNIX users\n"));
209 (*total_entries) = 0;
211 if (pw_buf == NULL) return False;
213 if (current_idx == 0) {
217 /* These two cases are inefficient, but should be called very rarely */
218 /* they are the cases where the starting index isn't picking up */
219 /* where we left off last time. It is efficient when it starts over */
220 /* at zero though. */
221 if (start_idx > current_idx) {
222 /* We aren't far enough; advance to start_idx */
223 while (current_idx < start_idx) {
227 if ((pwd = getpwent()) == NULL) break;
232 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
233 (current_idx < start_idx)) {
238 if (unmap_name == NULL) {
243 } else if (start_idx < current_idx) {
244 /* We are already too far; start over and advance to start_idx */
250 while (current_idx < start_idx) {
254 if ((pwd = getpwent()) == NULL) break;
259 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
260 (current_idx < start_idx)) {
265 if (unmap_name == NULL) {
272 /* now current_idx == start_idx */
273 while ((*num_entries) < max_num_entries) {
277 /* This does the original UNIX user itself */
279 if ((pwd = getpwent()) == NULL) break;
280 user_name_len = strlen(pwd->pw_name);
281 pw_rid = pdb_uid_to_user_rid(pwd->pw_uid);
282 init_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->pw_name, user_name_len);
283 init_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
284 pw_buf[(*num_entries)].user_rid = pw_rid;
285 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
287 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
289 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
297 /* This does all the user names that map to the UNIX user */
298 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
299 (*num_entries < max_num_entries)) {
300 user_name_len = strlen(unmap_name);
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 void 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 samr_io_r_close_hnd("", &r_u, rdata, 0);
359 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
363 /*******************************************************************
365 ********************************************************************/
366 static BOOL api_samr_close_hnd(prs_struct *data, prs_struct *rdata)
368 SAMR_Q_CLOSE_HND q_u;
370 /* grab the samr unknown 1 */
371 samr_io_q_close_hnd("", &q_u, data, 0);
373 /* construct reply. always indicate success */
374 samr_reply_close_hnd(&q_u, rdata);
380 /*******************************************************************
381 samr_reply_open_domain
382 ********************************************************************/
383 static void samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
386 SAMR_R_OPEN_DOMAIN r_u;
387 BOOL pol_open = False;
391 /* find the connection policy handle. */
392 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->connect_pol)) == -1))
394 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
397 /* get a (unique) handle. open a policy on it. */
398 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.domain_pol))))
400 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
403 /* associate the domain SID with the (unique) handle. */
404 if (r_u.status == 0x0 && !set_lsa_policy_samr_sid(&(r_u.domain_pol), &(q_u->dom_sid.sid)))
406 /* oh, whoops. don't know what error message to return, here */
407 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
410 if (r_u.status != 0 && pol_open)
412 close_lsa_policy_hnd(&(r_u.domain_pol));
415 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
417 /* store the response in the SMB stream */
418 samr_io_r_open_domain("", &r_u, rdata, 0);
420 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
424 /*******************************************************************
426 ********************************************************************/
427 static BOOL api_samr_open_domain(prs_struct *data, prs_struct *rdata)
429 SAMR_Q_OPEN_DOMAIN q_u;
431 /* grab the samr open */
432 samr_io_q_open_domain("", &q_u, data, 0);
434 /* construct reply. always indicate success */
435 samr_reply_open_domain(&q_u, rdata);
441 /*******************************************************************
442 samr_reply_unknown_2c
443 ********************************************************************/
444 static void samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u,
447 SAMR_R_UNKNOWN_2C r_u;
450 /* find the policy handle. open a policy on it. */
451 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
453 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
456 /* find the user's rid */
457 if ((status == 0x0) && (get_lsa_policy_samr_rid(&(q_u->user_pol)) == 0xffffffff))
459 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
462 init_samr_r_unknown_2c(&r_u, status);
464 DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
466 /* store the response in the SMB stream */
467 samr_io_r_unknown_2c("", &r_u, rdata, 0);
469 DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
473 /*******************************************************************
475 ********************************************************************/
476 static BOOL api_samr_unknown_2c(prs_struct *data, prs_struct *rdata)
478 SAMR_Q_UNKNOWN_2C q_u;
480 /* grab the samr open */
481 samr_io_q_unknown_2c("", &q_u, data, 0);
483 /* construct reply. always indicate success */
484 samr_reply_unknown_2c(&q_u, rdata);
490 /*******************************************************************
492 ********************************************************************/
493 static void samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
496 SAMR_R_UNKNOWN_3 r_u;
497 DOM_SID3 sid[MAX_SAM_SIDS];
503 /* find the policy handle. open a policy on it. */
504 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
506 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
509 /* find the user's rid */
510 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->user_pol))) == 0xffffffff)
512 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
518 DOM_SID everyone_sid;
520 user_sid = global_sam_sid;
522 SMB_ASSERT_ARRAY(user_sid.sub_auths, user_sid.num_auths+1);
527 user_sid.sub_auths[user_sid.num_auths++] = rid;
529 string_to_sid(&everyone_sid, "S-1-1");
531 /* maybe need another 1 or 2 (S-1-5-0x20-0x220 and S-1-5-20-0x224) */
532 /* these two are DOMAIN_ADMIN and DOMAIN_ACCT_OP group RIDs */
533 init_dom_sid3(&(sid[0]), 0x035b, 0x0002, &everyone_sid);
534 init_dom_sid3(&(sid[1]), 0x0044, 0x0002, &user_sid);
537 init_samr_r_unknown_3(&r_u,
539 0x00000014, 0x0002, 0x0070,
542 DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
544 /* store the response in the SMB stream */
545 samr_io_r_unknown_3("", &r_u, rdata, 0);
547 DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
551 /*******************************************************************
553 ********************************************************************/
554 static BOOL api_samr_unknown_3(prs_struct *data, prs_struct *rdata)
556 SAMR_Q_UNKNOWN_3 q_u;
558 /* grab the samr open */
559 samr_io_q_unknown_3("", &q_u, data, 0);
561 /* construct reply. always indicate success */
562 samr_reply_unknown_3(&q_u, rdata);
568 /*******************************************************************
569 samr_reply_enum_dom_users
570 ********************************************************************/
571 static void samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
574 SAMR_R_ENUM_DOM_USERS r_e;
575 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
580 r_e.total_num_entries = 0;
582 /* find the policy handle. open a policy on it. */
583 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
585 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
588 DEBUG(5,("samr_reply_enum_dom_users: %d\n", __LINE__));
591 get_sampwd_entries(pass, 0, &total_entries, &num_entries, MAX_SAM_ENTRIES, q_u->acb_mask);
594 init_samr_r_enum_dom_users(&r_e, total_entries,
595 q_u->unknown_0, num_entries,
598 /* store the response in the SMB stream */
599 samr_io_r_enum_dom_users("", &r_e, rdata, 0);
601 DEBUG(5,("samr_enum_dom_users: %d\n", __LINE__));
605 /*******************************************************************
606 api_samr_enum_dom_users
607 ********************************************************************/
608 static BOOL api_samr_enum_dom_users(prs_struct *data, prs_struct *rdata)
610 SAMR_Q_ENUM_DOM_USERS q_e;
612 /* grab the samr open */
613 samr_io_q_enum_dom_users("", &q_e, data, 0);
615 /* construct reply. */
616 samr_reply_enum_dom_users(&q_e, rdata);
622 /*******************************************************************
623 samr_reply_enum_dom_groups
624 ********************************************************************/
625 static void samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u,
628 SAMR_R_ENUM_DOM_GROUPS r_e;
629 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
632 char *dummy_group = "Domain Admins";
637 /* find the policy handle. open a policy on it. */
638 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
640 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
643 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
647 init_unistr2(&(pass[0].uni_user_name), dummy_group, strlen(dummy_group));
648 pass[0].user_rid = DOMAIN_GROUP_RID_ADMINS;
650 if (r_e.status == 0 && got_grps)
652 init_samr_r_enum_dom_groups(&r_e, q_u->start_idx, num_entries, pass, r_e.status);
655 /* store the response in the SMB stream */
656 samr_io_r_enum_dom_groups("", &r_e, rdata, 0);
658 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
662 /*******************************************************************
663 api_samr_enum_dom_groups
664 ********************************************************************/
665 static BOOL api_samr_enum_dom_groups(prs_struct *data, prs_struct *rdata)
667 SAMR_Q_ENUM_DOM_GROUPS q_e;
669 /* grab the samr open */
670 samr_io_q_enum_dom_groups("", &q_e, data, 0);
672 /* construct reply. */
673 samr_reply_enum_dom_groups(&q_e, rdata);
678 /*******************************************************************
679 samr_reply_enum_dom_aliases
680 ********************************************************************/
681 static void samr_reply_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_u,
684 SAMR_R_ENUM_DOM_ALIASES r_e;
685 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
695 /* find the policy handle. open a policy on it. */
696 if (r_e.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &sid))
698 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
701 sid_to_string(sid_str, &sid);
702 sid_to_string(sam_sid_str, &global_sam_sid);
704 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
706 /* well-known aliases */
707 if (strequal(sid_str, "S-1-5-32"))
710 while (num_entries < MAX_SAM_ENTRIES && ((name = builtin_alias_rids[num_entries].name) != NULL))
712 init_unistr2(&(pass[num_entries].uni_user_name), name, strlen(name));
713 pass[num_entries].user_rid = builtin_alias_rids[num_entries].rid;
717 else if (strequal(sid_str, sam_sid_str))
721 /* we return the UNIX groups here. This seems to be the right */
722 /* thing to do, since NT member servers return their local */
723 /* groups in the same situation. */
726 while (num_entries < MAX_SAM_ENTRIES && ((grp = getgrent()) != NULL))
729 init_unistr2(&(pass[num_entries].uni_user_name), name, strlen(name));
730 pass[num_entries].user_rid = pdb_gid_to_group_rid(grp->gr_gid);
737 init_samr_r_enum_dom_aliases(&r_e, num_entries, pass, r_e.status);
739 /* store the response in the SMB stream */
740 samr_io_r_enum_dom_aliases("", &r_e, rdata, 0);
742 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
746 /*******************************************************************
747 api_samr_enum_dom_aliases
748 ********************************************************************/
749 static BOOL api_samr_enum_dom_aliases(prs_struct *data, prs_struct *rdata)
751 SAMR_Q_ENUM_DOM_ALIASES q_e;
753 /* grab the samr open */
754 samr_io_q_enum_dom_aliases("", &q_e, data, 0);
756 /* construct reply. */
757 samr_reply_enum_dom_aliases(&q_e, rdata);
763 /*******************************************************************
764 samr_reply_query_dispinfo
765 ********************************************************************/
766 static void samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u,
769 SAMR_R_QUERY_DISPINFO r_e;
773 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
775 int total_entries = 0;
777 uint16 switch_level = 0x0;
783 DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
785 /* find the policy handle. open a policy on it. */
786 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
788 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
789 DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n"));
792 if (r_e.status == 0x0)
795 got_pwds = get_passwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, MAX_SAM_ENTRIES, 0);
798 switch (q_u->switch_level)
803 /* query disp info is for users */
805 init_sam_info_1(&info1, ACB_NORMAL,
806 q_u->start_idx, num_entries, pass);
808 ctr.sam.info1 = &info1;
814 /* query disp info is for servers */
816 init_sam_info_2(&info2, ACB_WSTRUST,
817 q_u->start_idx, num_entries, pass);
819 ctr.sam.info2 = &info2;
828 init_samr_r_query_dispinfo(&r_e, switch_level, &ctr, r_e.status);
831 /* store the response in the SMB stream */
832 samr_io_r_query_dispinfo("", &r_e, rdata, 0);
834 DEBUG(5,("samr_query_dispinfo: %d\n", __LINE__));
838 /*******************************************************************
839 api_samr_query_dispinfo
840 ********************************************************************/
841 static BOOL api_samr_query_dispinfo(prs_struct *data, prs_struct *rdata)
843 SAMR_Q_QUERY_DISPINFO q_e;
845 /* grab the samr open */
846 samr_io_q_query_dispinfo("", &q_e, data, 0);
848 /* construct reply. */
849 samr_reply_query_dispinfo(&q_e, rdata);
855 /*******************************************************************
856 samr_reply_query_aliasinfo
857 ********************************************************************/
858 static void samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
861 SAMR_R_QUERY_ALIASINFO r_e;
866 /* find the policy handle. open a policy on it. */
867 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
869 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
872 DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__));
874 if (r_e.status == 0x0)
876 if (q_u->switch_level != 3)
878 r_e.status = NT_STATUS_INVALID_INFO_CLASS;
882 init_samr_r_query_aliasinfo(&r_e, q_u->switch_level,
886 /* store the response in the SMB stream */
887 samr_io_r_query_aliasinfo("", &r_e, rdata, 0);
889 DEBUG(5,("samr_query_aliasinfo: %d\n", __LINE__));
893 /*******************************************************************
894 api_samr_query_aliasinfo
895 ********************************************************************/
896 static BOOL api_samr_query_aliasinfo(prs_struct *data, prs_struct *rdata)
898 SAMR_Q_QUERY_ALIASINFO q_e;
900 /* grab the samr open */
901 samr_io_q_query_aliasinfo("", &q_e, data, 0);
903 /* construct reply. */
904 samr_reply_query_aliasinfo(&q_e, rdata);
910 /*******************************************************************
911 samr_reply_lookup_ids
912 ********************************************************************/
913 static void samr_reply_lookup_ids(SAMR_Q_LOOKUP_IDS *q_u,
916 uint32 rid[MAX_SAM_ENTRIES];
918 int num_rids = q_u->num_sids1;
920 SAMR_R_LOOKUP_IDS r_u;
922 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
924 if (num_rids > MAX_SAM_ENTRIES)
926 num_rids = MAX_SAM_ENTRIES;
927 DEBUG(5,("samr_lookup_ids: truncating entries to %d\n", num_rids));
932 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
934 for (i = 0; i < num_rids && status == 0; i++)
936 struct sam_passwd *sam_pass;
940 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
941 q_u->uni_user_name[i].uni_str_len));
943 /* find the user account */
945 sam_pass = get_smb21pwd_entry(user_name, 0);
948 if (sam_pass == NULL)
950 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
955 rid[i] = sam_pass->user_rid;
961 rid[0] = BUILTIN_ALIAS_RID_USERS;
963 init_samr_r_lookup_ids(&r_u, num_rids, rid, status);
965 /* store the response in the SMB stream */
966 samr_io_r_lookup_ids("", &r_u, rdata, 0);
968 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
972 /*******************************************************************
974 ********************************************************************/
975 static BOOL api_samr_lookup_ids(prs_struct *data, prs_struct *rdata)
977 SAMR_Q_LOOKUP_IDS q_u;
979 /* grab the samr 0x10 */
980 samr_io_q_lookup_ids("", &q_u, data, 0);
982 /* construct reply. always indicate success */
983 samr_reply_lookup_ids(&q_u, rdata);
988 /*******************************************************************
989 samr_reply_lookup_names
990 ********************************************************************/
992 static BOOL samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
995 uint32 rid[MAX_SAM_ENTRIES];
996 uint8 type[MAX_SAM_ENTRIES];
999 int num_rids = q_u->num_names1;
1002 SAMR_R_LOOKUP_NAMES r_u;
1004 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1009 if (!get_lsa_policy_samr_sid(&q_u->pol, &pol_sid)) {
1010 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
1011 init_samr_r_lookup_names(&r_u, 0, rid, type, status);
1012 if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
1013 DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
1019 if (num_rids > MAX_SAM_ENTRIES) {
1020 num_rids = MAX_SAM_ENTRIES;
1021 DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
1024 SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
1026 for (i = 0; i < num_rids; i++) {
1029 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
1031 rid [i] = 0xffffffff;
1032 type[i] = SID_NAME_UNKNOWN;
1034 fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer,
1035 q_u->uni_name[i].uni_str_len));
1037 if(sid_equal(&pol_sid, &global_sam_sid)) {
1040 if(lookup_local_name(global_myname, name, &sid, &type[i])) {
1041 sid_split_rid( &sid, &rid[i]);
1047 init_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
1049 /* store the response in the SMB stream */
1050 if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
1051 DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
1055 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1060 /*******************************************************************
1061 api_samr_lookup_names
1062 ********************************************************************/
1064 static BOOL api_samr_lookup_names(prs_struct *data, prs_struct *rdata)
1066 SAMR_Q_LOOKUP_NAMES q_u;
1068 memset(&q_u, '\0', sizeof(q_u));
1070 /* grab the samr lookup names */
1071 if(!samr_io_q_lookup_names("", &q_u, data, 0)) {
1072 DEBUG(0,("api_samr_lookup_names: failed to unmarshall SAMR_Q_LOOKUP_NAMES.\n"));
1076 /* construct reply. always indicate success */
1077 if(!samr_reply_lookup_names(&q_u, rdata))
1083 /*******************************************************************
1084 samr_reply_chgpasswd_user
1085 ********************************************************************/
1087 static BOOL samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
1090 SAMR_R_CHGPASSWD_USER r_u;
1091 uint32 status = 0x0;
1095 fstrcpy(user_name, dos_unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len));
1096 fstrcpy(wks , dos_unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len));
1098 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1100 if (!pass_oem_change(user_name,
1101 q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1102 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1104 status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
1107 init_samr_r_chgpasswd_user(&r_u, status);
1109 /* store the response in the SMB stream */
1110 if(!samr_io_r_chgpasswd_user("", &r_u, rdata, 0)) {
1111 DEBUG(0,("samr_reply_chgpasswd_user: Failed to marshall SAMR_R_CHGPASSWD_USER struct.\n" ));
1115 DEBUG(5,("samr_chgpasswd_user: %d\n", __LINE__));
1119 /*******************************************************************
1120 api_samr_chgpasswd_user
1121 ********************************************************************/
1123 static BOOL api_samr_chgpasswd_user(prs_struct *data, prs_struct *rdata)
1125 SAMR_Q_CHGPASSWD_USER q_u;
1127 /* unknown 38 command */
1128 if (!samr_io_q_chgpasswd_user("", &q_u, data, 0)) {
1129 DEBUG(0,("api_samr_chgpasswd_user: samr_io_q_chgpasswd_user failed to parse RPC packet.\n"));
1133 /* construct reply. */
1134 if(!samr_reply_chgpasswd_user(&q_u, rdata)) {
1135 DEBUG(0,("api_samr_chgpasswd_user: samr_reply_chgpasswd_user failed to create reply packet.\n"));
1143 /*******************************************************************
1144 samr_reply_unknown_38
1145 ********************************************************************/
1146 static void samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u,
1149 SAMR_R_UNKNOWN_38 r_u;
1151 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1153 init_samr_r_unknown_38(&r_u);
1155 /* store the response in the SMB stream */
1156 samr_io_r_unknown_38("", &r_u, rdata, 0);
1158 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1161 /*******************************************************************
1163 ********************************************************************/
1164 static BOOL api_samr_unknown_38(prs_struct *data, prs_struct *rdata)
1166 SAMR_Q_UNKNOWN_38 q_u;
1168 /* unknown 38 command */
1169 samr_io_q_unknown_38("", &q_u, data, 0);
1171 /* construct reply. always indicate success */
1172 samr_reply_unknown_38(&q_u, rdata);
1178 /*******************************************************************
1179 samr_reply_unknown_12
1180 ********************************************************************/
1181 static void samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
1184 fstring group_names[MAX_SAM_ENTRIES];
1185 uint32 group_attrs[MAX_SAM_ENTRIES];
1187 int num_gids = q_u->num_gids1;
1189 SAMR_R_UNKNOWN_12 r_u;
1191 DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
1193 /* find the policy handle. open a policy on it. */
1194 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1196 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1202 if (num_gids > MAX_SAM_ENTRIES)
1204 num_gids = MAX_SAM_ENTRIES;
1205 DEBUG(5,("samr_unknown_12: truncating entries to %d\n", num_gids));
1208 for (i = 0; i < num_gids && status == 0; i++)
1210 fstrcpy(group_names[i], "dummy group");
1211 group_attrs[i] = 0x2;
1215 init_samr_r_unknown_12(&r_u, num_gids, group_names, group_attrs, status);
1217 /* store the response in the SMB stream */
1218 samr_io_r_unknown_12("", &r_u, rdata, 0);
1220 DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
1224 /*******************************************************************
1226 ********************************************************************/
1227 static BOOL api_samr_unknown_12(prs_struct *data, prs_struct *rdata)
1229 SAMR_Q_UNKNOWN_12 q_u;
1231 /* grab the samr lookup names */
1232 samr_io_q_unknown_12("", &q_u, data, 0);
1234 /* construct reply. always indicate success */
1235 samr_reply_unknown_12(&q_u, rdata);
1241 /*******************************************************************
1242 samr_reply_open_user
1243 ********************************************************************/
1244 static void samr_reply_open_user(SAMR_Q_OPEN_USER *q_u,
1248 SAMR_R_OPEN_USER r_u;
1249 struct sam_passwd *sam_pass;
1250 BOOL pol_open = False;
1252 /* set up the SAMR open_user response */
1253 memset((char *)r_u.user_pol.data, '\0', POL_HND_SIZE);
1257 /* find the policy handle. open a policy on it. */
1258 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
1260 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1263 /* get a (unique) handle. open a policy on it. */
1264 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.user_pol))))
1266 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1270 sam_pass = getsam21pwrid(q_u->user_rid);
1271 unbecome_root(True);
1273 /* check that the RID exists in our domain. */
1274 if (r_u.status == 0x0 && sam_pass == NULL)
1276 r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1279 /* associate the RID with the (unique) handle. */
1280 if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.user_pol), q_u->user_rid))
1282 /* oh, whoops. don't know what error message to return, here */
1283 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1286 if (r_u.status != 0 && pol_open)
1288 close_lsa_policy_hnd(&(r_u.user_pol));
1291 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1293 /* store the response in the SMB stream */
1294 samr_io_r_open_user("", &r_u, rdata, 0);
1296 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1300 /*******************************************************************
1302 ********************************************************************/
1303 static BOOL api_samr_open_user(prs_struct *data, prs_struct *rdata)
1305 SAMR_Q_OPEN_USER q_u;
1307 /* grab the samr unknown 22 */
1308 samr_io_q_open_user("", &q_u, data, 0);
1310 /* construct reply. always indicate success */
1311 samr_reply_open_user(&q_u, rdata, 0x0);
1317 /*************************************************************************
1319 *************************************************************************/
1320 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1322 struct smb_passwd *smb_pass;
1324 if (!pdb_rid_is_user(user_rid))
1326 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1331 smb_pass = getsmbpwrid(user_rid);
1332 unbecome_root(True);
1334 if (smb_pass == NULL)
1336 DEBUG(4,("User 0x%x not found\n", user_rid));
1340 DEBUG(3,("User:[%s]\n", smb_pass->smb_name));
1342 init_sam_user_info10(id10, smb_pass->acct_ctrl);
1347 /*************************************************************************
1349 *************************************************************************/
1350 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1353 struct sam_passwd *sam_pass;
1357 if (!pdb_rid_is_user(user_rid))
1359 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1364 sam_pass = getsam21pwrid(user_rid);
1365 unbecome_root(True);
1367 if (sam_pass == NULL)
1369 DEBUG(4,("User 0x%x not found\n", user_rid));
1373 DEBUG(3,("User:[%s]\n", sam_pass->smb_name));
1375 dummy_time.low = 0xffffffff;
1376 dummy_time.high = 0x7fffffff;
1378 DEBUG(5,("get_user_info_21 - TODO: convert unix times to NTTIMEs\n"));
1380 /* create a LOGON_HRS structure */
1381 hrs.len = sam_pass->hours_len;
1382 SMB_ASSERT_ARRAY(hrs.hours, hrs.len);
1383 for (i = 0; i < hrs.len; i++)
1385 hrs.hours[i] = sam_pass->hours[i];
1388 init_sam_user_info21(id21,
1390 &dummy_time, /* logon_time */
1391 &dummy_time, /* logoff_time */
1392 &dummy_time, /* kickoff_time */
1393 &dummy_time, /* pass_last_set_time */
1394 &dummy_time, /* pass_can_change_time */
1395 &dummy_time, /* pass_must_change_time */
1397 sam_pass->smb_name, /* user_name */
1398 sam_pass->full_name, /* full_name */
1399 sam_pass->home_dir, /* home_dir */
1400 sam_pass->dir_drive, /* dir_drive */
1401 sam_pass->logon_script, /* logon_script */
1402 sam_pass->profile_path, /* profile_path */
1403 sam_pass->acct_desc, /* description */
1404 sam_pass->workstations, /* workstations user can log in from */
1405 sam_pass->unknown_str, /* don't know, yet */
1406 sam_pass->munged_dial, /* dialin info. contains dialin path and tel no */
1408 sam_pass->user_rid, /* RID user_id */
1409 sam_pass->group_rid, /* RID group_id */
1410 sam_pass->acct_ctrl,
1412 sam_pass->unknown_3, /* unknown_3 */
1413 sam_pass->logon_divs, /* divisions per week */
1414 &hrs, /* logon hours */
1415 sam_pass->unknown_5,
1416 sam_pass->unknown_6);
1421 /*******************************************************************
1422 samr_reply_query_userinfo
1423 ********************************************************************/
1424 static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
1427 SAMR_R_QUERY_USERINFO r_u;
1429 SAM_USER_INFO_11 id11;
1431 SAM_USER_INFO_10 id10;
1432 SAM_USER_INFO_21 id21;
1435 uint32 status = 0x0;
1438 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1440 /* search for the handle */
1441 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1443 status = NT_STATUS_INVALID_HANDLE;
1446 /* find the user's rid */
1447 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1449 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1452 DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
1454 /* ok! user info levels (there are lots: see MSDEV help), off we go... */
1457 switch (q_u->switch_value)
1461 info = (void*)&id10;
1462 status = get_user_info_10(&id10, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1466 /* whoops - got this wrong. i think. or don't understand what's happening. */
1470 info = (void*)&id11;
1472 expire.low = 0xffffffff;
1473 expire.high = 0x7fffffff;
1475 make_sam_user_info11(&id11, &expire, "BROOKFIELDS$", 0x03ef, 0x201, 0x0080);
1482 info = (void*)&id21;
1483 status = get_user_info_21(&id21, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1489 status = NT_STATUS_INVALID_INFO_CLASS;
1496 init_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
1498 /* store the response in the SMB stream */
1499 samr_io_r_query_userinfo("", &r_u, rdata, 0);
1501 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1505 /*******************************************************************
1506 api_samr_query_userinfo
1507 ********************************************************************/
1508 static BOOL api_samr_query_userinfo(prs_struct *data, prs_struct *rdata)
1510 SAMR_Q_QUERY_USERINFO q_u;
1512 /* grab the samr unknown 24 */
1513 samr_io_q_query_userinfo("", &q_u, data, 0);
1515 /* construct reply. always indicate success */
1516 samr_reply_query_userinfo(&q_u, rdata);
1522 /*******************************************************************
1523 samr_reply_query_usergroups
1524 ********************************************************************/
1525 static void samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
1528 SAMR_R_QUERY_USERGROUPS r_u;
1529 uint32 status = 0x0;
1531 struct sam_passwd *sam_pass;
1532 DOM_GID *gids = NULL;
1536 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1538 /* find the policy handle. open a policy on it. */
1539 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1541 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1544 /* find the user's rid */
1545 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1547 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1553 sam_pass = getsam21pwrid(rid);
1554 unbecome_root(True);
1556 if (sam_pass == NULL)
1558 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1565 get_domain_user_groups(groups, sam_pass->smb_name);
1567 num_groups = make_dom_gids(groups, &gids);
1570 /* construct the response. lkclXXXX: gids are not copied! */
1571 init_samr_r_query_usergroups(&r_u, num_groups, gids, status);
1573 /* store the response in the SMB stream */
1574 samr_io_r_query_usergroups("", &r_u, rdata, 0);
1581 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1585 /*******************************************************************
1586 api_samr_query_usergroups
1587 ********************************************************************/
1588 static BOOL api_samr_query_usergroups(prs_struct *data, prs_struct *rdata)
1590 SAMR_Q_QUERY_USERGROUPS q_u;
1591 /* grab the samr unknown 32 */
1592 samr_io_q_query_usergroups("", &q_u, data, 0);
1594 /* construct reply. */
1595 samr_reply_query_usergroups(&q_u, rdata);
1601 /*******************************************************************
1602 samr_reply_query_dom_info
1603 ********************************************************************/
1604 static void samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
1607 SAMR_R_QUERY_DOMAIN_INFO r_u;
1609 uint16 switch_value = 0x0;
1610 uint32 status = 0x0;
1617 DEBUG(5,("samr_reply_query_dom_info: %d\n", __LINE__));
1619 /* find the policy handle. open a policy on it. */
1620 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
1622 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1623 DEBUG(5,("samr_reply_query_dom_info: invalid handle\n"));
1628 switch (q_u->switch_value)
1633 init_unk_info2(&ctr.info.inf2, global_myworkgroup, global_myname);
1639 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
1645 init_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
1647 /* store the response in the SMB stream */
1648 samr_io_r_query_dom_info("", &r_u, rdata, 0);
1650 DEBUG(5,("samr_query_dom_info: %d\n", __LINE__));
1654 /*******************************************************************
1655 api_samr_query_dom_info
1656 ********************************************************************/
1657 static BOOL api_samr_query_dom_info(prs_struct *data, prs_struct *rdata)
1659 SAMR_Q_QUERY_DOMAIN_INFO q_e;
1661 /* grab the samr unknown 8 command */
1662 samr_io_q_query_dom_info("", &q_e, data, 0);
1664 /* construct reply. */
1665 samr_reply_query_dom_info(&q_e, rdata);
1672 /*******************************************************************
1673 samr_reply_unknown_32
1674 ********************************************************************/
1675 static void samr_reply_unknown_32(SAMR_Q_UNKNOWN_32 *q_u,
1680 SAMR_R_UNKNOWN_32 r_u;
1682 /* set up the SAMR unknown_32 response */
1683 memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
1686 for (i = 4; i < POL_HND_SIZE; i++)
1688 r_u.pol.data[i] = i+1;
1692 init_dom_rid4(&(r_u.rid4), 0x0030, 0, 0);
1693 r_u.status = status;
1695 DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
1697 /* store the response in the SMB stream */
1698 samr_io_r_unknown_32("", &r_u, rdata, 0);
1700 DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
1704 /*******************************************************************
1706 ********************************************************************/
1707 static BOOL api_samr_unknown_32(prs_struct *data, prs_struct *rdata)
1710 struct sam_passwd *sam_pass;
1713 SAMR_Q_UNKNOWN_32 q_u;
1715 /* grab the samr unknown 32 */
1716 samr_io_q_unknown_32("", &q_u, data, 0);
1718 /* find the machine account: tell the caller if it exists.
1719 lkclXXXX i have *no* idea if this is a problem or not
1720 or even if you are supposed to construct a different
1721 reply if the account already exists...
1724 fstrcpy(mach_acct, dos_unistrn2(q_u.uni_mach_acct.buffer,
1725 q_u.uni_mach_acct.uni_str_len));
1728 sam_pass = getsam21pwnam(mach_acct);
1729 unbecome_root(True);
1731 if (sam_pass != NULL)
1733 /* machine account exists: say so */
1734 status = 0xC0000000 | NT_STATUS_USER_EXISTS;
1738 /* this could cause trouble... */
1739 DEBUG(0,("trouble!\n"));
1743 /* construct reply. */
1744 samr_reply_unknown_32(&q_u, rdata, status);
1750 /*******************************************************************
1751 samr_reply_connect_anon
1752 ********************************************************************/
1753 static void samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u,
1756 SAMR_R_CONNECT_ANON r_u;
1757 BOOL pol_open = False;
1759 /* set up the SAMR connect_anon response */
1762 /* get a (unique) handle. open a policy on it. */
1763 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1765 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1768 /* associate the domain SID with the (unique) handle. */
1769 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1771 /* oh, whoops. don't know what error message to return, here */
1772 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1775 if (r_u.status != 0 && pol_open)
1777 close_lsa_policy_hnd(&(r_u.connect_pol));
1780 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1782 /* store the response in the SMB stream */
1783 samr_io_r_connect_anon("", &r_u, rdata, 0);
1785 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1789 /*******************************************************************
1790 api_samr_connect_anon
1791 ********************************************************************/
1792 static BOOL api_samr_connect_anon(prs_struct *data, prs_struct *rdata)
1794 SAMR_Q_CONNECT_ANON q_u;
1796 /* grab the samr open policy */
1797 samr_io_q_connect_anon("", &q_u, data, 0);
1799 /* construct reply. always indicate success */
1800 samr_reply_connect_anon(&q_u, rdata);
1805 /*******************************************************************
1807 ********************************************************************/
1808 static void samr_reply_connect(SAMR_Q_CONNECT *q_u,
1812 BOOL pol_open = False;
1814 /* set up the SAMR connect response */
1817 /* get a (unique) handle. open a policy on it. */
1818 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1820 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1823 /* associate the domain SID with the (unique) handle. */
1824 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1826 /* oh, whoops. don't know what error message to return, here */
1827 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1830 if (r_u.status != 0 && pol_open)
1832 close_lsa_policy_hnd(&(r_u.connect_pol));
1835 DEBUG(5,("samr_connect: %d\n", __LINE__));
1837 /* store the response in the SMB stream */
1838 samr_io_r_connect("", &r_u, rdata, 0);
1840 DEBUG(5,("samr_connect: %d\n", __LINE__));
1844 /*******************************************************************
1846 ********************************************************************/
1847 static BOOL api_samr_connect(prs_struct *data, prs_struct *rdata)
1851 /* grab the samr open policy */
1852 samr_io_q_connect("", &q_u, data, 0);
1854 /* construct reply. always indicate success */
1855 samr_reply_connect(&q_u, rdata);
1860 /*******************************************************************
1861 samr_reply_open_alias
1862 ********************************************************************/
1863 static void samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
1866 SAMR_R_OPEN_ALIAS r_u;
1867 BOOL pol_open = False;
1869 /* set up the SAMR open_alias response */
1872 /* get a (unique) handle. open a policy on it. */
1873 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.pol))))
1875 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1878 /* associate a RID with the (unique) handle. */
1879 if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.pol), q_u->rid_alias))
1881 /* oh, whoops. don't know what error message to return, here */
1882 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1885 if (r_u.status != 0 && pol_open)
1887 close_lsa_policy_hnd(&(r_u.pol));
1890 DEBUG(5,("samr_open_alias: %d\n", __LINE__));
1892 /* store the response in the SMB stream */
1893 samr_io_r_open_alias("", &r_u, rdata, 0);
1895 DEBUG(5,("samr_open_alias: %d\n", __LINE__));
1899 /*******************************************************************
1901 ********************************************************************/
1902 static BOOL api_samr_open_alias(prs_struct *data, prs_struct *rdata)
1905 SAMR_Q_OPEN_ALIAS q_u;
1907 /* grab the samr open policy */
1908 samr_io_q_open_alias("", &q_u, data, 0);
1910 /* construct reply. always indicate success */
1911 samr_reply_open_alias(&q_u, rdata);
1916 /*******************************************************************
1917 array of \PIPE\samr operations
1918 ********************************************************************/
1919 static struct api_struct api_samr_cmds [] =
1921 { "SAMR_CLOSE_HND" , SAMR_CLOSE_HND , api_samr_close_hnd },
1922 { "SAMR_CONNECT" , SAMR_CONNECT , api_samr_connect },
1923 { "SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON , api_samr_connect_anon },
1924 { "SAMR_ENUM_DOM_USERS" , SAMR_ENUM_DOM_USERS , api_samr_enum_dom_users },
1925 { "SAMR_ENUM_DOM_GROUPS" , SAMR_ENUM_DOM_GROUPS , api_samr_enum_dom_groups },
1926 { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
1927 { "SAMR_LOOKUP_IDS" , SAMR_LOOKUP_IDS , api_samr_lookup_ids },
1928 { "SAMR_LOOKUP_NAMES" , SAMR_LOOKUP_NAMES , api_samr_lookup_names },
1929 { "SAMR_OPEN_USER" , SAMR_OPEN_USER , api_samr_open_user },
1930 { "SAMR_QUERY_USERINFO" , SAMR_QUERY_USERINFO , api_samr_query_userinfo },
1931 { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
1932 { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
1933 { "SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo },
1934 { "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo },
1935 { "SAMR_0x32" , 0x32 , api_samr_unknown_32 },
1936 { "SAMR_UNKNOWN_12" , SAMR_UNKNOWN_12 , api_samr_unknown_12 },
1937 { "SAMR_UNKNOWN_38" , SAMR_UNKNOWN_38 , api_samr_unknown_38 },
1938 { "SAMR_CHGPASSWD_USER" , SAMR_CHGPASSWD_USER , api_samr_chgpasswd_user },
1939 { "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias },
1940 { "SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain },
1941 { "SAMR_UNKNOWN_3" , SAMR_UNKNOWN_3 , api_samr_unknown_3 },
1942 { "SAMR_UNKNOWN_2C" , SAMR_UNKNOWN_2C , api_samr_unknown_2c },
1946 /*******************************************************************
1947 receives a samr pipe and responds.
1948 ********************************************************************/
1949 BOOL api_samr_rpc(pipes_struct *p, prs_struct *data)
1951 return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds, data);