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;
205 DEBUG(5, ("get_passwd_entries: retrieving a list of UNIX users\n"));
208 (*total_entries) = 0;
210 if (pw_buf == NULL) return False;
212 if (current_idx == 0) {
216 /* These two cases are inefficient, but should be called very rarely */
217 /* they are the cases where the starting index isn't picking up */
218 /* where we left off last time. It is efficient when it starts over */
219 /* at zero though. */
220 if (start_idx > current_idx) {
221 /* We aren't far enough; advance to start_idx */
222 while (current_idx < start_idx) {
226 if ((pwd = getpwent()) == NULL) break;
231 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
232 (current_idx < start_idx)) {
237 if (unmap_name == NULL) {
242 } else if (start_idx < current_idx) {
243 /* We are already too far; start over and advance to start_idx */
249 while (current_idx < start_idx) {
253 if ((pwd = getpwent()) == NULL) break;
258 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
259 (current_idx < start_idx)) {
264 if (unmap_name == NULL) {
271 sep = lp_winbind_separator();
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;
282 /* Don't enumerate winbind users as they are not local */
284 if (strchr(pwd->pw_name, *sep) != NULL) {
288 user_name_len = strlen(pwd->pw_name);
289 pw_rid = pdb_uid_to_user_rid(pwd->pw_uid);
290 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
291 init_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->pw_name, user_name_len);
292 init_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
293 pw_buf[(*num_entries)].user_rid = pw_rid;
294 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
296 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
298 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
306 /* This does all the user names that map to the UNIX user */
307 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
308 (*num_entries < max_num_entries)) {
309 user_name_len = strlen(unmap_name);
310 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
311 init_unistr2(&(pw_buf[(*num_entries)].uni_user_name), unmap_name, user_name_len);
312 init_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
313 pw_buf[(*num_entries)].user_rid = pw_rid;
314 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
316 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
318 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
326 if (unmap_name == NULL) {
327 /* done with 'aliases', go on to next UNIX user */
334 /* totally done, reset everything */
340 return (*num_entries) > 0;
343 /*******************************************************************
345 ********************************************************************/
346 static BOOL samr_reply_close_hnd(SAMR_Q_CLOSE_HND *q_u,
349 SAMR_R_CLOSE_HND r_u;
351 /* set up the SAMR unknown_1 response */
352 memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
354 /* close the policy handle */
355 if (close_lsa_policy_hnd(&(q_u->pol)))
361 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_INVALID;
364 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
366 /* store the response in the SMB stream */
367 if(!samr_io_r_close_hnd("", &r_u, rdata, 0))
370 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
375 /*******************************************************************
377 ********************************************************************/
378 static BOOL api_samr_close_hnd(pipes_struct *p)
380 SAMR_Q_CLOSE_HND q_u;
381 prs_struct *data = &p->in_data.data;
382 prs_struct *rdata = &p->out_data.rdata;
384 /* grab the samr unknown 1 */
385 if(!samr_io_q_close_hnd("", &q_u, data, 0))
388 /* construct reply. always indicate success */
389 if(!samr_reply_close_hnd(&q_u, rdata))
396 /*******************************************************************
397 samr_reply_open_domain
398 ********************************************************************/
399 static BOOL samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
402 SAMR_R_OPEN_DOMAIN r_u;
403 BOOL pol_open = False;
407 /* find the connection policy handle. */
408 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->connect_pol)) == -1))
410 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
413 /* get a (unique) handle. open a policy on it. */
414 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.domain_pol))))
416 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
419 /* associate the domain SID with the (unique) handle. */
420 if (r_u.status == 0x0 && !set_lsa_policy_samr_sid(&(r_u.domain_pol), &(q_u->dom_sid.sid)))
422 /* oh, whoops. don't know what error message to return, here */
423 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
426 if (r_u.status != 0 && pol_open)
428 close_lsa_policy_hnd(&(r_u.domain_pol));
431 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
433 /* store the response in the SMB stream */
434 if(!samr_io_r_open_domain("", &r_u, rdata, 0))
437 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
442 /*******************************************************************
444 ********************************************************************/
445 static BOOL api_samr_open_domain(pipes_struct *p)
447 SAMR_Q_OPEN_DOMAIN q_u;
448 prs_struct *data = &p->in_data.data;
449 prs_struct *rdata = &p->out_data.rdata;
451 /* grab the samr open */
452 if(!samr_io_q_open_domain("", &q_u, data, 0))
455 /* construct reply. always indicate success */
456 if(!samr_reply_open_domain(&q_u, rdata))
463 /*******************************************************************
464 samr_reply_unknown_2c
465 ********************************************************************/
466 static BOOL samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u,
469 SAMR_R_UNKNOWN_2C r_u;
472 /* find the policy handle. open a policy on it. */
473 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
475 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
478 /* find the user's rid */
479 if ((status == 0x0) && (get_lsa_policy_samr_rid(&(q_u->user_pol)) == 0xffffffff))
481 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
484 init_samr_r_unknown_2c(&r_u, status);
486 DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
488 /* store the response in the SMB stream */
489 if(!samr_io_r_unknown_2c("", &r_u, rdata, 0))
492 DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
497 /*******************************************************************
499 ********************************************************************/
500 static BOOL api_samr_unknown_2c(pipes_struct *p)
502 SAMR_Q_UNKNOWN_2C q_u;
503 prs_struct *data = &p->in_data.data;
504 prs_struct *rdata = &p->out_data.rdata;
506 /* grab the samr open */
507 if(!samr_io_q_unknown_2c("", &q_u, data, 0))
510 /* construct reply. always indicate success */
511 if(!samr_reply_unknown_2c(&q_u, rdata))
518 /*******************************************************************
520 ********************************************************************/
521 static BOOL samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
524 SAMR_R_UNKNOWN_3 r_u;
525 DOM_SID3 sid[MAX_SAM_SIDS];
531 /* find the policy handle. open a policy on it. */
532 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
534 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
537 /* find the user's rid */
538 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->user_pol))) == 0xffffffff)
540 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
546 DOM_SID everyone_sid;
548 user_sid = global_sam_sid;
550 SMB_ASSERT_ARRAY(user_sid.sub_auths, user_sid.num_auths+1);
555 user_sid.sub_auths[user_sid.num_auths++] = rid;
557 string_to_sid(&everyone_sid, "S-1-1");
559 /* maybe need another 1 or 2 (S-1-5-0x20-0x220 and S-1-5-20-0x224) */
560 /* these two are DOMAIN_ADMIN and DOMAIN_ACCT_OP group RIDs */
561 init_dom_sid3(&(sid[0]), 0x035b, 0x0002, &everyone_sid);
562 init_dom_sid3(&(sid[1]), 0x0044, 0x0002, &user_sid);
565 init_samr_r_unknown_3(&r_u,
567 0x00000014, 0x0002, 0x0070,
570 DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
572 /* store the response in the SMB stream */
573 if(!samr_io_r_unknown_3("", &r_u, rdata, 0))
576 DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
581 /*******************************************************************
583 ********************************************************************/
584 static BOOL api_samr_unknown_3(pipes_struct *p)
586 SAMR_Q_UNKNOWN_3 q_u;
587 prs_struct *data = &p->in_data.data;
588 prs_struct *rdata = &p->out_data.rdata;
590 /* grab the samr open */
591 if(!samr_io_q_unknown_3("", &q_u, data, 0))
594 /* construct reply. always indicate success */
595 if(!samr_reply_unknown_3(&q_u, rdata))
602 /*******************************************************************
603 samr_reply_enum_dom_users
604 ********************************************************************/
605 static BOOL samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
608 SAMR_R_ENUM_DOM_USERS r_e;
609 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
614 r_e.total_num_entries = 0;
616 /* find the policy handle. open a policy on it. */
617 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
619 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
622 DEBUG(5,("samr_reply_enum_dom_users: %d\n", __LINE__));
625 get_sampwd_entries(pass, 0, &total_entries, &num_entries, MAX_SAM_ENTRIES, q_u->acb_mask);
628 init_samr_r_enum_dom_users(&r_e, total_entries,
629 q_u->unknown_0, num_entries,
632 /* store the response in the SMB stream */
633 if(!samr_io_r_enum_dom_users("", &r_e, rdata, 0))
636 DEBUG(5,("samr_enum_dom_users: %d\n", __LINE__));
641 /*******************************************************************
642 api_samr_enum_dom_users
643 ********************************************************************/
644 static BOOL api_samr_enum_dom_users(pipes_struct *p)
646 SAMR_Q_ENUM_DOM_USERS q_e;
647 prs_struct *data = &p->in_data.data;
648 prs_struct *rdata = &p->out_data.rdata;
650 /* grab the samr open */
651 if(!samr_io_q_enum_dom_users("", &q_e, data, 0))
654 /* construct reply. */
655 if(!samr_reply_enum_dom_users(&q_e, rdata))
661 /*******************************************************************
662 samr_reply_enum_dom_groups
663 ********************************************************************/
664 static BOOL samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u,
667 SAMR_R_ENUM_DOM_GROUPS r_e;
668 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
671 char *dummy_group = "Domain Admins";
676 /* find the policy handle. open a policy on it. */
677 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
679 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
682 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
686 ZERO_STRUCTP(&pass[0]);
687 init_unistr2(&(pass[0].uni_user_name), dummy_group, strlen(dummy_group));
688 pass[0].user_rid = DOMAIN_GROUP_RID_ADMINS;
690 if (r_e.status == 0 && got_grps)
692 init_samr_r_enum_dom_groups(&r_e, q_u->start_idx, num_entries, pass, r_e.status);
695 /* store the response in the SMB stream */
696 if(!samr_io_r_enum_dom_groups("", &r_e, rdata, 0))
699 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
704 /*******************************************************************
705 api_samr_enum_dom_groups
706 ********************************************************************/
707 static BOOL api_samr_enum_dom_groups(pipes_struct *p)
709 SAMR_Q_ENUM_DOM_GROUPS q_e;
710 prs_struct *data = &p->in_data.data;
711 prs_struct *rdata = &p->out_data.rdata;
713 /* grab the samr open */
714 if(!samr_io_q_enum_dom_groups("", &q_e, data, 0))
717 /* construct reply. */
718 if(!samr_reply_enum_dom_groups(&q_e, rdata))
724 /*******************************************************************
725 samr_reply_enum_dom_aliases
726 ********************************************************************/
727 static BOOL samr_reply_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_u,
730 SAMR_R_ENUM_DOM_ALIASES r_e;
731 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
741 /* find the policy handle. open a policy on it. */
742 if (r_e.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &sid))
744 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
747 sid_to_string(sid_str, &sid);
748 sid_to_string(sam_sid_str, &global_sam_sid);
750 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
752 /* well-known aliases */
753 if (strequal(sid_str, "S-1-5-32"))
756 while (num_entries < MAX_SAM_ENTRIES && ((name = builtin_alias_rids[num_entries].name) != NULL))
758 init_unistr2(&(pass[num_entries].uni_user_name), name, strlen(name));
759 pass[num_entries].user_rid = builtin_alias_rids[num_entries].rid;
763 else if (strequal(sid_str, sam_sid_str))
768 sep = lp_winbind_separator();
771 /* we return the UNIX groups here. This seems to be the right */
772 /* thing to do, since NT member servers return their local */
773 /* groups in the same situation. */
776 while (num_entries < MAX_SAM_ENTRIES && ((grp = getgrent()) != NULL))
780 /* Don't return winbind groups as they are not local! */
782 if (strchr(name, *sep) != NULL) {
786 init_unistr2(&(pass[num_entries].uni_user_name), name, strlen(name));
787 pass[num_entries].user_rid = pdb_gid_to_group_rid(grp->gr_gid);
794 init_samr_r_enum_dom_aliases(&r_e, num_entries, pass, r_e.status);
796 /* store the response in the SMB stream */
797 if(!samr_io_r_enum_dom_aliases("", &r_e, rdata, 0))
800 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
805 /*******************************************************************
806 api_samr_enum_dom_aliases
807 ********************************************************************/
808 static BOOL api_samr_enum_dom_aliases(pipes_struct *p)
810 SAMR_Q_ENUM_DOM_ALIASES q_e;
811 prs_struct *data = &p->in_data.data;
812 prs_struct *rdata = &p->out_data.rdata;
814 /* grab the samr open */
815 if(!samr_io_q_enum_dom_aliases("", &q_e, data, 0))
818 /* construct reply. */
819 if(!samr_reply_enum_dom_aliases(&q_e, rdata))
826 /*******************************************************************
827 samr_reply_query_dispinfo
828 ********************************************************************/
829 static BOOL samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u, prs_struct *rdata)
831 SAMR_R_QUERY_DISPINFO r_e;
835 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
837 int total_entries = 0;
839 uint16 switch_level = 0x0;
845 DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
847 /* find the policy handle. open a policy on it. */
848 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
850 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
851 DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n"));
854 if (r_e.status == 0x0)
856 /* decide how many entries to get depending on the max_entries
857 and max_size passed by client */
860 if(q_u->max_entries > MAX_SAM_ENTRIES)
861 q_u->max_entries = MAX_SAM_ENTRIES;
863 retsize = (q_u->max_entries * (sizeof(SAM_ENTRY1)+sizeof(SAM_STR1)))
866 if(retsize > q_u->max_size)
868 /* determine max_entries based on max_size */
869 q_u->max_entries = (q_u->max_size - 3*sizeof(uint32)) /
870 (sizeof(SAM_ENTRY1)+sizeof(SAM_STR1));
871 q_u->max_entries = (q_u->max_entries>0?q_u->max_entries:1);
874 DEBUG(10,("samr_reply_query_dispinfo: Setting q_u->max_entries to %u\n",q_u->max_entries));
877 got_pwds = get_passwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, q_u->max_entries, 0);
880 /* more left - set resume handle */
881 if(total_entries > num_entries)
886 switch (q_u->switch_level)
891 /* query disp info is for users */
893 init_sam_info_1(&info1, ACB_NORMAL,
894 q_u->start_idx, num_entries, pass);
896 ctr.sam.info1 = &info1;
902 /* query disp info is for servers */
904 init_sam_info_2(&info2, ACB_WSTRUST,
905 q_u->start_idx, num_entries, pass);
907 ctr.sam.info2 = &info2;
914 /* more left - set resume handle */
915 if(total_entries > num_entries)
920 if (r_e.status == 0 || r_e.status == 0x105)
922 init_samr_r_query_dispinfo(&r_e, switch_level, &ctr, r_e.status);
925 /* store the response in the SMB stream */
926 if(!samr_io_r_query_dispinfo("", &r_e, rdata, 0))
929 DEBUG(5,("samr_query_dispinfo: %d\n", __LINE__));
934 /*******************************************************************
935 api_samr_query_dispinfo
936 ********************************************************************/
937 static BOOL api_samr_query_dispinfo(pipes_struct *p)
939 SAMR_Q_QUERY_DISPINFO q_e;
940 prs_struct *data = &p->in_data.data;
941 prs_struct *rdata = &p->out_data.rdata;
943 /* grab the samr open */
944 if(!samr_io_q_query_dispinfo("", &q_e, data, 0))
947 /* construct reply. */
948 if(!samr_reply_query_dispinfo(&q_e, rdata))
955 /*******************************************************************
956 samr_reply_query_aliasinfo
957 ********************************************************************/
958 static BOOL samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
961 SAMR_R_QUERY_ALIASINFO r_e;
962 fstring alias_desc = "Local Unix group";
969 DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__));
971 /* find the policy handle. open a policy on it. */
972 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
974 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
977 alias_rid = get_lsa_policy_samr_rid(&q_u->pol);
978 if(alias_rid == 0xffffffff)
979 r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
981 if(!lookup_local_rid(alias_rid, alias, &type))
983 r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
986 init_samr_r_query_aliasinfo(&r_e, q_u->switch_level, alias, alias_desc);
988 /* store the response in the SMB stream */
989 if(!samr_io_r_query_aliasinfo("", &r_e, rdata, 0))
992 DEBUG(5,("samr_query_aliasinfo: %d\n", __LINE__));
997 /*******************************************************************
998 api_samr_query_aliasinfo
999 ********************************************************************/
1000 static BOOL api_samr_query_aliasinfo(pipes_struct *p)
1002 SAMR_Q_QUERY_ALIASINFO q_e;
1003 prs_struct *data = &p->in_data.data;
1004 prs_struct *rdata = &p->out_data.rdata;
1006 /* grab the samr open */
1007 if(!samr_io_q_query_aliasinfo("", &q_e, data, 0))
1010 /* construct reply. */
1011 if(!samr_reply_query_aliasinfo(&q_e, rdata))
1018 /*******************************************************************
1019 samr_reply_lookup_ids
1020 ********************************************************************/
1021 static BOOL samr_reply_lookup_ids(SAMR_Q_LOOKUP_IDS *q_u,
1024 uint32 rid[MAX_SAM_ENTRIES];
1026 int num_rids = q_u->num_sids1;
1028 SAMR_R_LOOKUP_IDS r_u;
1030 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
1032 if (num_rids > MAX_SAM_ENTRIES)
1034 num_rids = MAX_SAM_ENTRIES;
1035 DEBUG(5,("samr_lookup_ids: truncating entries to %d\n", num_rids));
1040 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1042 for (i = 0; i < num_rids && status == 0; i++)
1044 struct sam_passwd *sam_pass;
1048 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1049 q_u->uni_user_name[i].uni_str_len));
1051 /* find the user account */
1053 sam_pass = get_smb21pwd_entry(user_name, 0);
1056 if (sam_pass == NULL)
1058 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1063 rid[i] = sam_pass->user_rid;
1069 rid[0] = BUILTIN_ALIAS_RID_USERS;
1071 init_samr_r_lookup_ids(&r_u, num_rids, rid, status);
1073 /* store the response in the SMB stream */
1074 if(!samr_io_r_lookup_ids("", &r_u, rdata, 0))
1077 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
1082 /*******************************************************************
1084 ********************************************************************/
1085 static BOOL api_samr_lookup_ids(pipes_struct *p)
1087 SAMR_Q_LOOKUP_IDS q_u;
1088 prs_struct *data = &p->in_data.data;
1089 prs_struct *rdata = &p->out_data.rdata;
1091 /* grab the samr 0x10 */
1092 if(!samr_io_q_lookup_ids("", &q_u, data, 0))
1095 /* construct reply. always indicate success */
1096 if(!samr_reply_lookup_ids(&q_u, rdata))
1102 /*******************************************************************
1103 samr_reply_lookup_names
1104 ********************************************************************/
1106 static BOOL samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
1109 uint32 rid[MAX_SAM_ENTRIES];
1110 uint8 type[MAX_SAM_ENTRIES];
1113 int num_rids = q_u->num_names1;
1116 SAMR_R_LOOKUP_NAMES r_u;
1118 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1123 if (!get_lsa_policy_samr_sid(&q_u->pol, &pol_sid)) {
1124 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
1125 init_samr_r_lookup_names(&r_u, 0, rid, type, status);
1126 if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
1127 DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
1133 if (num_rids > MAX_SAM_ENTRIES) {
1134 num_rids = MAX_SAM_ENTRIES;
1135 DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
1138 SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
1140 for (i = 0; i < num_rids; i++) {
1143 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
1145 rid [i] = 0xffffffff;
1146 type[i] = SID_NAME_UNKNOWN;
1148 fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer,
1149 q_u->uni_name[i].uni_str_len));
1151 if(sid_equal(&pol_sid, &global_sam_sid))
1154 if(lookup_local_name(global_myname, name,
1157 sid_split_rid( &sid, &rid[i]);
1163 init_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
1165 /* store the response in the SMB stream */
1166 if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
1167 DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
1171 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1176 /*******************************************************************
1177 api_samr_lookup_names
1178 ********************************************************************/
1180 static BOOL api_samr_lookup_names(pipes_struct *p)
1182 SAMR_Q_LOOKUP_NAMES q_u;
1183 prs_struct *data = &p->in_data.data;
1184 prs_struct *rdata = &p->out_data.rdata;
1186 memset(&q_u, '\0', sizeof(q_u));
1188 /* grab the samr lookup names */
1189 if(!samr_io_q_lookup_names("", &q_u, data, 0)) {
1190 DEBUG(0,("api_samr_lookup_names: failed to unmarshall SAMR_Q_LOOKUP_NAMES.\n"));
1194 /* construct reply. always indicate success */
1195 if(!samr_reply_lookup_names(&q_u, rdata))
1201 /*******************************************************************
1202 samr_reply_chgpasswd_user
1203 ********************************************************************/
1205 static BOOL samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
1208 SAMR_R_CHGPASSWD_USER r_u;
1209 uint32 status = 0x0;
1213 fstrcpy(user_name, dos_unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len));
1214 fstrcpy(wks , dos_unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len));
1216 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1218 if (!pass_oem_change(user_name,
1219 q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1220 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1222 status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
1225 init_samr_r_chgpasswd_user(&r_u, status);
1227 /* store the response in the SMB stream */
1228 if(!samr_io_r_chgpasswd_user("", &r_u, rdata, 0)) {
1229 DEBUG(0,("samr_reply_chgpasswd_user: Failed to marshall SAMR_R_CHGPASSWD_USER struct.\n" ));
1233 DEBUG(5,("samr_chgpasswd_user: %d\n", __LINE__));
1237 /*******************************************************************
1238 api_samr_chgpasswd_user
1239 ********************************************************************/
1241 static BOOL api_samr_chgpasswd_user(pipes_struct *p)
1243 SAMR_Q_CHGPASSWD_USER q_u;
1244 prs_struct *data = &p->in_data.data;
1245 prs_struct *rdata = &p->out_data.rdata;
1247 /* unknown 38 command */
1248 if (!samr_io_q_chgpasswd_user("", &q_u, data, 0)) {
1249 DEBUG(0,("api_samr_chgpasswd_user: samr_io_q_chgpasswd_user failed to parse RPC packet.\n"));
1253 /* construct reply. */
1254 if(!samr_reply_chgpasswd_user(&q_u, rdata)) {
1255 DEBUG(0,("api_samr_chgpasswd_user: samr_reply_chgpasswd_user failed to create reply packet.\n"));
1263 /*******************************************************************
1264 samr_reply_unknown_38
1265 ********************************************************************/
1266 static BOOL samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u, prs_struct *rdata)
1268 SAMR_R_UNKNOWN_38 r_u;
1270 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1272 init_samr_r_unknown_38(&r_u);
1274 /* store the response in the SMB stream */
1275 if(!samr_io_r_unknown_38("", &r_u, rdata, 0))
1278 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1282 /*******************************************************************
1284 ********************************************************************/
1285 static BOOL api_samr_unknown_38(pipes_struct *p)
1287 SAMR_Q_UNKNOWN_38 q_u;
1288 prs_struct *data = &p->in_data.data;
1289 prs_struct *rdata = &p->out_data.rdata;
1291 /* unknown 38 command */
1292 if(!samr_io_q_unknown_38("", &q_u, data, 0))
1295 /* construct reply. always indicate success */
1296 if(!samr_reply_unknown_38(&q_u, rdata))
1303 /*******************************************************************
1304 samr_reply_unknown_12
1305 ********************************************************************/
1306 static BOOL samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
1309 fstring group_names[MAX_SAM_ENTRIES];
1310 uint32 group_attrs[MAX_SAM_ENTRIES];
1312 int num_gids = q_u->num_gids1;
1314 SAMR_R_UNKNOWN_12 r_u;
1316 DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
1318 /* find the policy handle. open a policy on it. */
1319 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1321 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1327 if (num_gids > MAX_SAM_ENTRIES)
1329 num_gids = MAX_SAM_ENTRIES;
1330 DEBUG(5,("samr_unknown_12: truncating entries to %d\n", num_gids));
1333 for (i = 0; i < num_gids && status == 0; i++)
1335 fstrcpy(group_names[i], "dummy group");
1336 group_attrs[i] = 0x2;
1340 init_samr_r_unknown_12(&r_u, num_gids, group_names, group_attrs, status);
1342 /* store the response in the SMB stream */
1343 if(!samr_io_r_unknown_12("", &r_u, rdata, 0))
1346 DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
1351 /*******************************************************************
1353 ********************************************************************/
1354 static BOOL api_samr_unknown_12(pipes_struct *p)
1356 SAMR_Q_UNKNOWN_12 q_u;
1357 prs_struct *data = &p->in_data.data;
1358 prs_struct *rdata = &p->out_data.rdata;
1360 /* grab the samr lookup names */
1361 if(!samr_io_q_unknown_12("", &q_u, data, 0))
1364 /* construct reply. always indicate success */
1365 if(!samr_reply_unknown_12(&q_u, rdata))
1372 /*******************************************************************
1373 samr_reply_open_user
1374 ********************************************************************/
1375 static BOOL samr_reply_open_user(SAMR_Q_OPEN_USER *q_u, prs_struct *rdata, int status)
1377 SAMR_R_OPEN_USER r_u;
1378 struct sam_passwd *sam_pass;
1379 BOOL pol_open = False;
1381 /* set up the SAMR open_user response */
1382 memset((char *)r_u.user_pol.data, '\0', POL_HND_SIZE);
1386 /* find the policy handle. open a policy on it. */
1387 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
1389 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1392 /* get a (unique) handle. open a policy on it. */
1393 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.user_pol))))
1395 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1399 sam_pass = getsam21pwrid(q_u->user_rid);
1402 /* check that the RID exists in our domain. */
1403 if (r_u.status == 0x0 && sam_pass == NULL)
1405 r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1408 /* associate the RID with the (unique) handle. */
1409 if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.user_pol), q_u->user_rid))
1411 /* oh, whoops. don't know what error message to return, here */
1412 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1415 if (r_u.status != 0 && pol_open)
1417 close_lsa_policy_hnd(&(r_u.user_pol));
1420 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1422 /* store the response in the SMB stream */
1423 if(!samr_io_r_open_user("", &r_u, rdata, 0))
1426 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1431 /*******************************************************************
1433 ********************************************************************/
1434 static BOOL api_samr_open_user(pipes_struct *p)
1436 SAMR_Q_OPEN_USER q_u;
1437 prs_struct *data = &p->in_data.data;
1438 prs_struct *rdata = &p->out_data.rdata;
1440 /* grab the samr unknown 22 */
1441 if(!samr_io_q_open_user("", &q_u, data, 0))
1444 /* construct reply. always indicate success */
1445 if(!samr_reply_open_user(&q_u, rdata, 0x0))
1452 /*************************************************************************
1454 *************************************************************************/
1455 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1457 struct smb_passwd *smb_pass;
1459 if (!pdb_rid_is_user(user_rid))
1461 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1466 smb_pass = getsmbpwrid(user_rid);
1469 if (smb_pass == NULL)
1471 DEBUG(4,("User 0x%x not found\n", user_rid));
1475 DEBUG(3,("User:[%s]\n", smb_pass->smb_name));
1477 init_sam_user_info10(id10, smb_pass->acct_ctrl);
1482 /*************************************************************************
1484 *************************************************************************/
1485 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1488 struct sam_passwd *sam_pass;
1492 if (!pdb_rid_is_user(user_rid))
1494 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1499 sam_pass = getsam21pwrid(user_rid);
1502 if (sam_pass == NULL)
1504 DEBUG(4,("User 0x%x not found\n", user_rid));
1508 DEBUG(3,("User:[%s]\n", sam_pass->smb_name));
1510 dummy_time.low = 0xffffffff;
1511 dummy_time.high = 0x7fffffff;
1513 DEBUG(5,("get_user_info_21 - TODO: convert unix times to NTTIMEs\n"));
1515 /* create a LOGON_HRS structure */
1516 hrs.len = sam_pass->hours_len;
1517 SMB_ASSERT_ARRAY(hrs.hours, hrs.len);
1518 for (i = 0; i < hrs.len; i++)
1520 hrs.hours[i] = sam_pass->hours[i];
1523 init_sam_user_info21(id21,
1525 &dummy_time, /* logon_time */
1526 &dummy_time, /* logoff_time */
1527 &dummy_time, /* kickoff_time */
1528 &dummy_time, /* pass_last_set_time */
1529 &dummy_time, /* pass_can_change_time */
1530 &dummy_time, /* pass_must_change_time */
1532 sam_pass->smb_name, /* user_name */
1533 sam_pass->full_name, /* full_name */
1534 sam_pass->home_dir, /* home_dir */
1535 sam_pass->dir_drive, /* dir_drive */
1536 sam_pass->logon_script, /* logon_script */
1537 sam_pass->profile_path, /* profile_path */
1538 sam_pass->acct_desc, /* description */
1539 sam_pass->workstations, /* workstations user can log in from */
1540 sam_pass->unknown_str, /* don't know, yet */
1541 sam_pass->munged_dial, /* dialin info. contains dialin path and tel no */
1543 sam_pass->user_rid, /* RID user_id */
1544 sam_pass->group_rid, /* RID group_id */
1545 sam_pass->acct_ctrl,
1547 sam_pass->unknown_3, /* unknown_3 */
1548 sam_pass->logon_divs, /* divisions per week */
1549 &hrs, /* logon hours */
1550 sam_pass->unknown_5,
1551 sam_pass->unknown_6);
1556 /*******************************************************************
1557 samr_reply_query_userinfo
1558 ********************************************************************/
1559 static BOOL samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
1562 SAMR_R_QUERY_USERINFO r_u;
1564 SAM_USER_INFO_11 id11;
1566 SAM_USER_INFO_10 id10;
1567 SAM_USER_INFO_21 id21;
1570 uint32 status = 0x0;
1573 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1575 /* search for the handle */
1576 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1578 status = NT_STATUS_INVALID_HANDLE;
1581 /* find the user's rid */
1582 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1584 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1587 DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
1589 /* ok! user info levels (there are lots: see MSDEV help), off we go... */
1592 switch (q_u->switch_value)
1596 info = (void*)&id10;
1597 status = get_user_info_10(&id10, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1601 /* whoops - got this wrong. i think. or don't understand what's happening. */
1605 info = (void*)&id11;
1607 expire.low = 0xffffffff;
1608 expire.high = 0x7fffffff;
1610 make_sam_user_info11(&id11, &expire, "BROOKFIELDS$", 0x03ef, 0x201, 0x0080);
1617 info = (void*)&id21;
1618 status = get_user_info_21(&id21, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1624 status = NT_STATUS_INVALID_INFO_CLASS;
1631 init_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
1633 /* store the response in the SMB stream */
1634 if(!samr_io_r_query_userinfo("", &r_u, rdata, 0))
1637 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1642 /*******************************************************************
1643 api_samr_query_userinfo
1644 ********************************************************************/
1645 static BOOL api_samr_query_userinfo(pipes_struct *p)
1647 SAMR_Q_QUERY_USERINFO q_u;
1648 prs_struct *data = &p->in_data.data;
1649 prs_struct *rdata = &p->out_data.rdata;
1651 /* grab the samr unknown 24 */
1652 if(!samr_io_q_query_userinfo("", &q_u, data, 0))
1655 /* construct reply. always indicate success */
1656 if(!samr_reply_query_userinfo(&q_u, rdata))
1663 /*******************************************************************
1664 samr_reply_query_usergroups
1665 ********************************************************************/
1666 static BOOL samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
1669 SAMR_R_QUERY_USERGROUPS r_u;
1670 uint32 status = 0x0;
1672 struct sam_passwd *sam_pass;
1673 DOM_GID *gids = NULL;
1677 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1679 /* find the policy handle. open a policy on it. */
1680 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1682 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1685 /* find the user's rid */
1686 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1688 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1694 sam_pass = getsam21pwrid(rid);
1697 if (sam_pass == NULL)
1699 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1706 get_domain_user_groups(groups, sam_pass->smb_name);
1708 num_groups = make_dom_gids(groups, &gids);
1711 /* construct the response. lkclXXXX: gids are not copied! */
1712 init_samr_r_query_usergroups(&r_u, num_groups, gids, status);
1714 /* store the response in the SMB stream */
1715 if(!samr_io_r_query_usergroups("", &r_u, rdata, 0)) {
1724 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1729 /*******************************************************************
1730 api_samr_query_usergroups
1731 ********************************************************************/
1732 static BOOL api_samr_query_usergroups(pipes_struct *p)
1734 SAMR_Q_QUERY_USERGROUPS q_u;
1735 prs_struct *data = &p->in_data.data;
1736 prs_struct *rdata = &p->out_data.rdata;
1738 /* grab the samr unknown 32 */
1739 if(!samr_io_q_query_usergroups("", &q_u, data, 0))
1742 /* construct reply. */
1743 if(!samr_reply_query_usergroups(&q_u, rdata))
1750 /*******************************************************************
1751 samr_reply_query_dom_info
1752 ********************************************************************/
1753 static BOOL samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_struct *rdata)
1755 SAMR_R_QUERY_DOMAIN_INFO r_u;
1757 uint16 switch_value = 0x0;
1758 uint32 status = 0x0;
1765 DEBUG(5,("samr_reply_query_dom_info: %d\n", __LINE__));
1767 /* find the policy handle. open a policy on it. */
1768 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
1770 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1771 DEBUG(5,("samr_reply_query_dom_info: invalid handle\n"));
1776 switch (q_u->switch_value)
1781 init_unk_info2(&ctr.info.inf2, global_myworkgroup, global_myname);
1787 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
1793 init_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
1795 /* store the response in the SMB stream */
1796 if(!samr_io_r_query_dom_info("", &r_u, rdata, 0))
1799 DEBUG(5,("samr_query_dom_info: %d\n", __LINE__));
1804 /*******************************************************************
1805 api_samr_query_dom_info
1806 ********************************************************************/
1807 static BOOL api_samr_query_dom_info(pipes_struct *p)
1809 SAMR_Q_QUERY_DOMAIN_INFO q_e;
1810 prs_struct *data = &p->in_data.data;
1811 prs_struct *rdata = &p->out_data.rdata;
1813 /* grab the samr unknown 8 command */
1814 if(!samr_io_q_query_dom_info("", &q_e, data, 0))
1817 /* construct reply. */
1818 if(!samr_reply_query_dom_info(&q_e, rdata))
1824 /*******************************************************************
1825 samr_reply_unknown_32
1826 ********************************************************************/
1827 static BOOL samr_reply_unknown_32(SAMR_Q_UNKNOWN_32 *q_u,
1832 SAMR_R_UNKNOWN_32 r_u;
1834 /* set up the SAMR unknown_32 response */
1835 memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
1838 for (i = 4; i < POL_HND_SIZE; i++)
1840 r_u.pol.data[i] = i+1;
1844 init_dom_rid4(&(r_u.rid4), 0x0030, 0, 0);
1845 r_u.status = status;
1847 DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
1849 /* store the response in the SMB stream */
1850 if(!samr_io_r_unknown_32("", &r_u, rdata, 0))
1853 DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
1858 /*******************************************************************
1860 ********************************************************************/
1861 static BOOL api_samr_unknown_32(pipes_struct *p)
1864 struct sam_passwd *sam_pass;
1866 prs_struct *data = &p->in_data.data;
1867 prs_struct *rdata = &p->out_data.rdata;
1869 SAMR_Q_UNKNOWN_32 q_u;
1871 /* grab the samr unknown 32 */
1872 samr_io_q_unknown_32("", &q_u, data, 0);
1874 /* find the machine account: tell the caller if it exists.
1875 lkclXXXX i have *no* idea if this is a problem or not
1876 or even if you are supposed to construct a different
1877 reply if the account already exists...
1880 fstrcpy(mach_acct, dos_unistrn2(q_u.uni_mach_acct.buffer,
1881 q_u.uni_mach_acct.uni_str_len));
1884 sam_pass = getsam21pwnam(mach_acct);
1887 if (sam_pass != NULL)
1889 /* machine account exists: say so */
1890 status = 0xC0000000 | NT_STATUS_USER_EXISTS;
1894 /* this could cause trouble... */
1895 DEBUG(0,("trouble!\n"));
1899 /* construct reply. */
1900 if(!samr_reply_unknown_32(&q_u, rdata, status))
1907 /*******************************************************************
1908 samr_reply_connect_anon
1909 ********************************************************************/
1910 static BOOL samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u, prs_struct *rdata)
1912 SAMR_R_CONNECT_ANON r_u;
1913 BOOL pol_open = False;
1915 /* set up the SAMR connect_anon response */
1918 /* get a (unique) handle. open a policy on it. */
1919 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1921 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1924 /* associate the domain SID with the (unique) handle. */
1925 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1927 /* oh, whoops. don't know what error message to return, here */
1928 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1931 if (r_u.status != 0 && pol_open)
1933 close_lsa_policy_hnd(&(r_u.connect_pol));
1936 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1938 /* store the response in the SMB stream */
1939 if(!samr_io_r_connect_anon("", &r_u, rdata, 0))
1942 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1947 /*******************************************************************
1948 api_samr_connect_anon
1949 ********************************************************************/
1950 static BOOL api_samr_connect_anon(pipes_struct *p)
1952 SAMR_Q_CONNECT_ANON q_u;
1953 prs_struct *data = &p->in_data.data;
1954 prs_struct *rdata = &p->out_data.rdata;
1956 /* grab the samr open policy */
1957 if(!samr_io_q_connect_anon("", &q_u, data, 0))
1960 /* construct reply. always indicate success */
1961 if(!samr_reply_connect_anon(&q_u, rdata))
1967 /*******************************************************************
1969 ********************************************************************/
1970 static BOOL samr_reply_connect(SAMR_Q_CONNECT *q_u, prs_struct *rdata)
1973 BOOL pol_open = False;
1975 /* set up the SAMR connect response */
1978 /* get a (unique) handle. open a policy on it. */
1979 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1981 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1984 /* associate the domain SID with the (unique) handle. */
1985 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1987 /* oh, whoops. don't know what error message to return, here */
1988 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1991 if (r_u.status != 0 && pol_open)
1993 close_lsa_policy_hnd(&(r_u.connect_pol));
1996 DEBUG(5,("samr_connect: %d\n", __LINE__));
1998 /* store the response in the SMB stream */
1999 if(!samr_io_r_connect("", &r_u, rdata, 0))
2002 DEBUG(5,("samr_connect: %d\n", __LINE__));
2007 /*******************************************************************
2009 ********************************************************************/
2010 static BOOL api_samr_connect(pipes_struct *p)
2013 prs_struct *data = &p->in_data.data;
2014 prs_struct *rdata = &p->out_data.rdata;
2016 /* grab the samr open policy */
2017 if(!samr_io_q_connect("", &q_u, data, 0))
2020 /* construct reply. always indicate success */
2021 if(!samr_reply_connect(&q_u, rdata))
2027 /**********************************************************************
2028 api_reply_lookup_domain
2029 **********************************************************************/
2030 static BOOL samr_reply_lookup_domain(SAMR_Q_LOOKUP_DOMAIN* q_u, prs_struct* rdata)
2032 SAMR_R_LOOKUP_DOMAIN r_u;
2035 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->connect_pol)) == -1))
2037 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
2038 DEBUG(5,("samr_reply_lookup_domain: invalid handle\n"));
2041 /* assume the domain name sent is our global_myname and
2042 send global_sam_sid */
2043 init_samr_r_lookup_domain(&r_u, &global_sam_sid, r_u.status);
2045 if(!samr_io_r_lookup_domain("", &r_u, rdata, 0))
2048 DEBUG(5,("samr_reply_lookup_domain: %d\n", __LINE__));
2053 /**********************************************************************
2054 api_samr_lookup_domain
2055 **********************************************************************/
2056 static BOOL api_samr_lookup_domain(pipes_struct *p)
2058 SAMR_Q_LOOKUP_DOMAIN q_u;
2059 prs_struct *data = &p->in_data.data;
2060 prs_struct *rdata = &p->out_data.rdata;
2062 if(!samr_io_q_lookup_domain("", &q_u, data, 0))
2065 if(!samr_reply_lookup_domain(&q_u, rdata))
2071 /**********************************************************************
2072 samr_reply_enum_domains
2073 **********************************************************************/
2074 static BOOL samr_reply_enum_domains(SAMR_Q_ENUM_DOMAINS* q_u, prs_struct* rdata)
2076 SAMR_R_ENUM_DOMAINS r_u;
2079 fstrcpy(dom[0],global_myname);
2080 fstrcpy(dom[1],"Builtin");
2083 init_samr_r_enum_domains(&r_u, q_u->start_idx, dom, 2);
2084 if(!samr_io_r_enum_domains("", &r_u, rdata, 0)) {
2086 free(r_u.uni_dom_name);
2091 free(r_u.uni_dom_name);
2096 /**********************************************************************
2097 api_samr_enum_domains
2098 **********************************************************************/
2099 static BOOL api_samr_enum_domains(pipes_struct *p)
2101 SAMR_Q_ENUM_DOMAINS q_u;
2102 prs_struct *data = &p->in_data.data;
2103 prs_struct *rdata = &p->out_data.rdata;
2105 if(!samr_io_q_enum_domains("", &q_u, data, 0))
2108 if(!samr_reply_enum_domains(&q_u, rdata))
2114 /*******************************************************************
2115 samr_reply_open_alias
2116 ********************************************************************/
2117 static BOOL samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u, prs_struct *rdata)
2119 SAMR_R_OPEN_ALIAS r_u;
2120 BOOL pol_open = False;
2122 /* set up the SAMR open_alias response */
2125 /* get a (unique) handle. open a policy on it. */
2126 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.pol))))
2128 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2131 /* associate a RID with the (unique) handle. */
2132 if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.pol), q_u->rid_alias))
2134 /* oh, whoops. don't know what error message to return, here */
2135 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2138 if (r_u.status != 0 && pol_open)
2140 close_lsa_policy_hnd(&(r_u.pol));
2143 DEBUG(5,("samr_open_alias: %d\n", __LINE__));
2145 /* store the response in the SMB stream */
2146 if(!samr_io_r_open_alias("", &r_u, rdata, 0))
2149 DEBUG(5,("samr_open_alias: %d\n", __LINE__));
2154 /*******************************************************************
2156 ********************************************************************/
2157 static BOOL api_samr_open_alias(pipes_struct *p)
2159 SAMR_Q_OPEN_ALIAS q_u;
2160 prs_struct *data = &p->in_data.data;
2161 prs_struct *rdata = &p->out_data.rdata;
2163 /* grab the samr open policy */
2164 if(!samr_io_q_open_alias("", &q_u, data, 0))
2167 /* construct reply. always indicate success */
2168 if(!samr_reply_open_alias(&q_u, rdata))
2174 /*******************************************************************
2175 array of \PIPE\samr operations
2176 ********************************************************************/
2177 static struct api_struct api_samr_cmds [] =
2179 { "SAMR_CLOSE_HND" , SAMR_CLOSE_HND , api_samr_close_hnd },
2180 { "SAMR_CONNECT" , SAMR_CONNECT , api_samr_connect },
2181 { "SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON , api_samr_connect_anon },
2182 { "SAMR_ENUM_DOM_USERS" , SAMR_ENUM_DOM_USERS , api_samr_enum_dom_users },
2183 { "SAMR_ENUM_DOM_GROUPS" , SAMR_ENUM_DOM_GROUPS , api_samr_enum_dom_groups },
2184 { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
2185 { "SAMR_LOOKUP_IDS" , SAMR_LOOKUP_IDS , api_samr_lookup_ids },
2186 { "SAMR_LOOKUP_NAMES" , SAMR_LOOKUP_NAMES , api_samr_lookup_names },
2187 { "SAMR_OPEN_USER" , SAMR_OPEN_USER , api_samr_open_user },
2188 { "SAMR_QUERY_USERINFO" , SAMR_QUERY_USERINFO , api_samr_query_userinfo },
2189 { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
2190 { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
2191 { "SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo },
2192 { "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo },
2193 { "SAMR_0x32" , 0x32 , api_samr_unknown_32 },
2194 { "SAMR_UNKNOWN_12" , SAMR_UNKNOWN_12 , api_samr_unknown_12 },
2195 { "SAMR_UNKNOWN_38" , SAMR_UNKNOWN_38 , api_samr_unknown_38 },
2196 { "SAMR_CHGPASSWD_USER" , SAMR_CHGPASSWD_USER , api_samr_chgpasswd_user },
2197 { "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias },
2198 { "SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain },
2199 { "SAMR_UNKNOWN_3" , SAMR_UNKNOWN_3 , api_samr_unknown_3 },
2200 { "SAMR_UNKNOWN_2C" , SAMR_UNKNOWN_2C , api_samr_unknown_2c },
2201 { "SAMR_LOOKUP_DOMAIN" , SAMR_LOOKUP_DOMAIN , api_samr_lookup_domain },
2202 { "SAMR_ENUM_DOMAINS" , SAMR_ENUM_DOMAINS , api_samr_enum_domains },
2206 /*******************************************************************
2207 receives a samr pipe and responds.
2208 ********************************************************************/
2209 BOOL api_samr_rpc(pipes_struct *p)
2211 return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds);