3 * Unix SMB/Netbios implementation.
5 * RPC Pipe client / server routines
6 * Copyright (C) Andrew Tridgell 1992-1997,
7 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
8 * Copyright (C) Paul Ashton 1997.
9 * Copyright (C) Hewlett-Packard Company 1999.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 extern int DEBUGLEVEL;
32 extern fstring global_myworkgroup;
33 extern pstring global_myname;
34 extern DOM_SID global_sam_sid;
36 extern rid_name domain_group_rids[];
37 extern rid_name domain_alias_rids[];
38 extern rid_name builtin_alias_rids[];
40 /*******************************************************************
41 This next function should be replaced with something that
42 dynamically returns the correct user info..... JRA.
43 ********************************************************************/
45 static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf,
47 int *total_entries, int *num_entries,
52 struct sam_passwd *pwd = NULL;
57 if (pw_buf == NULL) return False;
59 vp = startsmbpwent(False);
61 DEBUG(0, ("get_sampwd_entries: Unable to open SMB password database.\n"));
65 while (((pwd = getsam21pwent(vp)) != NULL) && (*num_entries) < max_num_entries) {
69 /* skip the requested number of entries.
70 not very efficient, but hey...
76 user_name_len = strlen(pwd->smb_name);
77 init_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->smb_name, user_name_len);
78 init_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
79 pw_buf[(*num_entries)].user_rid = pwd->user_rid;
80 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
82 /* Now check if the NT compatible password is available. */
83 if (pwd->smb_nt_passwd != NULL) {
84 memcpy( pw_buf[(*num_entries)].nt_pwd , pwd->smb_nt_passwd, 16);
87 pw_buf[(*num_entries)].acb_info = (uint16)pwd->acct_ctrl;
89 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
90 (*num_entries), pwd->smb_name,
91 pwd->user_rid, pwd->acct_ctrl));
93 if (acb_mask == 0 || IS_BITS_SET_SOME(pwd->acct_ctrl, acb_mask)) {
94 DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
97 DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
105 return (*num_entries) > 0;
108 /*******************************************************************
109 This function uses the username map file and tries to map a UNIX
110 user name to an DOS name. (Sort of the reverse of the
111 map_username() function.) Since more than one DOS name can map
112 to the UNIX name, to reverse the mapping you have to specify
113 which corresponding DOS name you want; that's where the name_idx
114 parameter comes in. Returns the string requested or NULL if it
115 fails or can't complete the request for any reason. This doesn't
116 handle group names (starting with '@') or names starting with
117 '+' or '&'. If they are encountered, they are skipped.
118 ********************************************************************/
120 static char *unmap_unixname(char *unix_user_name, int name_idx)
123 char *mapfile = lp_username_map();
128 if (!*unix_user_name) return NULL;
129 if (!*mapfile) return NULL;
131 f = sys_fopen(mapfile,"r");
133 DEBUG(0,("unmap_unixname: can't open username map %s\n", mapfile));
137 DEBUG(5,("unmap_unixname: scanning username map %s, index: %d\n", mapfile, name_idx));
139 while((s=fgets_slash(buf,sizeof(buf),f))!=NULL) {
141 char *dosname = strchr(unixname,'=');
148 while (isspace(*unixname))
150 if ('!' == *unixname) {
152 while (*unixname && isspace(*unixname))
156 if (!*unixname || strchr("#;",*unixname))
159 if (strncmp(unixname, unix_user_name, strlen(unix_user_name)))
162 /* We have matched the UNIX user name */
164 while(next_token(&dosname, tok, LIST_SEP, sizeof(tok))) {
165 if (!strchr("@&+", *tok)) {
174 DEBUG(0,("unmap_unixname: index too high - not that many DOS names\n"));
183 DEBUG(0,("unmap_unixname: Couldn't find the UNIX user name\n"));
188 /*******************************************************************
189 This function sets up a list of users taken from the list of
190 users that UNIX knows about, as well as all the user names that
191 Samba maps to a valid UNIX user name. (This should work with
193 ********************************************************************/
195 static BOOL get_passwd_entries(SAM_USER_INFO_21 *pw_buf,
197 int *total_entries, int *num_entries,
201 static struct passwd *pwd = NULL;
202 static uint32 pw_rid;
203 static BOOL orig_done = False;
204 static int current_idx = 0;
205 static int mapped_idx = 0;
207 DEBUG(5, ("get_passwd_entries: retrieving a list of UNIX users\n"));
210 (*total_entries) = 0;
212 if (pw_buf == NULL) return False;
214 if (current_idx == 0) {
218 /* These two cases are inefficient, but should be called very rarely */
219 /* they are the cases where the starting index isn't picking up */
220 /* where we left off last time. It is efficient when it starts over */
221 /* at zero though. */
222 if (start_idx > current_idx) {
223 /* We aren't far enough; advance to start_idx */
224 while (current_idx < start_idx) {
228 if ((pwd = getpwent()) == NULL) break;
233 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
234 (current_idx < start_idx)) {
239 if (unmap_name == NULL) {
244 } else if (start_idx < current_idx) {
245 /* We are already too far; start over and advance to start_idx */
251 while (current_idx < start_idx) {
255 if ((pwd = getpwent()) == NULL) break;
260 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
261 (current_idx < start_idx)) {
266 if (unmap_name == NULL) {
273 /* now current_idx == start_idx */
274 while ((*num_entries) < max_num_entries) {
278 /* This does the original UNIX user itself */
280 if ((pwd = getpwent()) == NULL) break;
281 user_name_len = strlen(pwd->pw_name);
282 pw_rid = pdb_uid_to_user_rid(pwd->pw_uid);
283 init_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->pw_name, user_name_len);
284 init_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
285 pw_buf[(*num_entries)].user_rid = pw_rid;
286 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
288 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
290 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
298 /* This does all the user names that map to the UNIX user */
299 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
300 (*num_entries < max_num_entries)) {
301 user_name_len = strlen(unmap_name);
302 init_unistr2(&(pw_buf[(*num_entries)].uni_user_name), unmap_name, user_name_len);
303 init_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
304 pw_buf[(*num_entries)].user_rid = pw_rid;
305 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
307 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
309 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
317 if (unmap_name == NULL) {
318 /* done with 'aliases', go on to next UNIX user */
325 /* totally done, reset everything */
331 return (*num_entries) > 0;
334 /*******************************************************************
336 ********************************************************************/
337 static void samr_reply_close_hnd(SAMR_Q_CLOSE_HND *q_u,
340 SAMR_R_CLOSE_HND r_u;
342 /* set up the SAMR unknown_1 response */
343 memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
345 /* close the policy handle */
346 if (close_lsa_policy_hnd(&(q_u->pol)))
352 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_INVALID;
355 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
357 /* store the response in the SMB stream */
358 samr_io_r_close_hnd("", &r_u, rdata, 0);
360 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
364 /*******************************************************************
366 ********************************************************************/
367 static BOOL api_samr_close_hnd( uint16 vuid, prs_struct *data, prs_struct *rdata)
369 SAMR_Q_CLOSE_HND q_u;
371 /* grab the samr unknown 1 */
372 samr_io_q_close_hnd("", &q_u, data, 0);
374 /* construct reply. always indicate success */
375 samr_reply_close_hnd(&q_u, rdata);
381 /*******************************************************************
382 samr_reply_open_domain
383 ********************************************************************/
384 static void samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
387 SAMR_R_OPEN_DOMAIN r_u;
388 BOOL pol_open = False;
392 /* find the connection policy handle. */
393 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->connect_pol)) == -1))
395 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
398 /* get a (unique) handle. open a policy on it. */
399 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.domain_pol))))
401 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
404 /* associate the domain SID with the (unique) handle. */
405 if (r_u.status == 0x0 && !set_lsa_policy_samr_sid(&(r_u.domain_pol), &(q_u->dom_sid.sid)))
407 /* oh, whoops. don't know what error message to return, here */
408 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
411 if (r_u.status != 0 && pol_open)
413 close_lsa_policy_hnd(&(r_u.domain_pol));
416 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
418 /* store the response in the SMB stream */
419 samr_io_r_open_domain("", &r_u, rdata, 0);
421 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
425 /*******************************************************************
427 ********************************************************************/
428 static BOOL api_samr_open_domain( uint16 vuid, prs_struct *data, prs_struct *rdata)
430 SAMR_Q_OPEN_DOMAIN q_u;
432 /* grab the samr open */
433 samr_io_q_open_domain("", &q_u, data, 0);
435 /* construct reply. always indicate success */
436 samr_reply_open_domain(&q_u, rdata);
442 /*******************************************************************
443 samr_reply_unknown_2c
444 ********************************************************************/
445 static void samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u,
448 SAMR_R_UNKNOWN_2C r_u;
451 /* find the policy handle. open a policy on it. */
452 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
454 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
457 /* find the user's rid */
458 if ((status == 0x0) && (get_lsa_policy_samr_rid(&(q_u->user_pol)) == 0xffffffff))
460 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
463 init_samr_r_unknown_2c(&r_u, status);
465 DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
467 /* store the response in the SMB stream */
468 samr_io_r_unknown_2c("", &r_u, rdata, 0);
470 DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
474 /*******************************************************************
476 ********************************************************************/
477 static BOOL api_samr_unknown_2c( uint16 vuid, prs_struct *data, prs_struct *rdata)
479 SAMR_Q_UNKNOWN_2C q_u;
481 /* grab the samr open */
482 samr_io_q_unknown_2c("", &q_u, data, 0);
484 /* construct reply. always indicate success */
485 samr_reply_unknown_2c(&q_u, rdata);
491 /*******************************************************************
493 ********************************************************************/
494 static void samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
497 SAMR_R_UNKNOWN_3 r_u;
498 DOM_SID3 sid[MAX_SAM_SIDS];
504 /* find the policy handle. open a policy on it. */
505 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
507 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
510 /* find the user's rid */
511 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->user_pol))) == 0xffffffff)
513 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
519 DOM_SID everyone_sid;
521 user_sid = global_sam_sid;
523 SMB_ASSERT_ARRAY(user_sid.sub_auths, user_sid.num_auths+1);
528 user_sid.sub_auths[user_sid.num_auths++] = rid;
530 string_to_sid(&everyone_sid, "S-1-1");
532 /* maybe need another 1 or 2 (S-1-5-0x20-0x220 and S-1-5-20-0x224) */
533 /* these two are DOMAIN_ADMIN and DOMAIN_ACCT_OP group RIDs */
534 init_dom_sid3(&(sid[0]), 0x035b, 0x0002, &everyone_sid);
535 init_dom_sid3(&(sid[1]), 0x0044, 0x0002, &user_sid);
538 init_samr_r_unknown_3(&r_u,
540 0x00000014, 0x0002, 0x0070,
543 DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
545 /* store the response in the SMB stream */
546 samr_io_r_unknown_3("", &r_u, rdata, 0);
548 DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
552 /*******************************************************************
554 ********************************************************************/
555 static BOOL api_samr_unknown_3( uint16 vuid, prs_struct *data, prs_struct *rdata)
557 SAMR_Q_UNKNOWN_3 q_u;
559 /* grab the samr open */
560 samr_io_q_unknown_3("", &q_u, data, 0);
562 /* construct reply. always indicate success */
563 samr_reply_unknown_3(&q_u, rdata);
569 /*******************************************************************
570 samr_reply_enum_dom_users
571 ********************************************************************/
572 static void samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
575 SAMR_R_ENUM_DOM_USERS r_e;
576 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
581 r_e.total_num_entries = 0;
583 /* find the policy handle. open a policy on it. */
584 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
586 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
589 DEBUG(5,("samr_reply_enum_dom_users: %d\n", __LINE__));
592 get_sampwd_entries(pass, 0, &total_entries, &num_entries, MAX_SAM_ENTRIES, q_u->acb_mask);
595 init_samr_r_enum_dom_users(&r_e, total_entries,
596 q_u->unknown_0, num_entries,
599 /* store the response in the SMB stream */
600 samr_io_r_enum_dom_users("", &r_e, rdata, 0);
602 DEBUG(5,("samr_enum_dom_users: %d\n", __LINE__));
606 /*******************************************************************
607 api_samr_enum_dom_users
608 ********************************************************************/
609 static BOOL api_samr_enum_dom_users( uint16 vuid, prs_struct *data, prs_struct *rdata)
611 SAMR_Q_ENUM_DOM_USERS q_e;
613 /* grab the samr open */
614 samr_io_q_enum_dom_users("", &q_e, data, 0);
616 /* construct reply. */
617 samr_reply_enum_dom_users(&q_e, rdata);
623 /*******************************************************************
624 samr_reply_enum_dom_groups
625 ********************************************************************/
626 static void samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u,
629 SAMR_R_ENUM_DOM_GROUPS r_e;
630 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
633 char *dummy_group = "Domain Admins";
638 /* find the policy handle. open a policy on it. */
639 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
641 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
644 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
648 init_unistr2(&(pass[0].uni_user_name), dummy_group, strlen(dummy_group));
649 pass[0].user_rid = DOMAIN_GROUP_RID_ADMINS;
651 if (r_e.status == 0 && got_grps)
653 init_samr_r_enum_dom_groups(&r_e, q_u->start_idx, num_entries, pass, r_e.status);
656 /* store the response in the SMB stream */
657 samr_io_r_enum_dom_groups("", &r_e, rdata, 0);
659 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
663 /*******************************************************************
664 api_samr_enum_dom_groups
665 ********************************************************************/
666 static BOOL api_samr_enum_dom_groups( uint16 vuid, prs_struct *data, prs_struct *rdata)
668 SAMR_Q_ENUM_DOM_GROUPS q_e;
670 /* grab the samr open */
671 samr_io_q_enum_dom_groups("", &q_e, data, 0);
673 /* construct reply. */
674 samr_reply_enum_dom_groups(&q_e, rdata);
679 /*******************************************************************
680 samr_reply_enum_dom_aliases
681 ********************************************************************/
682 static void samr_reply_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_u,
685 SAMR_R_ENUM_DOM_ALIASES r_e;
686 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
696 /* find the policy handle. open a policy on it. */
697 if (r_e.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &sid))
699 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
702 sid_to_string(sid_str, &sid);
703 sid_to_string(sam_sid_str, &global_sam_sid);
705 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
707 /* well-known aliases */
708 if (strequal(sid_str, "S-1-5-32"))
711 while (num_entries < MAX_SAM_ENTRIES && ((name = builtin_alias_rids[num_entries].name) != NULL))
713 init_unistr2(&(pass[num_entries].uni_user_name), name, strlen(name));
714 pass[num_entries].user_rid = builtin_alias_rids[num_entries].rid;
718 else if (strequal(sid_str, sam_sid_str))
722 /* we return the UNIX groups here. This seems to be the right */
723 /* thing to do, since NT member servers return their local */
724 /* groups in the same situation. */
727 while (num_entries < MAX_SAM_ENTRIES && ((grp = getgrent()) != NULL))
730 init_unistr2(&(pass[num_entries].uni_user_name), name, strlen(name));
731 pass[num_entries].user_rid = pdb_gid_to_group_rid(grp->gr_gid);
738 init_samr_r_enum_dom_aliases(&r_e, num_entries, pass, r_e.status);
740 /* store the response in the SMB stream */
741 samr_io_r_enum_dom_aliases("", &r_e, rdata, 0);
743 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
747 /*******************************************************************
748 api_samr_enum_dom_aliases
749 ********************************************************************/
750 static BOOL api_samr_enum_dom_aliases( uint16 vuid, prs_struct *data, prs_struct *rdata)
752 SAMR_Q_ENUM_DOM_ALIASES q_e;
754 /* grab the samr open */
755 samr_io_q_enum_dom_aliases("", &q_e, data, 0);
757 /* construct reply. */
758 samr_reply_enum_dom_aliases(&q_e, rdata);
764 /*******************************************************************
765 samr_reply_query_dispinfo
766 ********************************************************************/
767 static void samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u,
770 SAMR_R_QUERY_DISPINFO r_e;
774 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
776 int total_entries = 0;
778 uint16 switch_level = 0x0;
784 DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
786 /* find the policy handle. open a policy on it. */
787 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
789 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
790 DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n"));
793 if (r_e.status == 0x0)
796 got_pwds = get_passwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, MAX_SAM_ENTRIES, 0);
799 switch (q_u->switch_level)
804 /* query disp info is for users */
806 init_sam_info_1(&info1, ACB_NORMAL,
807 q_u->start_idx, num_entries, pass);
809 ctr.sam.info1 = &info1;
815 /* query disp info is for servers */
817 init_sam_info_2(&info2, ACB_WSTRUST,
818 q_u->start_idx, num_entries, pass);
820 ctr.sam.info2 = &info2;
829 init_samr_r_query_dispinfo(&r_e, switch_level, &ctr, r_e.status);
832 /* store the response in the SMB stream */
833 samr_io_r_query_dispinfo("", &r_e, rdata, 0);
835 DEBUG(5,("samr_query_dispinfo: %d\n", __LINE__));
839 /*******************************************************************
840 api_samr_query_dispinfo
841 ********************************************************************/
842 static BOOL api_samr_query_dispinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
844 SAMR_Q_QUERY_DISPINFO q_e;
846 /* grab the samr open */
847 samr_io_q_query_dispinfo("", &q_e, data, 0);
849 /* construct reply. */
850 samr_reply_query_dispinfo(&q_e, rdata);
856 /*******************************************************************
857 samr_reply_query_aliasinfo
858 ********************************************************************/
859 static void samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
862 SAMR_R_QUERY_ALIASINFO r_e;
867 /* find the policy handle. open a policy on it. */
868 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
870 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
873 DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__));
875 if (r_e.status == 0x0)
877 if (q_u->switch_level != 3)
879 r_e.status = NT_STATUS_INVALID_INFO_CLASS;
883 init_samr_r_query_aliasinfo(&r_e, q_u->switch_level,
887 /* store the response in the SMB stream */
888 samr_io_r_query_aliasinfo("", &r_e, rdata, 0);
890 DEBUG(5,("samr_query_aliasinfo: %d\n", __LINE__));
894 /*******************************************************************
895 api_samr_query_aliasinfo
896 ********************************************************************/
897 static BOOL api_samr_query_aliasinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
899 SAMR_Q_QUERY_ALIASINFO q_e;
901 /* grab the samr open */
902 samr_io_q_query_aliasinfo("", &q_e, data, 0);
904 /* construct reply. */
905 samr_reply_query_aliasinfo(&q_e, rdata);
911 /*******************************************************************
912 samr_reply_lookup_ids
913 ********************************************************************/
914 static void samr_reply_lookup_ids(SAMR_Q_LOOKUP_IDS *q_u,
917 uint32 rid[MAX_SAM_ENTRIES];
919 int num_rids = q_u->num_sids1;
921 SAMR_R_LOOKUP_IDS r_u;
923 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
925 if (num_rids > MAX_SAM_ENTRIES)
927 num_rids = MAX_SAM_ENTRIES;
928 DEBUG(5,("samr_lookup_ids: truncating entries to %d\n", num_rids));
933 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
935 for (i = 0; i < num_rids && status == 0; i++)
937 struct sam_passwd *sam_pass;
941 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
942 q_u->uni_user_name[i].uni_str_len));
944 /* find the user account */
946 sam_pass = get_smb21pwd_entry(user_name, 0);
949 if (sam_pass == NULL)
951 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
956 rid[i] = sam_pass->user_rid;
962 rid[0] = BUILTIN_ALIAS_RID_USERS;
964 init_samr_r_lookup_ids(&r_u, num_rids, rid, status);
966 /* store the response in the SMB stream */
967 samr_io_r_lookup_ids("", &r_u, rdata, 0);
969 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
973 /*******************************************************************
975 ********************************************************************/
976 static BOOL api_samr_lookup_ids( uint16 vuid, prs_struct *data, prs_struct *rdata)
978 SAMR_Q_LOOKUP_IDS q_u;
980 /* grab the samr 0x10 */
981 samr_io_q_lookup_ids("", &q_u, data, 0);
983 /* construct reply. always indicate success */
984 samr_reply_lookup_ids(&q_u, rdata);
989 /*******************************************************************
990 samr_reply_lookup_names
991 ********************************************************************/
993 static BOOL samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
996 uint32 rid[MAX_SAM_ENTRIES];
997 uint8 type[MAX_SAM_ENTRIES];
1000 int num_rids = q_u->num_names1;
1003 SAMR_R_LOOKUP_NAMES r_u;
1005 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1010 if (!get_lsa_policy_samr_sid(&q_u->pol, &pol_sid)) {
1011 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
1012 init_samr_r_lookup_names(&r_u, 0, rid, type, status);
1013 if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
1014 DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
1020 if (num_rids > MAX_SAM_ENTRIES) {
1021 num_rids = MAX_SAM_ENTRIES;
1022 DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
1025 SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
1027 for (i = 0; i < num_rids; i++) {
1030 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
1032 rid [i] = 0xffffffff;
1033 type[i] = SID_NAME_UNKNOWN;
1035 fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer,
1036 q_u->uni_name[i].uni_str_len));
1038 if(sid_equal(&pol_sid, &global_sam_sid)) {
1041 if(lookup_local_name(global_myname, name, &sid, &type[i])) {
1042 sid_split_rid( &sid, &rid[i]);
1048 init_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
1050 /* store the response in the SMB stream */
1051 if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
1052 DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
1056 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1061 /*******************************************************************
1062 api_samr_lookup_names
1063 ********************************************************************/
1065 static BOOL api_samr_lookup_names( uint16 vuid, prs_struct *data, prs_struct *rdata)
1067 SAMR_Q_LOOKUP_NAMES q_u;
1069 memset(&q_u, '\0', sizeof(q_u));
1071 /* grab the samr lookup names */
1072 if(!samr_io_q_lookup_names("", &q_u, data, 0)) {
1073 DEBUG(0,("api_samr_lookup_names: failed to unmarshall SAMR_Q_LOOKUP_NAMES.\n"));
1077 /* construct reply. always indicate success */
1078 if(!samr_reply_lookup_names(&q_u, rdata))
1084 /*******************************************************************
1085 samr_reply_chgpasswd_user
1086 ********************************************************************/
1088 static BOOL samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
1091 SAMR_R_CHGPASSWD_USER r_u;
1092 uint32 status = 0x0;
1096 fstrcpy(user_name, dos_unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len));
1097 fstrcpy(wks , dos_unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len));
1099 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1101 if (!pass_oem_change(user_name,
1102 q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1103 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1105 status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
1108 init_samr_r_chgpasswd_user(&r_u, status);
1110 /* store the response in the SMB stream */
1111 if(!samr_io_r_chgpasswd_user("", &r_u, rdata, 0)) {
1112 DEBUG(0,("samr_reply_chgpasswd_user: Failed to marshall SAMR_R_CHGPASSWD_USER struct.\n" ));
1116 DEBUG(5,("samr_chgpasswd_user: %d\n", __LINE__));
1120 /*******************************************************************
1121 api_samr_chgpasswd_user
1122 ********************************************************************/
1124 static BOOL api_samr_chgpasswd_user( uint16 vuid, prs_struct *data, prs_struct *rdata)
1126 SAMR_Q_CHGPASSWD_USER q_u;
1128 /* unknown 38 command */
1129 if (!samr_io_q_chgpasswd_user("", &q_u, data, 0)) {
1130 DEBUG(0,("api_samr_chgpasswd_user: samr_io_q_chgpasswd_user failed to parse RPC packet.\n"));
1134 /* construct reply. */
1135 if(!samr_reply_chgpasswd_user(&q_u, rdata)) {
1136 DEBUG(0,("api_samr_chgpasswd_user: samr_reply_chgpasswd_user failed to create reply packet.\n"));
1144 /*******************************************************************
1145 samr_reply_unknown_38
1146 ********************************************************************/
1147 static void samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u,
1150 SAMR_R_UNKNOWN_38 r_u;
1152 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1154 init_samr_r_unknown_38(&r_u);
1156 /* store the response in the SMB stream */
1157 samr_io_r_unknown_38("", &r_u, rdata, 0);
1159 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1162 /*******************************************************************
1164 ********************************************************************/
1165 static BOOL api_samr_unknown_38( uint16 vuid, prs_struct *data, prs_struct *rdata)
1167 SAMR_Q_UNKNOWN_38 q_u;
1169 /* unknown 38 command */
1170 samr_io_q_unknown_38("", &q_u, data, 0);
1172 /* construct reply. always indicate success */
1173 samr_reply_unknown_38(&q_u, rdata);
1179 /*******************************************************************
1180 samr_reply_unknown_12
1181 ********************************************************************/
1182 static void samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
1185 fstring group_names[MAX_SAM_ENTRIES];
1186 uint32 group_attrs[MAX_SAM_ENTRIES];
1188 int num_gids = q_u->num_gids1;
1190 SAMR_R_UNKNOWN_12 r_u;
1192 DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
1194 /* find the policy handle. open a policy on it. */
1195 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1197 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1203 if (num_gids > MAX_SAM_ENTRIES)
1205 num_gids = MAX_SAM_ENTRIES;
1206 DEBUG(5,("samr_unknown_12: truncating entries to %d\n", num_gids));
1209 for (i = 0; i < num_gids && status == 0; i++)
1211 fstrcpy(group_names[i], "dummy group");
1212 group_attrs[i] = 0x2;
1216 init_samr_r_unknown_12(&r_u, num_gids, group_names, group_attrs, status);
1218 /* store the response in the SMB stream */
1219 samr_io_r_unknown_12("", &r_u, rdata, 0);
1221 DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
1225 /*******************************************************************
1227 ********************************************************************/
1228 static BOOL api_samr_unknown_12( uint16 vuid, prs_struct *data, prs_struct *rdata)
1230 SAMR_Q_UNKNOWN_12 q_u;
1232 /* grab the samr lookup names */
1233 samr_io_q_unknown_12("", &q_u, data, 0);
1235 /* construct reply. always indicate success */
1236 samr_reply_unknown_12(&q_u, rdata);
1242 /*******************************************************************
1243 samr_reply_open_user
1244 ********************************************************************/
1245 static void samr_reply_open_user(SAMR_Q_OPEN_USER *q_u,
1249 SAMR_R_OPEN_USER r_u;
1250 struct sam_passwd *sam_pass;
1251 BOOL pol_open = False;
1253 /* set up the SAMR open_user response */
1254 memset((char *)r_u.user_pol.data, '\0', POL_HND_SIZE);
1258 /* find the policy handle. open a policy on it. */
1259 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
1261 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1264 /* get a (unique) handle. open a policy on it. */
1265 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.user_pol))))
1267 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1271 sam_pass = getsam21pwrid(q_u->user_rid);
1272 unbecome_root(True);
1274 /* check that the RID exists in our domain. */
1275 if (r_u.status == 0x0 && sam_pass == NULL)
1277 r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1280 /* associate the RID with the (unique) handle. */
1281 if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.user_pol), q_u->user_rid))
1283 /* oh, whoops. don't know what error message to return, here */
1284 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1287 if (r_u.status != 0 && pol_open)
1289 close_lsa_policy_hnd(&(r_u.user_pol));
1292 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1294 /* store the response in the SMB stream */
1295 samr_io_r_open_user("", &r_u, rdata, 0);
1297 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1301 /*******************************************************************
1303 ********************************************************************/
1304 static BOOL api_samr_open_user( uint16 vuid, prs_struct *data, prs_struct *rdata)
1306 SAMR_Q_OPEN_USER q_u;
1308 /* grab the samr unknown 22 */
1309 samr_io_q_open_user("", &q_u, data, 0);
1311 /* construct reply. always indicate success */
1312 samr_reply_open_user(&q_u, rdata, 0x0);
1318 /*************************************************************************
1320 *************************************************************************/
1321 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1323 struct smb_passwd *smb_pass;
1325 if (!pdb_rid_is_user(user_rid))
1327 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1332 smb_pass = getsmbpwrid(user_rid);
1333 unbecome_root(True);
1335 if (smb_pass == NULL)
1337 DEBUG(4,("User 0x%x not found\n", user_rid));
1341 DEBUG(3,("User:[%s]\n", smb_pass->smb_name));
1343 init_sam_user_info10(id10, smb_pass->acct_ctrl);
1348 /*************************************************************************
1350 *************************************************************************/
1351 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1354 struct sam_passwd *sam_pass;
1358 if (!pdb_rid_is_user(user_rid))
1360 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1365 sam_pass = getsam21pwrid(user_rid);
1366 unbecome_root(True);
1368 if (sam_pass == NULL)
1370 DEBUG(4,("User 0x%x not found\n", user_rid));
1374 DEBUG(3,("User:[%s]\n", sam_pass->smb_name));
1376 dummy_time.low = 0xffffffff;
1377 dummy_time.high = 0x7fffffff;
1379 DEBUG(5,("get_user_info_21 - TODO: convert unix times to NTTIMEs\n"));
1381 /* create a LOGON_HRS structure */
1382 hrs.len = sam_pass->hours_len;
1383 SMB_ASSERT_ARRAY(hrs.hours, hrs.len);
1384 for (i = 0; i < hrs.len; i++)
1386 hrs.hours[i] = sam_pass->hours[i];
1389 init_sam_user_info21(id21,
1391 &dummy_time, /* logon_time */
1392 &dummy_time, /* logoff_time */
1393 &dummy_time, /* kickoff_time */
1394 &dummy_time, /* pass_last_set_time */
1395 &dummy_time, /* pass_can_change_time */
1396 &dummy_time, /* pass_must_change_time */
1398 sam_pass->smb_name, /* user_name */
1399 sam_pass->full_name, /* full_name */
1400 sam_pass->home_dir, /* home_dir */
1401 sam_pass->dir_drive, /* dir_drive */
1402 sam_pass->logon_script, /* logon_script */
1403 sam_pass->profile_path, /* profile_path */
1404 sam_pass->acct_desc, /* description */
1405 sam_pass->workstations, /* workstations user can log in from */
1406 sam_pass->unknown_str, /* don't know, yet */
1407 sam_pass->munged_dial, /* dialin info. contains dialin path and tel no */
1409 sam_pass->user_rid, /* RID user_id */
1410 sam_pass->group_rid, /* RID group_id */
1411 sam_pass->acct_ctrl,
1413 sam_pass->unknown_3, /* unknown_3 */
1414 sam_pass->logon_divs, /* divisions per week */
1415 &hrs, /* logon hours */
1416 sam_pass->unknown_5,
1417 sam_pass->unknown_6);
1422 /*******************************************************************
1423 samr_reply_query_userinfo
1424 ********************************************************************/
1425 static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
1428 SAMR_R_QUERY_USERINFO r_u;
1430 SAM_USER_INFO_11 id11;
1432 SAM_USER_INFO_10 id10;
1433 SAM_USER_INFO_21 id21;
1436 uint32 status = 0x0;
1439 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1441 /* search for the handle */
1442 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1444 status = NT_STATUS_INVALID_HANDLE;
1447 /* find the user's rid */
1448 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1450 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1453 DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
1455 /* ok! user info levels (there are lots: see MSDEV help), off we go... */
1458 switch (q_u->switch_value)
1462 info = (void*)&id10;
1463 status = get_user_info_10(&id10, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1467 /* whoops - got this wrong. i think. or don't understand what's happening. */
1471 info = (void*)&id11;
1473 expire.low = 0xffffffff;
1474 expire.high = 0x7fffffff;
1476 make_sam_user_info11(&id11, &expire, "BROOKFIELDS$", 0x03ef, 0x201, 0x0080);
1483 info = (void*)&id21;
1484 status = get_user_info_21(&id21, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1490 status = NT_STATUS_INVALID_INFO_CLASS;
1497 init_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
1499 /* store the response in the SMB stream */
1500 samr_io_r_query_userinfo("", &r_u, rdata, 0);
1502 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1506 /*******************************************************************
1507 api_samr_query_userinfo
1508 ********************************************************************/
1509 static BOOL api_samr_query_userinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
1511 SAMR_Q_QUERY_USERINFO q_u;
1513 /* grab the samr unknown 24 */
1514 samr_io_q_query_userinfo("", &q_u, data, 0);
1516 /* construct reply. always indicate success */
1517 samr_reply_query_userinfo(&q_u, rdata);
1523 /*******************************************************************
1524 samr_reply_query_usergroups
1525 ********************************************************************/
1526 static void samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
1529 SAMR_R_QUERY_USERGROUPS r_u;
1530 uint32 status = 0x0;
1532 struct sam_passwd *sam_pass;
1533 DOM_GID *gids = NULL;
1537 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1539 /* find the policy handle. open a policy on it. */
1540 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1542 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1545 /* find the user's rid */
1546 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1548 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1554 sam_pass = getsam21pwrid(rid);
1555 unbecome_root(True);
1557 if (sam_pass == NULL)
1559 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1566 get_domain_user_groups(groups, sam_pass->smb_name);
1568 num_groups = make_dom_gids(groups, &gids);
1571 /* construct the response. lkclXXXX: gids are not copied! */
1572 init_samr_r_query_usergroups(&r_u, num_groups, gids, status);
1574 /* store the response in the SMB stream */
1575 samr_io_r_query_usergroups("", &r_u, rdata, 0);
1582 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1586 /*******************************************************************
1587 api_samr_query_usergroups
1588 ********************************************************************/
1589 static BOOL api_samr_query_usergroups( uint16 vuid, prs_struct *data, prs_struct *rdata)
1591 SAMR_Q_QUERY_USERGROUPS q_u;
1592 /* grab the samr unknown 32 */
1593 samr_io_q_query_usergroups("", &q_u, data, 0);
1595 /* construct reply. */
1596 samr_reply_query_usergroups(&q_u, rdata);
1602 /*******************************************************************
1603 samr_reply_query_dom_info
1604 ********************************************************************/
1605 static void samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
1608 SAMR_R_QUERY_DOMAIN_INFO r_u;
1610 uint16 switch_value = 0x0;
1611 uint32 status = 0x0;
1618 DEBUG(5,("samr_reply_query_dom_info: %d\n", __LINE__));
1620 /* find the policy handle. open a policy on it. */
1621 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
1623 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1624 DEBUG(5,("samr_reply_query_dom_info: invalid handle\n"));
1629 switch (q_u->switch_value)
1634 init_unk_info2(&ctr.info.inf2, global_myworkgroup, global_myname);
1640 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
1646 init_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
1648 /* store the response in the SMB stream */
1649 samr_io_r_query_dom_info("", &r_u, rdata, 0);
1651 DEBUG(5,("samr_query_dom_info: %d\n", __LINE__));
1655 /*******************************************************************
1656 api_samr_query_dom_info
1657 ********************************************************************/
1658 static BOOL api_samr_query_dom_info( uint16 vuid, prs_struct *data, prs_struct *rdata)
1660 SAMR_Q_QUERY_DOMAIN_INFO q_e;
1662 /* grab the samr unknown 8 command */
1663 samr_io_q_query_dom_info("", &q_e, data, 0);
1665 /* construct reply. */
1666 samr_reply_query_dom_info(&q_e, rdata);
1673 /*******************************************************************
1674 samr_reply_unknown_32
1675 ********************************************************************/
1676 static void samr_reply_unknown_32(SAMR_Q_UNKNOWN_32 *q_u,
1681 SAMR_R_UNKNOWN_32 r_u;
1683 /* set up the SAMR unknown_32 response */
1684 memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
1687 for (i = 4; i < POL_HND_SIZE; i++)
1689 r_u.pol.data[i] = i+1;
1693 init_dom_rid4(&(r_u.rid4), 0x0030, 0, 0);
1694 r_u.status = status;
1696 DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
1698 /* store the response in the SMB stream */
1699 samr_io_r_unknown_32("", &r_u, rdata, 0);
1701 DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
1705 /*******************************************************************
1707 ********************************************************************/
1708 static BOOL api_samr_unknown_32( uint16 vuid, prs_struct *data, prs_struct *rdata)
1711 struct sam_passwd *sam_pass;
1714 SAMR_Q_UNKNOWN_32 q_u;
1716 /* grab the samr unknown 32 */
1717 samr_io_q_unknown_32("", &q_u, data, 0);
1719 /* find the machine account: tell the caller if it exists.
1720 lkclXXXX i have *no* idea if this is a problem or not
1721 or even if you are supposed to construct a different
1722 reply if the account already exists...
1725 fstrcpy(mach_acct, dos_unistrn2(q_u.uni_mach_acct.buffer,
1726 q_u.uni_mach_acct.uni_str_len));
1729 sam_pass = getsam21pwnam(mach_acct);
1730 unbecome_root(True);
1732 if (sam_pass != NULL)
1734 /* machine account exists: say so */
1735 status = 0xC0000000 | NT_STATUS_USER_EXISTS;
1739 /* this could cause trouble... */
1740 DEBUG(0,("trouble!\n"));
1744 /* construct reply. */
1745 samr_reply_unknown_32(&q_u, rdata, status);
1751 /*******************************************************************
1752 samr_reply_connect_anon
1753 ********************************************************************/
1754 static void samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u,
1757 SAMR_R_CONNECT_ANON r_u;
1758 BOOL pol_open = False;
1760 /* set up the SAMR connect_anon response */
1763 /* get a (unique) handle. open a policy on it. */
1764 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1766 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1769 /* associate the domain SID with the (unique) handle. */
1770 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1772 /* oh, whoops. don't know what error message to return, here */
1773 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1776 if (r_u.status != 0 && pol_open)
1778 close_lsa_policy_hnd(&(r_u.connect_pol));
1781 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1783 /* store the response in the SMB stream */
1784 samr_io_r_connect_anon("", &r_u, rdata, 0);
1786 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1790 /*******************************************************************
1791 api_samr_connect_anon
1792 ********************************************************************/
1793 static BOOL api_samr_connect_anon( uint16 vuid, prs_struct *data, prs_struct *rdata)
1795 SAMR_Q_CONNECT_ANON q_u;
1797 /* grab the samr open policy */
1798 samr_io_q_connect_anon("", &q_u, data, 0);
1800 /* construct reply. always indicate success */
1801 samr_reply_connect_anon(&q_u, rdata);
1806 /*******************************************************************
1808 ********************************************************************/
1809 static void samr_reply_connect(SAMR_Q_CONNECT *q_u,
1813 BOOL pol_open = False;
1815 /* set up the SAMR connect response */
1818 /* get a (unique) handle. open a policy on it. */
1819 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1821 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1824 /* associate the domain SID with the (unique) handle. */
1825 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1827 /* oh, whoops. don't know what error message to return, here */
1828 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1831 if (r_u.status != 0 && pol_open)
1833 close_lsa_policy_hnd(&(r_u.connect_pol));
1836 DEBUG(5,("samr_connect: %d\n", __LINE__));
1838 /* store the response in the SMB stream */
1839 samr_io_r_connect("", &r_u, rdata, 0);
1841 DEBUG(5,("samr_connect: %d\n", __LINE__));
1845 /*******************************************************************
1847 ********************************************************************/
1848 static BOOL api_samr_connect( uint16 vuid, prs_struct *data, prs_struct *rdata)
1852 /* grab the samr open policy */
1853 samr_io_q_connect("", &q_u, data, 0);
1855 /* construct reply. always indicate success */
1856 samr_reply_connect(&q_u, rdata);
1861 /*******************************************************************
1862 samr_reply_open_alias
1863 ********************************************************************/
1864 static void samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
1867 SAMR_R_OPEN_ALIAS r_u;
1868 BOOL pol_open = False;
1870 /* set up the SAMR open_alias response */
1873 /* get a (unique) handle. open a policy on it. */
1874 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.pol))))
1876 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1879 /* associate a RID with the (unique) handle. */
1880 if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.pol), q_u->rid_alias))
1882 /* oh, whoops. don't know what error message to return, here */
1883 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1886 if (r_u.status != 0 && pol_open)
1888 close_lsa_policy_hnd(&(r_u.pol));
1891 DEBUG(5,("samr_open_alias: %d\n", __LINE__));
1893 /* store the response in the SMB stream */
1894 samr_io_r_open_alias("", &r_u, rdata, 0);
1896 DEBUG(5,("samr_open_alias: %d\n", __LINE__));
1900 /*******************************************************************
1902 ********************************************************************/
1903 static BOOL api_samr_open_alias( uint16 vuid, prs_struct *data, prs_struct *rdata)
1906 SAMR_Q_OPEN_ALIAS q_u;
1908 /* grab the samr open policy */
1909 samr_io_q_open_alias("", &q_u, data, 0);
1911 /* construct reply. always indicate success */
1912 samr_reply_open_alias(&q_u, rdata);
1917 /*******************************************************************
1918 array of \PIPE\samr operations
1919 ********************************************************************/
1920 static struct api_struct api_samr_cmds [] =
1922 { "SAMR_CLOSE_HND" , SAMR_CLOSE_HND , api_samr_close_hnd },
1923 { "SAMR_CONNECT" , SAMR_CONNECT , api_samr_connect },
1924 { "SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON , api_samr_connect_anon },
1925 { "SAMR_ENUM_DOM_USERS" , SAMR_ENUM_DOM_USERS , api_samr_enum_dom_users },
1926 { "SAMR_ENUM_DOM_GROUPS" , SAMR_ENUM_DOM_GROUPS , api_samr_enum_dom_groups },
1927 { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
1928 { "SAMR_LOOKUP_IDS" , SAMR_LOOKUP_IDS , api_samr_lookup_ids },
1929 { "SAMR_LOOKUP_NAMES" , SAMR_LOOKUP_NAMES , api_samr_lookup_names },
1930 { "SAMR_OPEN_USER" , SAMR_OPEN_USER , api_samr_open_user },
1931 { "SAMR_QUERY_USERINFO" , SAMR_QUERY_USERINFO , api_samr_query_userinfo },
1932 { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
1933 { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
1934 { "SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo },
1935 { "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo },
1936 { "SAMR_0x32" , 0x32 , api_samr_unknown_32 },
1937 { "SAMR_UNKNOWN_12" , SAMR_UNKNOWN_12 , api_samr_unknown_12 },
1938 { "SAMR_UNKNOWN_38" , SAMR_UNKNOWN_38 , api_samr_unknown_38 },
1939 { "SAMR_CHGPASSWD_USER" , SAMR_CHGPASSWD_USER , api_samr_chgpasswd_user },
1940 { "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias },
1941 { "SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain },
1942 { "SAMR_UNKNOWN_3" , SAMR_UNKNOWN_3 , api_samr_unknown_3 },
1943 { "SAMR_UNKNOWN_2C" , SAMR_UNKNOWN_2C , api_samr_unknown_2c },
1947 /*******************************************************************
1948 receives a samr pipe and responds.
1949 ********************************************************************/
1950 BOOL api_samr_rpc(pipes_struct *p, prs_struct *data)
1952 return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds, data);