3 * Unix SMB/Netbios implementation.
5 * RPC Pipe client / server routines
6 * Copyright (C) Andrew Tridgell 1992-1997,
7 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
8 * Copyright (C) Paul Ashton 1997.
9 * Copyright (C) Hewlett-Packard Company 1999.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 extern int DEBUGLEVEL;
30 extern fstring global_myworkgroup;
31 extern pstring global_myname;
32 extern DOM_SID global_sam_sid;
34 extern rid_name domain_group_rids[];
35 extern rid_name domain_alias_rids[];
36 extern rid_name builtin_alias_rids[];
38 /*******************************************************************
39 This next function should be replaced with something that
40 dynamically returns the correct user info..... JRA.
41 ********************************************************************/
43 static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf,
45 int *total_entries, int *num_entries,
50 struct sam_passwd *pwd = NULL;
55 if (pw_buf == NULL) return False;
57 vp = startsmbpwent(False);
59 DEBUG(0, ("get_sampwd_entries: Unable to open SMB password database.\n"));
63 while (((pwd = getsam21pwent(vp)) != NULL) && (*num_entries) < max_num_entries) {
67 /* skip the requested number of entries.
68 not very efficient, but hey...
74 user_name_len = strlen(pwd->smb_name);
75 init_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->smb_name, user_name_len);
76 init_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
77 pw_buf[(*num_entries)].user_rid = pwd->user_rid;
78 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
80 /* Now check if the NT compatible password is available. */
81 if (pwd->smb_nt_passwd != NULL) {
82 memcpy( pw_buf[(*num_entries)].nt_pwd , pwd->smb_nt_passwd, 16);
85 pw_buf[(*num_entries)].acb_info = (uint16)pwd->acct_ctrl;
87 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
88 (*num_entries), pwd->smb_name,
89 pwd->user_rid, pwd->acct_ctrl));
91 if (acb_mask == 0 || IS_BITS_SET_SOME(pwd->acct_ctrl, acb_mask)) {
92 DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
95 DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
103 return (*num_entries) > 0;
106 /*******************************************************************
107 This function uses the username map file and tries to map a UNIX
108 user name to an DOS name. (Sort of the reverse of the
109 map_username() function.) Since more than one DOS name can map
110 to the UNIX name, to reverse the mapping you have to specify
111 which corresponding DOS name you want; that's where the name_idx
112 parameter comes in. Returns the string requested or NULL if it
113 fails or can't complete the request for any reason. This doesn't
114 handle group names (starting with '@') or names starting with
115 '+' or '&'. If they are encountered, they are skipped.
116 ********************************************************************/
118 static char *unmap_unixname(char *unix_user_name, int name_idx)
120 char *mapfile = lp_username_map();
125 if (!*unix_user_name) return NULL;
126 if (!*mapfile) return NULL;
128 lines = file_lines_load(mapfile, NULL);
130 DEBUG(0,("unmap_unixname: can't open username map %s\n", mapfile));
134 DEBUG(5,("unmap_unixname: scanning username map %s, index: %d\n", mapfile, name_idx));
136 for (i=0; lines[i]; i++) {
137 char *unixname = lines[i];
138 char *dosname = strchr(unixname,'=');
145 while (isspace(*unixname))
147 if ('!' == *unixname) {
149 while (*unixname && isspace(*unixname))
153 if (!*unixname || strchr("#;",*unixname))
156 if (strncmp(unixname, unix_user_name, strlen(unix_user_name)))
159 /* We have matched the UNIX user name */
161 while(next_token(&dosname, tok, LIST_SEP, sizeof(tok))) {
162 if (!strchr("@&+", *tok)) {
171 DEBUG(0,("unmap_unixname: index too high - not that many DOS names\n"));
172 file_lines_free(lines);
175 file_lines_free(lines);
180 DEBUG(0,("unmap_unixname: Couldn't find the UNIX user name\n"));
181 file_lines_free(lines);
185 /*******************************************************************
186 This function sets up a list of users taken from the list of
187 users that UNIX knows about, as well as all the user names that
188 Samba maps to a valid UNIX user name. (This should work with
190 ********************************************************************/
192 static BOOL get_passwd_entries(SAM_USER_INFO_21 *pw_buf,
194 int *total_entries, int *num_entries,
198 static struct passwd *pwd = NULL;
199 static uint32 pw_rid;
200 static BOOL orig_done = False;
201 static int current_idx = 0;
202 static int mapped_idx = 0;
204 DEBUG(5, ("get_passwd_entries: retrieving a list of UNIX users\n"));
207 (*total_entries) = 0;
209 if (pw_buf == NULL) return False;
211 if (current_idx == 0) {
215 /* These two cases are inefficient, but should be called very rarely */
216 /* they are the cases where the starting index isn't picking up */
217 /* where we left off last time. It is efficient when it starts over */
218 /* at zero though. */
219 if (start_idx > current_idx) {
220 /* We aren't far enough; advance to start_idx */
221 while (current_idx < start_idx) {
225 if ((pwd = getpwent()) == NULL) break;
230 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
231 (current_idx < start_idx)) {
236 if (unmap_name == NULL) {
241 } else if (start_idx < current_idx) {
242 /* We are already too far; start over and advance to start_idx */
248 while (current_idx < start_idx) {
252 if ((pwd = getpwent()) == NULL) break;
257 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
258 (current_idx < start_idx)) {
263 if (unmap_name == NULL) {
270 /* now current_idx == start_idx */
271 while ((*num_entries) < max_num_entries) {
275 /* This does the original UNIX user itself */
277 if ((pwd = getpwent()) == NULL) break;
278 user_name_len = strlen(pwd->pw_name);
279 pw_rid = pdb_uid_to_user_rid(pwd->pw_uid);
280 init_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->pw_name, user_name_len);
281 init_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
282 pw_buf[(*num_entries)].user_rid = pw_rid;
283 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
285 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
287 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
295 /* This does all the user names that map to the UNIX user */
296 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
297 (*num_entries < max_num_entries)) {
298 user_name_len = strlen(unmap_name);
299 init_unistr2(&(pw_buf[(*num_entries)].uni_user_name), unmap_name, user_name_len);
300 init_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
301 pw_buf[(*num_entries)].user_rid = pw_rid;
302 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
304 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
306 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
314 if (unmap_name == NULL) {
315 /* done with 'aliases', go on to next UNIX user */
322 /* totally done, reset everything */
328 return (*num_entries) > 0;
331 /*******************************************************************
333 ********************************************************************/
334 static BOOL samr_reply_close_hnd(SAMR_Q_CLOSE_HND *q_u,
337 SAMR_R_CLOSE_HND r_u;
339 /* set up the SAMR unknown_1 response */
340 memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
342 /* close the policy handle */
343 if (close_lsa_policy_hnd(&(q_u->pol)))
349 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_INVALID;
352 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
354 /* store the response in the SMB stream */
355 if(!samr_io_r_close_hnd("", &r_u, rdata, 0))
358 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 if(!samr_io_q_close_hnd("", &q_u, data, 0))
374 /* construct reply. always indicate success */
375 if(!samr_reply_close_hnd(&q_u, rdata))
382 /*******************************************************************
383 samr_reply_open_domain
384 ********************************************************************/
385 static BOOL samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
388 SAMR_R_OPEN_DOMAIN r_u;
389 BOOL pol_open = False;
393 /* find the connection policy handle. */
394 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->connect_pol)) == -1))
396 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
399 /* get a (unique) handle. open a policy on it. */
400 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.domain_pol))))
402 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
405 /* associate the domain SID with the (unique) handle. */
406 if (r_u.status == 0x0 && !set_lsa_policy_samr_sid(&(r_u.domain_pol), &(q_u->dom_sid.sid)))
408 /* oh, whoops. don't know what error message to return, here */
409 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
412 if (r_u.status != 0 && pol_open)
414 close_lsa_policy_hnd(&(r_u.domain_pol));
417 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
419 /* store the response in the SMB stream */
420 if(!samr_io_r_open_domain("", &r_u, rdata, 0))
423 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
428 /*******************************************************************
430 ********************************************************************/
431 static BOOL api_samr_open_domain(prs_struct *data, prs_struct *rdata)
433 SAMR_Q_OPEN_DOMAIN q_u;
435 /* grab the samr open */
436 if(!samr_io_q_open_domain("", &q_u, data, 0))
439 /* construct reply. always indicate success */
440 if(!samr_reply_open_domain(&q_u, rdata))
447 /*******************************************************************
448 samr_reply_unknown_2c
449 ********************************************************************/
450 static BOOL samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u,
453 SAMR_R_UNKNOWN_2C r_u;
456 /* find the policy handle. open a policy on it. */
457 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
459 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
462 /* find the user's rid */
463 if ((status == 0x0) && (get_lsa_policy_samr_rid(&(q_u->user_pol)) == 0xffffffff))
465 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
468 init_samr_r_unknown_2c(&r_u, status);
470 DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
472 /* store the response in the SMB stream */
473 if(!samr_io_r_unknown_2c("", &r_u, rdata, 0))
476 DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
481 /*******************************************************************
483 ********************************************************************/
484 static BOOL api_samr_unknown_2c(prs_struct *data, prs_struct *rdata)
486 SAMR_Q_UNKNOWN_2C q_u;
488 /* grab the samr open */
489 if(!samr_io_q_unknown_2c("", &q_u, data, 0))
492 /* construct reply. always indicate success */
493 if(!samr_reply_unknown_2c(&q_u, rdata))
500 /*******************************************************************
502 ********************************************************************/
503 static BOOL samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
506 SAMR_R_UNKNOWN_3 r_u;
507 DOM_SID3 sid[MAX_SAM_SIDS];
513 /* find the policy handle. open a policy on it. */
514 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
516 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
519 /* find the user's rid */
520 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->user_pol))) == 0xffffffff)
522 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
528 DOM_SID everyone_sid;
530 user_sid = global_sam_sid;
532 SMB_ASSERT_ARRAY(user_sid.sub_auths, user_sid.num_auths+1);
537 user_sid.sub_auths[user_sid.num_auths++] = rid;
539 string_to_sid(&everyone_sid, "S-1-1");
541 /* maybe need another 1 or 2 (S-1-5-0x20-0x220 and S-1-5-20-0x224) */
542 /* these two are DOMAIN_ADMIN and DOMAIN_ACCT_OP group RIDs */
543 init_dom_sid3(&(sid[0]), 0x035b, 0x0002, &everyone_sid);
544 init_dom_sid3(&(sid[1]), 0x0044, 0x0002, &user_sid);
547 init_samr_r_unknown_3(&r_u,
549 0x00000014, 0x0002, 0x0070,
552 DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
554 /* store the response in the SMB stream */
555 if(!samr_io_r_unknown_3("", &r_u, rdata, 0))
558 DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
563 /*******************************************************************
565 ********************************************************************/
566 static BOOL api_samr_unknown_3(prs_struct *data, prs_struct *rdata)
568 SAMR_Q_UNKNOWN_3 q_u;
570 /* grab the samr open */
571 if(!samr_io_q_unknown_3("", &q_u, data, 0))
574 /* construct reply. always indicate success */
575 if(!samr_reply_unknown_3(&q_u, rdata))
582 /*******************************************************************
583 samr_reply_enum_dom_users
584 ********************************************************************/
585 static BOOL samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
588 SAMR_R_ENUM_DOM_USERS r_e;
589 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
594 r_e.total_num_entries = 0;
596 /* find the policy handle. open a policy on it. */
597 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
599 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
602 DEBUG(5,("samr_reply_enum_dom_users: %d\n", __LINE__));
605 get_sampwd_entries(pass, 0, &total_entries, &num_entries, MAX_SAM_ENTRIES, q_u->acb_mask);
608 init_samr_r_enum_dom_users(&r_e, total_entries,
609 q_u->unknown_0, num_entries,
612 /* store the response in the SMB stream */
613 if(!samr_io_r_enum_dom_users("", &r_e, rdata, 0))
616 DEBUG(5,("samr_enum_dom_users: %d\n", __LINE__));
621 /*******************************************************************
622 api_samr_enum_dom_users
623 ********************************************************************/
624 static BOOL api_samr_enum_dom_users(prs_struct *data, prs_struct *rdata)
626 SAMR_Q_ENUM_DOM_USERS q_e;
628 /* grab the samr open */
629 if(!samr_io_q_enum_dom_users("", &q_e, data, 0))
632 /* construct reply. */
633 if(!samr_reply_enum_dom_users(&q_e, rdata))
639 /*******************************************************************
640 samr_reply_enum_dom_groups
641 ********************************************************************/
642 static BOOL samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u,
645 SAMR_R_ENUM_DOM_GROUPS r_e;
646 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
649 char *dummy_group = "Domain Admins";
654 /* find the policy handle. open a policy on it. */
655 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
657 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
660 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
664 init_unistr2(&(pass[0].uni_user_name), dummy_group, strlen(dummy_group));
665 pass[0].user_rid = DOMAIN_GROUP_RID_ADMINS;
667 if (r_e.status == 0 && got_grps)
669 init_samr_r_enum_dom_groups(&r_e, q_u->start_idx, num_entries, pass, r_e.status);
672 /* store the response in the SMB stream */
673 if(!samr_io_r_enum_dom_groups("", &r_e, rdata, 0))
676 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
681 /*******************************************************************
682 api_samr_enum_dom_groups
683 ********************************************************************/
684 static BOOL api_samr_enum_dom_groups(prs_struct *data, prs_struct *rdata)
686 SAMR_Q_ENUM_DOM_GROUPS q_e;
688 /* grab the samr open */
689 if(!samr_io_q_enum_dom_groups("", &q_e, data, 0))
692 /* construct reply. */
693 if(!samr_reply_enum_dom_groups(&q_e, rdata))
699 /*******************************************************************
700 samr_reply_enum_dom_aliases
701 ********************************************************************/
702 static BOOL samr_reply_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_u,
705 SAMR_R_ENUM_DOM_ALIASES r_e;
706 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
716 /* find the policy handle. open a policy on it. */
717 if (r_e.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &sid))
719 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
722 sid_to_string(sid_str, &sid);
723 sid_to_string(sam_sid_str, &global_sam_sid);
725 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
727 /* well-known aliases */
728 if (strequal(sid_str, "S-1-5-32"))
731 while (num_entries < MAX_SAM_ENTRIES && ((name = builtin_alias_rids[num_entries].name) != NULL))
733 init_unistr2(&(pass[num_entries].uni_user_name), name, strlen(name));
734 pass[num_entries].user_rid = builtin_alias_rids[num_entries].rid;
738 else if (strequal(sid_str, sam_sid_str))
742 /* we return the UNIX groups here. This seems to be the right */
743 /* thing to do, since NT member servers return their local */
744 /* groups in the same situation. */
747 while (num_entries < MAX_SAM_ENTRIES && ((grp = getgrent()) != NULL))
750 init_unistr2(&(pass[num_entries].uni_user_name), name, strlen(name));
751 pass[num_entries].user_rid = pdb_gid_to_group_rid(grp->gr_gid);
758 init_samr_r_enum_dom_aliases(&r_e, num_entries, pass, r_e.status);
760 /* store the response in the SMB stream */
761 if(!samr_io_r_enum_dom_aliases("", &r_e, rdata, 0))
764 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
769 /*******************************************************************
770 api_samr_enum_dom_aliases
771 ********************************************************************/
772 static BOOL api_samr_enum_dom_aliases(prs_struct *data, prs_struct *rdata)
774 SAMR_Q_ENUM_DOM_ALIASES q_e;
776 /* grab the samr open */
777 if(!samr_io_q_enum_dom_aliases("", &q_e, data, 0))
780 /* construct reply. */
781 if(!samr_reply_enum_dom_aliases(&q_e, rdata))
788 /*******************************************************************
789 samr_reply_query_dispinfo
790 ********************************************************************/
791 static BOOL samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u,
794 SAMR_R_QUERY_DISPINFO r_e;
798 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
800 int total_entries = 0;
802 uint16 switch_level = 0x0;
808 DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
810 /* find the policy handle. open a policy on it. */
811 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
813 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
814 DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n"));
817 if (r_e.status == 0x0)
819 /* decide how many entries to get depending on the max_entries
820 and max_size passed by client */
823 if(q_u->max_entries > MAX_SAM_ENTRIES)
824 q_u->max_entries = MAX_SAM_ENTRIES;
826 retsize = (q_u->max_entries * (sizeof(SAM_ENTRY1)+sizeof(SAM_STR1)))
829 if(retsize > q_u->max_size)
831 /* determine max_entries based on max_size */
832 q_u->max_entries = (q_u->max_size - 3*sizeof(uint32)) /
833 (sizeof(SAM_ENTRY1)+sizeof(SAM_STR1));
834 q_u->max_entries = (q_u->max_entries>0?q_u->max_entries:1);
837 DEBUG(10,("samr_reply_query_dispinfo: Setting q_u->max_entries to %u\n",q_u->max_entries));
840 got_pwds = get_passwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, q_u->max_entries, 0);
843 /* more left - set resume handle */
844 if(total_entries > num_entries)
849 switch (q_u->switch_level)
854 /* query disp info is for users */
856 init_sam_info_1(&info1, ACB_NORMAL,
857 q_u->start_idx, num_entries, pass);
859 ctr.sam.info1 = &info1;
865 /* query disp info is for servers */
867 init_sam_info_2(&info2, ACB_WSTRUST,
868 q_u->start_idx, num_entries, pass);
870 ctr.sam.info2 = &info2;
877 /* more left - set resume handle */
878 if(total_entries > num_entries)
883 if (r_e.status == 0 || r_e.status == 0x105)
885 init_samr_r_query_dispinfo(&r_e, switch_level, &ctr, r_e.status);
888 /* store the response in the SMB stream */
889 if(!samr_io_r_query_dispinfo("", &r_e, rdata, 0))
892 DEBUG(5,("samr_query_dispinfo: %d\n", __LINE__));
897 /*******************************************************************
898 api_samr_query_dispinfo
899 ********************************************************************/
900 static BOOL api_samr_query_dispinfo(prs_struct *data, prs_struct *rdata)
902 SAMR_Q_QUERY_DISPINFO q_e;
904 /* grab the samr open */
905 if(!samr_io_q_query_dispinfo("", &q_e, data, 0))
908 /* construct reply. */
909 if(!samr_reply_query_dispinfo(&q_e, rdata))
916 /*******************************************************************
917 samr_reply_query_aliasinfo
918 ********************************************************************/
919 static BOOL samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
922 SAMR_R_QUERY_ALIASINFO r_e;
923 fstring alias_desc = "Local Unix group";
930 DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__));
932 /* find the policy handle. open a policy on it. */
933 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
935 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
938 alias_rid = get_lsa_policy_samr_rid(&q_u->pol);
939 if(alias_rid == 0xffffffff)
940 r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
942 if(!lookup_local_rid(alias_rid, alias, &type))
944 r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
947 init_samr_r_query_aliasinfo(&r_e, q_u->switch_level, alias, alias_desc);
949 /* store the response in the SMB stream */
950 if(!samr_io_r_query_aliasinfo("", &r_e, rdata, 0))
953 DEBUG(5,("samr_query_aliasinfo: %d\n", __LINE__));
958 /*******************************************************************
959 api_samr_query_aliasinfo
960 ********************************************************************/
961 static BOOL api_samr_query_aliasinfo(prs_struct *data, prs_struct *rdata)
963 SAMR_Q_QUERY_ALIASINFO q_e;
965 /* grab the samr open */
966 if(!samr_io_q_query_aliasinfo("", &q_e, data, 0))
969 /* construct reply. */
970 if(!samr_reply_query_aliasinfo(&q_e, rdata))
977 /*******************************************************************
978 samr_reply_lookup_ids
979 ********************************************************************/
980 static BOOL samr_reply_lookup_ids(SAMR_Q_LOOKUP_IDS *q_u,
983 uint32 rid[MAX_SAM_ENTRIES];
985 int num_rids = q_u->num_sids1;
987 SAMR_R_LOOKUP_IDS r_u;
989 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
991 if (num_rids > MAX_SAM_ENTRIES)
993 num_rids = MAX_SAM_ENTRIES;
994 DEBUG(5,("samr_lookup_ids: truncating entries to %d\n", num_rids));
999 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1001 for (i = 0; i < num_rids && status == 0; i++)
1003 struct sam_passwd *sam_pass;
1007 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1008 q_u->uni_user_name[i].uni_str_len));
1010 /* find the user account */
1012 sam_pass = get_smb21pwd_entry(user_name, 0);
1013 unbecome_root(True);
1015 if (sam_pass == NULL)
1017 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1022 rid[i] = sam_pass->user_rid;
1028 rid[0] = BUILTIN_ALIAS_RID_USERS;
1030 init_samr_r_lookup_ids(&r_u, num_rids, rid, status);
1032 /* store the response in the SMB stream */
1033 if(!samr_io_r_lookup_ids("", &r_u, rdata, 0))
1036 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
1041 /*******************************************************************
1043 ********************************************************************/
1044 static BOOL api_samr_lookup_ids(prs_struct *data, prs_struct *rdata)
1046 SAMR_Q_LOOKUP_IDS q_u;
1048 /* grab the samr 0x10 */
1049 if(!samr_io_q_lookup_ids("", &q_u, data, 0))
1052 /* construct reply. always indicate success */
1053 if(!samr_reply_lookup_ids(&q_u, rdata))
1059 /*******************************************************************
1060 samr_reply_lookup_names
1061 ********************************************************************/
1063 static BOOL samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
1066 uint32 rid[MAX_SAM_ENTRIES];
1067 uint8 type[MAX_SAM_ENTRIES];
1070 int num_rids = q_u->num_names1;
1073 SAMR_R_LOOKUP_NAMES r_u;
1075 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1080 if (!get_lsa_policy_samr_sid(&q_u->pol, &pol_sid)) {
1081 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
1082 init_samr_r_lookup_names(&r_u, 0, rid, type, status);
1083 if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
1084 DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
1090 if (num_rids > MAX_SAM_ENTRIES) {
1091 num_rids = MAX_SAM_ENTRIES;
1092 DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
1095 SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
1097 for (i = 0; i < num_rids; i++) {
1100 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
1102 rid [i] = 0xffffffff;
1103 type[i] = SID_NAME_UNKNOWN;
1105 fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer,
1106 q_u->uni_name[i].uni_str_len));
1108 if(sid_equal(&pol_sid, &global_sam_sid))
1111 if(lookup_local_name(global_myname, name,
1114 sid_split_rid( &sid, &rid[i]);
1120 init_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
1122 /* store the response in the SMB stream */
1123 if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
1124 DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
1128 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1133 /*******************************************************************
1134 api_samr_lookup_names
1135 ********************************************************************/
1137 static BOOL api_samr_lookup_names(prs_struct *data, prs_struct *rdata)
1139 SAMR_Q_LOOKUP_NAMES q_u;
1141 memset(&q_u, '\0', sizeof(q_u));
1143 /* grab the samr lookup names */
1144 if(!samr_io_q_lookup_names("", &q_u, data, 0)) {
1145 DEBUG(0,("api_samr_lookup_names: failed to unmarshall SAMR_Q_LOOKUP_NAMES.\n"));
1149 /* construct reply. always indicate success */
1150 if(!samr_reply_lookup_names(&q_u, rdata))
1156 /*******************************************************************
1157 samr_reply_chgpasswd_user
1158 ********************************************************************/
1160 static BOOL samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
1163 SAMR_R_CHGPASSWD_USER r_u;
1164 uint32 status = 0x0;
1168 fstrcpy(user_name, dos_unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len));
1169 fstrcpy(wks , dos_unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len));
1171 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1173 if (!pass_oem_change(user_name,
1174 q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1175 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1177 status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
1180 init_samr_r_chgpasswd_user(&r_u, status);
1182 /* store the response in the SMB stream */
1183 if(!samr_io_r_chgpasswd_user("", &r_u, rdata, 0)) {
1184 DEBUG(0,("samr_reply_chgpasswd_user: Failed to marshall SAMR_R_CHGPASSWD_USER struct.\n" ));
1188 DEBUG(5,("samr_chgpasswd_user: %d\n", __LINE__));
1192 /*******************************************************************
1193 api_samr_chgpasswd_user
1194 ********************************************************************/
1196 static BOOL api_samr_chgpasswd_user(prs_struct *data, prs_struct *rdata)
1198 SAMR_Q_CHGPASSWD_USER q_u;
1200 /* unknown 38 command */
1201 if (!samr_io_q_chgpasswd_user("", &q_u, data, 0)) {
1202 DEBUG(0,("api_samr_chgpasswd_user: samr_io_q_chgpasswd_user failed to parse RPC packet.\n"));
1206 /* construct reply. */
1207 if(!samr_reply_chgpasswd_user(&q_u, rdata)) {
1208 DEBUG(0,("api_samr_chgpasswd_user: samr_reply_chgpasswd_user failed to create reply packet.\n"));
1216 /*******************************************************************
1217 samr_reply_unknown_38
1218 ********************************************************************/
1219 static BOOL samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u, prs_struct *rdata)
1221 SAMR_R_UNKNOWN_38 r_u;
1223 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1225 init_samr_r_unknown_38(&r_u);
1227 /* store the response in the SMB stream */
1228 if(!samr_io_r_unknown_38("", &r_u, rdata, 0))
1231 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1235 /*******************************************************************
1237 ********************************************************************/
1238 static BOOL api_samr_unknown_38(prs_struct *data, prs_struct *rdata)
1240 SAMR_Q_UNKNOWN_38 q_u;
1242 /* unknown 38 command */
1243 if(!samr_io_q_unknown_38("", &q_u, data, 0))
1246 /* construct reply. always indicate success */
1247 if(!samr_reply_unknown_38(&q_u, rdata))
1254 /*******************************************************************
1255 samr_reply_unknown_12
1256 ********************************************************************/
1257 static BOOL samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
1260 fstring group_names[MAX_SAM_ENTRIES];
1261 uint32 group_attrs[MAX_SAM_ENTRIES];
1263 int num_gids = q_u->num_gids1;
1265 SAMR_R_UNKNOWN_12 r_u;
1267 DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
1269 /* find the policy handle. open a policy on it. */
1270 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1272 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1278 if (num_gids > MAX_SAM_ENTRIES)
1280 num_gids = MAX_SAM_ENTRIES;
1281 DEBUG(5,("samr_unknown_12: truncating entries to %d\n", num_gids));
1284 for (i = 0; i < num_gids && status == 0; i++)
1286 fstrcpy(group_names[i], "dummy group");
1287 group_attrs[i] = 0x2;
1291 init_samr_r_unknown_12(&r_u, num_gids, group_names, group_attrs, status);
1293 /* store the response in the SMB stream */
1294 if(!samr_io_r_unknown_12("", &r_u, rdata, 0))
1297 DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
1302 /*******************************************************************
1304 ********************************************************************/
1305 static BOOL api_samr_unknown_12(prs_struct *data, prs_struct *rdata)
1307 SAMR_Q_UNKNOWN_12 q_u;
1309 /* grab the samr lookup names */
1310 if(!samr_io_q_unknown_12("", &q_u, data, 0))
1313 /* construct reply. always indicate success */
1314 if(!samr_reply_unknown_12(&q_u, rdata))
1321 /*******************************************************************
1322 samr_reply_open_user
1323 ********************************************************************/
1324 static BOOL samr_reply_open_user(SAMR_Q_OPEN_USER *q_u, prs_struct *rdata, int status)
1326 SAMR_R_OPEN_USER r_u;
1327 struct sam_passwd *sam_pass;
1328 BOOL pol_open = False;
1330 /* set up the SAMR open_user response */
1331 memset((char *)r_u.user_pol.data, '\0', POL_HND_SIZE);
1335 /* find the policy handle. open a policy on it. */
1336 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
1338 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1341 /* get a (unique) handle. open a policy on it. */
1342 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.user_pol))))
1344 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1348 sam_pass = getsam21pwrid(q_u->user_rid);
1349 unbecome_root(True);
1351 /* check that the RID exists in our domain. */
1352 if (r_u.status == 0x0 && sam_pass == NULL)
1354 r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1357 /* associate the RID with the (unique) handle. */
1358 if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.user_pol), q_u->user_rid))
1360 /* oh, whoops. don't know what error message to return, here */
1361 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1364 if (r_u.status != 0 && pol_open)
1366 close_lsa_policy_hnd(&(r_u.user_pol));
1369 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1371 /* store the response in the SMB stream */
1372 if(!samr_io_r_open_user("", &r_u, rdata, 0))
1375 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1380 /*******************************************************************
1382 ********************************************************************/
1383 static BOOL api_samr_open_user(prs_struct *data, prs_struct *rdata)
1385 SAMR_Q_OPEN_USER q_u;
1387 /* grab the samr unknown 22 */
1388 if(!samr_io_q_open_user("", &q_u, data, 0))
1391 /* construct reply. always indicate success */
1392 if(!samr_reply_open_user(&q_u, rdata, 0x0))
1399 /*************************************************************************
1401 *************************************************************************/
1402 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1404 struct smb_passwd *smb_pass;
1406 if (!pdb_rid_is_user(user_rid))
1408 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1413 smb_pass = getsmbpwrid(user_rid);
1414 unbecome_root(True);
1416 if (smb_pass == NULL)
1418 DEBUG(4,("User 0x%x not found\n", user_rid));
1422 DEBUG(3,("User:[%s]\n", smb_pass->smb_name));
1424 init_sam_user_info10(id10, smb_pass->acct_ctrl);
1429 /*************************************************************************
1431 *************************************************************************/
1432 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1435 struct sam_passwd *sam_pass;
1439 if (!pdb_rid_is_user(user_rid))
1441 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1446 sam_pass = getsam21pwrid(user_rid);
1447 unbecome_root(True);
1449 if (sam_pass == NULL)
1451 DEBUG(4,("User 0x%x not found\n", user_rid));
1455 DEBUG(3,("User:[%s]\n", sam_pass->smb_name));
1457 dummy_time.low = 0xffffffff;
1458 dummy_time.high = 0x7fffffff;
1460 DEBUG(5,("get_user_info_21 - TODO: convert unix times to NTTIMEs\n"));
1462 /* create a LOGON_HRS structure */
1463 hrs.len = sam_pass->hours_len;
1464 SMB_ASSERT_ARRAY(hrs.hours, hrs.len);
1465 for (i = 0; i < hrs.len; i++)
1467 hrs.hours[i] = sam_pass->hours[i];
1470 init_sam_user_info21(id21,
1472 &dummy_time, /* logon_time */
1473 &dummy_time, /* logoff_time */
1474 &dummy_time, /* kickoff_time */
1475 &dummy_time, /* pass_last_set_time */
1476 &dummy_time, /* pass_can_change_time */
1477 &dummy_time, /* pass_must_change_time */
1479 sam_pass->smb_name, /* user_name */
1480 sam_pass->full_name, /* full_name */
1481 sam_pass->home_dir, /* home_dir */
1482 sam_pass->dir_drive, /* dir_drive */
1483 sam_pass->logon_script, /* logon_script */
1484 sam_pass->profile_path, /* profile_path */
1485 sam_pass->acct_desc, /* description */
1486 sam_pass->workstations, /* workstations user can log in from */
1487 sam_pass->unknown_str, /* don't know, yet */
1488 sam_pass->munged_dial, /* dialin info. contains dialin path and tel no */
1490 sam_pass->user_rid, /* RID user_id */
1491 sam_pass->group_rid, /* RID group_id */
1492 sam_pass->acct_ctrl,
1494 sam_pass->unknown_3, /* unknown_3 */
1495 sam_pass->logon_divs, /* divisions per week */
1496 &hrs, /* logon hours */
1497 sam_pass->unknown_5,
1498 sam_pass->unknown_6);
1503 /*******************************************************************
1504 samr_reply_query_userinfo
1505 ********************************************************************/
1506 static BOOL samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
1509 SAMR_R_QUERY_USERINFO r_u;
1511 SAM_USER_INFO_11 id11;
1513 SAM_USER_INFO_10 id10;
1514 SAM_USER_INFO_21 id21;
1517 uint32 status = 0x0;
1520 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1522 /* search for the handle */
1523 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1525 status = NT_STATUS_INVALID_HANDLE;
1528 /* find the user's rid */
1529 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1531 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1534 DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
1536 /* ok! user info levels (there are lots: see MSDEV help), off we go... */
1539 switch (q_u->switch_value)
1543 info = (void*)&id10;
1544 status = get_user_info_10(&id10, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1548 /* whoops - got this wrong. i think. or don't understand what's happening. */
1552 info = (void*)&id11;
1554 expire.low = 0xffffffff;
1555 expire.high = 0x7fffffff;
1557 make_sam_user_info11(&id11, &expire, "BROOKFIELDS$", 0x03ef, 0x201, 0x0080);
1564 info = (void*)&id21;
1565 status = get_user_info_21(&id21, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1571 status = NT_STATUS_INVALID_INFO_CLASS;
1578 init_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
1580 /* store the response in the SMB stream */
1581 if(!samr_io_r_query_userinfo("", &r_u, rdata, 0))
1584 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1589 /*******************************************************************
1590 api_samr_query_userinfo
1591 ********************************************************************/
1592 static BOOL api_samr_query_userinfo(prs_struct *data, prs_struct *rdata)
1594 SAMR_Q_QUERY_USERINFO q_u;
1596 /* grab the samr unknown 24 */
1597 if(!samr_io_q_query_userinfo("", &q_u, data, 0))
1600 /* construct reply. always indicate success */
1601 if(!samr_reply_query_userinfo(&q_u, rdata))
1608 /*******************************************************************
1609 samr_reply_query_usergroups
1610 ********************************************************************/
1611 static BOOL samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
1614 SAMR_R_QUERY_USERGROUPS r_u;
1615 uint32 status = 0x0;
1617 struct sam_passwd *sam_pass;
1618 DOM_GID *gids = NULL;
1622 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1624 /* find the policy handle. open a policy on it. */
1625 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1627 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1630 /* find the user's rid */
1631 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1633 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1639 sam_pass = getsam21pwrid(rid);
1640 unbecome_root(True);
1642 if (sam_pass == NULL)
1644 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1651 get_domain_user_groups(groups, sam_pass->smb_name);
1653 num_groups = make_dom_gids(groups, &gids);
1656 /* construct the response. lkclXXXX: gids are not copied! */
1657 init_samr_r_query_usergroups(&r_u, num_groups, gids, status);
1659 /* store the response in the SMB stream */
1660 if(!samr_io_r_query_usergroups("", &r_u, rdata, 0)) {
1669 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1674 /*******************************************************************
1675 api_samr_query_usergroups
1676 ********************************************************************/
1677 static BOOL api_samr_query_usergroups(prs_struct *data, prs_struct *rdata)
1679 SAMR_Q_QUERY_USERGROUPS q_u;
1680 /* grab the samr unknown 32 */
1681 if(!samr_io_q_query_usergroups("", &q_u, data, 0))
1684 /* construct reply. */
1685 if(!samr_reply_query_usergroups(&q_u, rdata))
1692 /*******************************************************************
1693 samr_reply_query_dom_info
1694 ********************************************************************/
1695 static BOOL samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_struct *rdata)
1697 SAMR_R_QUERY_DOMAIN_INFO r_u;
1699 uint16 switch_value = 0x0;
1700 uint32 status = 0x0;
1707 DEBUG(5,("samr_reply_query_dom_info: %d\n", __LINE__));
1709 /* find the policy handle. open a policy on it. */
1710 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
1712 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1713 DEBUG(5,("samr_reply_query_dom_info: invalid handle\n"));
1718 switch (q_u->switch_value)
1723 init_unk_info2(&ctr.info.inf2, global_myworkgroup, global_myname);
1729 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
1735 init_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
1737 /* store the response in the SMB stream */
1738 if(!samr_io_r_query_dom_info("", &r_u, rdata, 0))
1741 DEBUG(5,("samr_query_dom_info: %d\n", __LINE__));
1746 /*******************************************************************
1747 api_samr_query_dom_info
1748 ********************************************************************/
1749 static BOOL api_samr_query_dom_info(prs_struct *data, prs_struct *rdata)
1751 SAMR_Q_QUERY_DOMAIN_INFO q_e;
1753 /* grab the samr unknown 8 command */
1754 if(!samr_io_q_query_dom_info("", &q_e, data, 0))
1757 /* construct reply. */
1758 if(!samr_reply_query_dom_info(&q_e, rdata))
1764 /*******************************************************************
1765 samr_reply_unknown_32
1766 ********************************************************************/
1767 static BOOL samr_reply_unknown_32(SAMR_Q_UNKNOWN_32 *q_u,
1772 SAMR_R_UNKNOWN_32 r_u;
1774 /* set up the SAMR unknown_32 response */
1775 memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
1778 for (i = 4; i < POL_HND_SIZE; i++)
1780 r_u.pol.data[i] = i+1;
1784 init_dom_rid4(&(r_u.rid4), 0x0030, 0, 0);
1785 r_u.status = status;
1787 DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
1789 /* store the response in the SMB stream */
1790 if(!samr_io_r_unknown_32("", &r_u, rdata, 0))
1793 DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
1798 /*******************************************************************
1800 ********************************************************************/
1801 static BOOL api_samr_unknown_32(prs_struct *data, prs_struct *rdata)
1804 struct sam_passwd *sam_pass;
1807 SAMR_Q_UNKNOWN_32 q_u;
1809 /* grab the samr unknown 32 */
1810 samr_io_q_unknown_32("", &q_u, data, 0);
1812 /* find the machine account: tell the caller if it exists.
1813 lkclXXXX i have *no* idea if this is a problem or not
1814 or even if you are supposed to construct a different
1815 reply if the account already exists...
1818 fstrcpy(mach_acct, dos_unistrn2(q_u.uni_mach_acct.buffer,
1819 q_u.uni_mach_acct.uni_str_len));
1822 sam_pass = getsam21pwnam(mach_acct);
1823 unbecome_root(True);
1825 if (sam_pass != NULL)
1827 /* machine account exists: say so */
1828 status = 0xC0000000 | NT_STATUS_USER_EXISTS;
1832 /* this could cause trouble... */
1833 DEBUG(0,("trouble!\n"));
1837 /* construct reply. */
1838 if(!samr_reply_unknown_32(&q_u, rdata, status))
1845 /*******************************************************************
1846 samr_reply_connect_anon
1847 ********************************************************************/
1848 static BOOL samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u, prs_struct *rdata)
1850 SAMR_R_CONNECT_ANON r_u;
1851 BOOL pol_open = False;
1853 /* set up the SAMR connect_anon response */
1856 /* get a (unique) handle. open a policy on it. */
1857 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1859 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1862 /* associate the domain SID with the (unique) handle. */
1863 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1865 /* oh, whoops. don't know what error message to return, here */
1866 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1869 if (r_u.status != 0 && pol_open)
1871 close_lsa_policy_hnd(&(r_u.connect_pol));
1874 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1876 /* store the response in the SMB stream */
1877 if(!samr_io_r_connect_anon("", &r_u, rdata, 0))
1880 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1885 /*******************************************************************
1886 api_samr_connect_anon
1887 ********************************************************************/
1888 static BOOL api_samr_connect_anon(prs_struct *data, prs_struct *rdata)
1890 SAMR_Q_CONNECT_ANON q_u;
1892 /* grab the samr open policy */
1893 if(!samr_io_q_connect_anon("", &q_u, data, 0))
1896 /* construct reply. always indicate success */
1897 if(!samr_reply_connect_anon(&q_u, rdata))
1903 /*******************************************************************
1905 ********************************************************************/
1906 static BOOL samr_reply_connect(SAMR_Q_CONNECT *q_u, prs_struct *rdata)
1909 BOOL pol_open = False;
1911 /* set up the SAMR connect response */
1914 /* get a (unique) handle. open a policy on it. */
1915 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1917 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1920 /* associate the domain SID with the (unique) handle. */
1921 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1923 /* oh, whoops. don't know what error message to return, here */
1924 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1927 if (r_u.status != 0 && pol_open)
1929 close_lsa_policy_hnd(&(r_u.connect_pol));
1932 DEBUG(5,("samr_connect: %d\n", __LINE__));
1934 /* store the response in the SMB stream */
1935 if(!samr_io_r_connect("", &r_u, rdata, 0))
1938 DEBUG(5,("samr_connect: %d\n", __LINE__));
1943 /*******************************************************************
1945 ********************************************************************/
1946 static BOOL api_samr_connect(prs_struct *data, prs_struct *rdata)
1950 /* grab the samr open policy */
1951 if(!samr_io_q_connect("", &q_u, data, 0))
1954 /* construct reply. always indicate success */
1955 if(!samr_reply_connect(&q_u, rdata))
1961 /**********************************************************************
1962 api_reply_lookup_domain
1963 **********************************************************************/
1964 static BOOL samr_reply_lookup_domain(SAMR_Q_LOOKUP_DOMAIN* q_u, prs_struct* rdata)
1966 SAMR_R_LOOKUP_DOMAIN r_u;
1969 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->connect_pol)) == -1))
1971 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1972 DEBUG(5,("samr_reply_lookup_domain: invalid handle\n"));
1975 /* assume the domain name sent is our global_myname and
1976 send global_sam_sid */
1977 init_samr_r_lookup_domain(&r_u, &global_sam_sid, r_u.status);
1979 if(!samr_io_r_lookup_domain("", &r_u, rdata, 0))
1982 DEBUG(5,("samr_reply_lookup_domain: %d\n", __LINE__));
1987 /**********************************************************************
1988 api_samr_lookup_domain
1989 **********************************************************************/
1990 static BOOL api_samr_lookup_domain(prs_struct* data, prs_struct* rdata)
1992 SAMR_Q_LOOKUP_DOMAIN q_u;
1994 if(!samr_io_q_lookup_domain("", &q_u, data, 0))
1997 if(!samr_reply_lookup_domain(&q_u, rdata))
2003 /**********************************************************************
2004 samr_reply_enum_domains
2005 **********************************************************************/
2006 static BOOL samr_reply_enum_domains(SAMR_Q_ENUM_DOMAINS* q_u, prs_struct* rdata)
2008 SAMR_R_ENUM_DOMAINS r_u;
2011 fstrcpy(dom[0],global_myname);
2012 fstrcpy(dom[1],"Builtin");
2015 init_samr_r_enum_domains(&r_u, q_u->start_idx, dom, 2);
2016 if(!samr_io_r_enum_domains("", &r_u, rdata, 0)) {
2018 free(r_u.uni_dom_name);
2023 free(r_u.uni_dom_name);
2028 /**********************************************************************
2029 api_samr_enum_domains
2030 **********************************************************************/
2031 static BOOL api_samr_enum_domains(prs_struct* data, prs_struct* rdata)
2033 SAMR_Q_ENUM_DOMAINS q_u;
2035 if(!samr_io_q_enum_domains("", &q_u, data, 0))
2038 if(!samr_reply_enum_domains(&q_u, rdata))
2044 /*******************************************************************
2045 samr_reply_open_alias
2046 ********************************************************************/
2047 static BOOL samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u, prs_struct *rdata)
2049 SAMR_R_OPEN_ALIAS r_u;
2050 BOOL pol_open = False;
2052 /* set up the SAMR open_alias response */
2055 /* get a (unique) handle. open a policy on it. */
2056 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.pol))))
2058 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2061 /* associate a RID with the (unique) handle. */
2062 if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.pol), q_u->rid_alias))
2064 /* oh, whoops. don't know what error message to return, here */
2065 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2068 if (r_u.status != 0 && pol_open)
2070 close_lsa_policy_hnd(&(r_u.pol));
2073 DEBUG(5,("samr_open_alias: %d\n", __LINE__));
2075 /* store the response in the SMB stream */
2076 if(!samr_io_r_open_alias("", &r_u, rdata, 0))
2079 DEBUG(5,("samr_open_alias: %d\n", __LINE__));
2084 /*******************************************************************
2086 ********************************************************************/
2087 static BOOL api_samr_open_alias(prs_struct *data, prs_struct *rdata)
2090 SAMR_Q_OPEN_ALIAS q_u;
2092 /* grab the samr open policy */
2093 if(!samr_io_q_open_alias("", &q_u, data, 0))
2096 /* construct reply. always indicate success */
2097 if(!samr_reply_open_alias(&q_u, rdata))
2103 /*******************************************************************
2104 array of \PIPE\samr operations
2105 ********************************************************************/
2106 static struct api_struct api_samr_cmds [] =
2108 { "SAMR_CLOSE_HND" , SAMR_CLOSE_HND , api_samr_close_hnd },
2109 { "SAMR_CONNECT" , SAMR_CONNECT , api_samr_connect },
2110 { "SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON , api_samr_connect_anon },
2111 { "SAMR_ENUM_DOM_USERS" , SAMR_ENUM_DOM_USERS , api_samr_enum_dom_users },
2112 { "SAMR_ENUM_DOM_GROUPS" , SAMR_ENUM_DOM_GROUPS , api_samr_enum_dom_groups },
2113 { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
2114 { "SAMR_LOOKUP_IDS" , SAMR_LOOKUP_IDS , api_samr_lookup_ids },
2115 { "SAMR_LOOKUP_NAMES" , SAMR_LOOKUP_NAMES , api_samr_lookup_names },
2116 { "SAMR_OPEN_USER" , SAMR_OPEN_USER , api_samr_open_user },
2117 { "SAMR_QUERY_USERINFO" , SAMR_QUERY_USERINFO , api_samr_query_userinfo },
2118 { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
2119 { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
2120 { "SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo },
2121 { "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo },
2122 { "SAMR_0x32" , 0x32 , api_samr_unknown_32 },
2123 { "SAMR_UNKNOWN_12" , SAMR_UNKNOWN_12 , api_samr_unknown_12 },
2124 { "SAMR_UNKNOWN_38" , SAMR_UNKNOWN_38 , api_samr_unknown_38 },
2125 { "SAMR_CHGPASSWD_USER" , SAMR_CHGPASSWD_USER , api_samr_chgpasswd_user },
2126 { "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias },
2127 { "SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain },
2128 { "SAMR_UNKNOWN_3" , SAMR_UNKNOWN_3 , api_samr_unknown_3 },
2129 { "SAMR_UNKNOWN_2C" , SAMR_UNKNOWN_2C , api_samr_unknown_2c },
2130 { "SAMR_LOOKUP_DOMAIN" , SAMR_LOOKUP_DOMAIN , api_samr_lookup_domain },
2131 { "SAMR_ENUM_DOMAINS" , SAMR_ENUM_DOMAINS , api_samr_enum_domains },
2135 /*******************************************************************
2136 receives a samr pipe and responds.
2137 ********************************************************************/
2138 BOOL api_samr_rpc(pipes_struct *p, prs_struct *data)
2140 return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds, data);