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 || (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];
740 /* find the policy handle. open a policy on it. */
741 if (r_e.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &sid))
743 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
746 sid_to_string(sid_str, &sid);
747 sid_to_string(sam_sid_str, &global_sam_sid);
749 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
751 /* well-known aliases */
752 if (strequal(sid_str, "S-1-5-32"))
755 while (num_entries < MAX_SAM_ENTRIES && ((name = builtin_alias_rids[num_entries].name) != NULL))
757 init_unistr2(&(pass[num_entries].uni_user_name), name, strlen(name));
758 pass[num_entries].user_rid = builtin_alias_rids[num_entries].rid;
762 else if (strequal(sid_str, sam_sid_str))
767 sep = lp_winbind_separator();
770 /* we return the UNIX groups here. This seems to be the right */
771 /* thing to do, since NT member servers return their local */
772 /* groups in the same situation. */
775 while (num_entries < MAX_SAM_ENTRIES && ((grp = getgrent()) != NULL))
779 /* Don't return winbind groups as they are not local! */
781 if (strchr(name, *sep) != NULL) {
785 init_unistr2(&(pass[num_entries].uni_user_name), name, strlen(name));
786 pass[num_entries].user_rid = pdb_gid_to_group_rid(grp->gr_gid);
793 init_samr_r_enum_dom_aliases(&r_e, num_entries, pass, r_e.status);
795 /* store the response in the SMB stream */
796 if(!samr_io_r_enum_dom_aliases("", &r_e, rdata, 0))
799 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
804 /*******************************************************************
805 api_samr_enum_dom_aliases
806 ********************************************************************/
807 static BOOL api_samr_enum_dom_aliases(pipes_struct *p)
809 SAMR_Q_ENUM_DOM_ALIASES q_e;
810 prs_struct *data = &p->in_data.data;
811 prs_struct *rdata = &p->out_data.rdata;
813 /* grab the samr open */
814 if(!samr_io_q_enum_dom_aliases("", &q_e, data, 0))
817 /* construct reply. */
818 if(!samr_reply_enum_dom_aliases(&q_e, rdata))
825 /*******************************************************************
826 samr_reply_query_dispinfo
827 ********************************************************************/
828 static BOOL samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u, prs_struct *rdata)
830 SAMR_R_QUERY_DISPINFO r_e;
834 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
836 int total_entries = 0;
838 uint16 switch_level = 0x0;
842 DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
844 /* find the policy handle. open a policy on it. */
845 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
847 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
848 DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n"));
851 if (r_e.status == 0x0)
853 /* decide how many entries to get depending on the max_entries
854 and max_size passed by client */
857 if(q_u->max_entries > MAX_SAM_ENTRIES)
858 q_u->max_entries = MAX_SAM_ENTRIES;
860 retsize = (q_u->max_entries * (sizeof(SAM_ENTRY1)+sizeof(SAM_STR1)))
863 if(retsize > q_u->max_size)
865 /* determine max_entries based on max_size */
866 q_u->max_entries = (q_u->max_size - 3*sizeof(uint32)) /
867 (sizeof(SAM_ENTRY1)+sizeof(SAM_STR1));
868 q_u->max_entries = (q_u->max_entries>0?q_u->max_entries:1);
871 DEBUG(10,("samr_reply_query_dispinfo: Setting q_u->max_entries to %u\n",q_u->max_entries));
874 got_pwds = get_passwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, q_u->max_entries, 0);
877 /* more left - set resume handle */
878 if(total_entries > num_entries)
883 switch (q_u->switch_level)
888 /* query disp info is for users */
890 init_sam_info_1(&info1, ACB_NORMAL,
891 q_u->start_idx, num_entries, pass);
893 ctr.sam.info1 = &info1;
899 /* query disp info is for servers */
901 init_sam_info_2(&info2, ACB_WSTRUST,
902 q_u->start_idx, num_entries, pass);
904 ctr.sam.info2 = &info2;
911 /* more left - set resume handle */
912 if(total_entries > num_entries)
917 if (r_e.status == 0 || r_e.status == 0x105)
919 init_samr_r_query_dispinfo(&r_e, switch_level, &ctr, r_e.status);
922 /* store the response in the SMB stream */
923 if(!samr_io_r_query_dispinfo("", &r_e, rdata, 0))
926 DEBUG(5,("samr_query_dispinfo: %d\n", __LINE__));
931 /*******************************************************************
932 api_samr_query_dispinfo
933 ********************************************************************/
934 static BOOL api_samr_query_dispinfo(pipes_struct *p)
936 SAMR_Q_QUERY_DISPINFO q_e;
937 prs_struct *data = &p->in_data.data;
938 prs_struct *rdata = &p->out_data.rdata;
940 /* grab the samr open */
941 if(!samr_io_q_query_dispinfo("", &q_e, data, 0))
944 /* construct reply. */
945 if(!samr_reply_query_dispinfo(&q_e, rdata))
952 /*******************************************************************
953 samr_reply_query_aliasinfo
954 ********************************************************************/
955 static BOOL samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
958 SAMR_R_QUERY_ALIASINFO r_e;
959 fstring alias_desc = "Local Unix group";
966 DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__));
968 /* find the policy handle. open a policy on it. */
969 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
971 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
974 alias_rid = get_lsa_policy_samr_rid(&q_u->pol);
975 if(alias_rid == 0xffffffff)
976 r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
978 if(!local_lookup_rid(alias_rid, alias, &type))
980 r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
983 init_samr_r_query_aliasinfo(&r_e, q_u->switch_level, alias, alias_desc);
985 /* store the response in the SMB stream */
986 if(!samr_io_r_query_aliasinfo("", &r_e, rdata, 0))
989 DEBUG(5,("samr_query_aliasinfo: %d\n", __LINE__));
994 /*******************************************************************
995 api_samr_query_aliasinfo
996 ********************************************************************/
997 static BOOL api_samr_query_aliasinfo(pipes_struct *p)
999 SAMR_Q_QUERY_ALIASINFO q_e;
1000 prs_struct *data = &p->in_data.data;
1001 prs_struct *rdata = &p->out_data.rdata;
1003 /* grab the samr open */
1004 if(!samr_io_q_query_aliasinfo("", &q_e, data, 0))
1007 /* construct reply. */
1008 if(!samr_reply_query_aliasinfo(&q_e, rdata))
1015 /*******************************************************************
1016 samr_reply_lookup_ids
1017 ********************************************************************/
1018 static BOOL samr_reply_lookup_ids(SAMR_Q_LOOKUP_IDS *q_u,
1021 uint32 rid[MAX_SAM_ENTRIES];
1023 int num_rids = q_u->num_sids1;
1025 SAMR_R_LOOKUP_IDS r_u;
1027 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
1029 if (num_rids > MAX_SAM_ENTRIES)
1031 num_rids = MAX_SAM_ENTRIES;
1032 DEBUG(5,("samr_lookup_ids: truncating entries to %d\n", num_rids));
1037 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1039 for (i = 0; i < num_rids && status == 0; i++)
1041 struct sam_passwd *sam_pass;
1045 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1046 q_u->uni_user_name[i].uni_str_len));
1048 /* find the user account */
1050 sam_pass = get_smb21pwd_entry(user_name, 0);
1053 if (sam_pass == NULL)
1055 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1060 rid[i] = sam_pass->user_rid;
1066 rid[0] = BUILTIN_ALIAS_RID_USERS;
1068 init_samr_r_lookup_ids(&r_u, num_rids, rid, status);
1070 /* store the response in the SMB stream */
1071 if(!samr_io_r_lookup_ids("", &r_u, rdata, 0))
1074 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
1079 /*******************************************************************
1081 ********************************************************************/
1082 static BOOL api_samr_lookup_ids(pipes_struct *p)
1084 SAMR_Q_LOOKUP_IDS q_u;
1085 prs_struct *data = &p->in_data.data;
1086 prs_struct *rdata = &p->out_data.rdata;
1088 /* grab the samr 0x10 */
1089 if(!samr_io_q_lookup_ids("", &q_u, data, 0))
1092 /* construct reply. always indicate success */
1093 if(!samr_reply_lookup_ids(&q_u, rdata))
1099 /*******************************************************************
1100 samr_reply_lookup_names
1101 ********************************************************************/
1103 static BOOL samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
1106 uint32 rid[MAX_SAM_ENTRIES];
1107 uint8 type[MAX_SAM_ENTRIES];
1110 int num_rids = q_u->num_names1;
1113 SAMR_R_LOOKUP_NAMES r_u;
1115 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1120 if (!get_lsa_policy_samr_sid(&q_u->pol, &pol_sid)) {
1121 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
1122 init_samr_r_lookup_names(&r_u, 0, rid, type, status);
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"));
1130 if (num_rids > MAX_SAM_ENTRIES) {
1131 num_rids = MAX_SAM_ENTRIES;
1132 DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
1135 SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
1137 for (i = 0; i < num_rids; i++) {
1140 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
1142 rid [i] = 0xffffffff;
1143 type[i] = SID_NAME_UNKNOWN;
1145 fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer,
1146 q_u->uni_name[i].uni_str_len));
1148 if(sid_equal(&pol_sid, &global_sam_sid))
1151 if(local_lookup_name(global_myname, name,
1154 sid_split_rid( &sid, &rid[i]);
1160 init_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
1162 /* store the response in the SMB stream */
1163 if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
1164 DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
1168 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1173 /*******************************************************************
1174 api_samr_lookup_names
1175 ********************************************************************/
1177 static BOOL api_samr_lookup_names(pipes_struct *p)
1179 SAMR_Q_LOOKUP_NAMES q_u;
1180 prs_struct *data = &p->in_data.data;
1181 prs_struct *rdata = &p->out_data.rdata;
1183 memset(&q_u, '\0', sizeof(q_u));
1185 /* grab the samr lookup names */
1186 if(!samr_io_q_lookup_names("", &q_u, data, 0)) {
1187 DEBUG(0,("api_samr_lookup_names: failed to unmarshall SAMR_Q_LOOKUP_NAMES.\n"));
1191 /* construct reply. always indicate success */
1192 if(!samr_reply_lookup_names(&q_u, rdata))
1198 /*******************************************************************
1199 samr_reply_chgpasswd_user
1200 ********************************************************************/
1202 static BOOL samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
1205 SAMR_R_CHGPASSWD_USER r_u;
1206 uint32 status = 0x0;
1210 fstrcpy(user_name, dos_unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len));
1211 fstrcpy(wks , dos_unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len));
1213 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1215 if (!pass_oem_change(user_name,
1216 q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1217 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1219 status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
1222 init_samr_r_chgpasswd_user(&r_u, status);
1224 /* store the response in the SMB stream */
1225 if(!samr_io_r_chgpasswd_user("", &r_u, rdata, 0)) {
1226 DEBUG(0,("samr_reply_chgpasswd_user: Failed to marshall SAMR_R_CHGPASSWD_USER struct.\n" ));
1230 DEBUG(5,("samr_chgpasswd_user: %d\n", __LINE__));
1234 /*******************************************************************
1235 api_samr_chgpasswd_user
1236 ********************************************************************/
1238 static BOOL api_samr_chgpasswd_user(pipes_struct *p)
1240 SAMR_Q_CHGPASSWD_USER q_u;
1241 prs_struct *data = &p->in_data.data;
1242 prs_struct *rdata = &p->out_data.rdata;
1244 /* unknown 38 command */
1245 if (!samr_io_q_chgpasswd_user("", &q_u, data, 0)) {
1246 DEBUG(0,("api_samr_chgpasswd_user: samr_io_q_chgpasswd_user failed to parse RPC packet.\n"));
1250 /* construct reply. */
1251 if(!samr_reply_chgpasswd_user(&q_u, rdata)) {
1252 DEBUG(0,("api_samr_chgpasswd_user: samr_reply_chgpasswd_user failed to create reply packet.\n"));
1260 /*******************************************************************
1261 samr_reply_unknown_38
1262 ********************************************************************/
1263 static BOOL samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u, prs_struct *rdata)
1265 SAMR_R_UNKNOWN_38 r_u;
1267 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1269 init_samr_r_unknown_38(&r_u);
1271 /* store the response in the SMB stream */
1272 if(!samr_io_r_unknown_38("", &r_u, rdata, 0))
1275 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1279 /*******************************************************************
1281 ********************************************************************/
1282 static BOOL api_samr_unknown_38(pipes_struct *p)
1284 SAMR_Q_UNKNOWN_38 q_u;
1285 prs_struct *data = &p->in_data.data;
1286 prs_struct *rdata = &p->out_data.rdata;
1288 /* unknown 38 command */
1289 if(!samr_io_q_unknown_38("", &q_u, data, 0))
1292 /* construct reply. always indicate success */
1293 if(!samr_reply_unknown_38(&q_u, rdata))
1300 /*******************************************************************
1301 samr_reply_unknown_12
1302 ********************************************************************/
1303 static BOOL samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
1306 fstring group_names[MAX_SAM_ENTRIES];
1307 uint32 group_attrs[MAX_SAM_ENTRIES];
1309 int num_gids = q_u->num_gids1;
1311 SAMR_R_UNKNOWN_12 r_u;
1313 DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
1315 /* find the policy handle. open a policy on it. */
1316 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1318 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1324 if (num_gids > MAX_SAM_ENTRIES)
1326 num_gids = MAX_SAM_ENTRIES;
1327 DEBUG(5,("samr_unknown_12: truncating entries to %d\n", num_gids));
1330 for (i = 0; i < num_gids && status == 0; i++)
1332 fstrcpy(group_names[i], "dummy group");
1333 group_attrs[i] = 0x2;
1337 init_samr_r_unknown_12(&r_u, num_gids, group_names, group_attrs, status);
1339 /* store the response in the SMB stream */
1340 if(!samr_io_r_unknown_12("", &r_u, rdata, 0))
1343 DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
1348 /*******************************************************************
1350 ********************************************************************/
1351 static BOOL api_samr_unknown_12(pipes_struct *p)
1353 SAMR_Q_UNKNOWN_12 q_u;
1354 prs_struct *data = &p->in_data.data;
1355 prs_struct *rdata = &p->out_data.rdata;
1357 /* grab the samr lookup names */
1358 if(!samr_io_q_unknown_12("", &q_u, data, 0))
1361 /* construct reply. always indicate success */
1362 if(!samr_reply_unknown_12(&q_u, rdata))
1369 /*******************************************************************
1370 samr_reply_open_user
1371 ********************************************************************/
1372 static BOOL samr_reply_open_user(SAMR_Q_OPEN_USER *q_u, prs_struct *rdata, int status)
1374 SAMR_R_OPEN_USER r_u;
1375 struct sam_passwd *sam_pass;
1376 BOOL pol_open = False;
1378 /* set up the SAMR open_user response */
1379 memset((char *)r_u.user_pol.data, '\0', POL_HND_SIZE);
1383 /* find the policy handle. open a policy on it. */
1384 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
1386 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1389 /* get a (unique) handle. open a policy on it. */
1390 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.user_pol))))
1392 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1396 sam_pass = getsam21pwrid(q_u->user_rid);
1399 /* check that the RID exists in our domain. */
1400 if (r_u.status == 0x0 && sam_pass == NULL)
1402 r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1405 /* associate the RID with the (unique) handle. */
1406 if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.user_pol), q_u->user_rid))
1408 /* oh, whoops. don't know what error message to return, here */
1409 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1412 if (r_u.status != 0 && pol_open)
1414 close_lsa_policy_hnd(&(r_u.user_pol));
1417 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1419 /* store the response in the SMB stream */
1420 if(!samr_io_r_open_user("", &r_u, rdata, 0))
1423 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1428 /*******************************************************************
1430 ********************************************************************/
1431 static BOOL api_samr_open_user(pipes_struct *p)
1433 SAMR_Q_OPEN_USER q_u;
1434 prs_struct *data = &p->in_data.data;
1435 prs_struct *rdata = &p->out_data.rdata;
1437 /* grab the samr unknown 22 */
1438 if(!samr_io_q_open_user("", &q_u, data, 0))
1441 /* construct reply. always indicate success */
1442 if(!samr_reply_open_user(&q_u, rdata, 0x0))
1449 /*************************************************************************
1451 *************************************************************************/
1452 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1454 struct smb_passwd *smb_pass;
1456 if (!pdb_rid_is_user(user_rid))
1458 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1463 smb_pass = getsmbpwrid(user_rid);
1466 if (smb_pass == NULL)
1468 DEBUG(4,("User 0x%x not found\n", user_rid));
1472 DEBUG(3,("User:[%s]\n", smb_pass->smb_name));
1474 init_sam_user_info10(id10, smb_pass->acct_ctrl);
1479 /*************************************************************************
1481 *************************************************************************/
1482 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1485 struct sam_passwd *sam_pass;
1489 if (!pdb_rid_is_user(user_rid))
1491 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1496 sam_pass = getsam21pwrid(user_rid);
1499 if (sam_pass == NULL)
1501 DEBUG(4,("User 0x%x not found\n", user_rid));
1505 DEBUG(3,("User:[%s]\n", sam_pass->smb_name));
1507 dummy_time.low = 0xffffffff;
1508 dummy_time.high = 0x7fffffff;
1510 DEBUG(5,("get_user_info_21 - TODO: convert unix times to NTTIMEs\n"));
1512 /* create a LOGON_HRS structure */
1513 hrs.len = sam_pass->hours_len;
1514 SMB_ASSERT_ARRAY(hrs.hours, hrs.len);
1515 for (i = 0; i < hrs.len; i++)
1517 hrs.hours[i] = sam_pass->hours[i];
1520 init_sam_user_info21(id21,
1522 &dummy_time, /* logon_time */
1523 &dummy_time, /* logoff_time */
1524 &dummy_time, /* kickoff_time */
1525 &dummy_time, /* pass_last_set_time */
1526 &dummy_time, /* pass_can_change_time */
1527 &dummy_time, /* pass_must_change_time */
1529 sam_pass->smb_name, /* user_name */
1530 sam_pass->full_name, /* full_name */
1531 sam_pass->home_dir, /* home_dir */
1532 sam_pass->dir_drive, /* dir_drive */
1533 sam_pass->logon_script, /* logon_script */
1534 sam_pass->profile_path, /* profile_path */
1535 sam_pass->acct_desc, /* description */
1536 sam_pass->workstations, /* workstations user can log in from */
1537 sam_pass->unknown_str, /* don't know, yet */
1538 sam_pass->munged_dial, /* dialin info. contains dialin path and tel no */
1540 sam_pass->user_rid, /* RID user_id */
1541 sam_pass->group_rid, /* RID group_id */
1542 sam_pass->acct_ctrl,
1544 sam_pass->unknown_3, /* unknown_3 */
1545 sam_pass->logon_divs, /* divisions per week */
1546 &hrs, /* logon hours */
1547 sam_pass->unknown_5,
1548 sam_pass->unknown_6);
1553 /*******************************************************************
1554 samr_reply_query_userinfo
1555 ********************************************************************/
1556 static BOOL samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
1559 SAMR_R_QUERY_USERINFO r_u;
1561 SAM_USER_INFO_11 id11;
1563 SAM_USER_INFO_10 id10;
1564 SAM_USER_INFO_21 id21;
1567 uint32 status = 0x0;
1570 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1572 /* search for the handle */
1573 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1575 status = NT_STATUS_INVALID_HANDLE;
1578 /* find the user's rid */
1579 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1581 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1584 DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
1586 /* ok! user info levels (there are lots: see MSDEV help), off we go... */
1589 switch (q_u->switch_value)
1593 info = (void*)&id10;
1594 status = get_user_info_10(&id10, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1598 /* whoops - got this wrong. i think. or don't understand what's happening. */
1602 info = (void*)&id11;
1604 expire.low = 0xffffffff;
1605 expire.high = 0x7fffffff;
1607 make_sam_user_info11(&id11, &expire, "BROOKFIELDS$", 0x03ef, 0x201, 0x0080);
1614 info = (void*)&id21;
1615 status = get_user_info_21(&id21, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1621 status = NT_STATUS_INVALID_INFO_CLASS;
1628 init_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
1630 /* store the response in the SMB stream */
1631 if(!samr_io_r_query_userinfo("", &r_u, rdata, 0))
1634 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1639 /*******************************************************************
1640 api_samr_query_userinfo
1641 ********************************************************************/
1642 static BOOL api_samr_query_userinfo(pipes_struct *p)
1644 SAMR_Q_QUERY_USERINFO q_u;
1645 prs_struct *data = &p->in_data.data;
1646 prs_struct *rdata = &p->out_data.rdata;
1648 /* grab the samr unknown 24 */
1649 if(!samr_io_q_query_userinfo("", &q_u, data, 0))
1652 /* construct reply. always indicate success */
1653 if(!samr_reply_query_userinfo(&q_u, rdata))
1660 /*******************************************************************
1661 samr_reply_query_usergroups
1662 ********************************************************************/
1663 static BOOL samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
1666 SAMR_R_QUERY_USERGROUPS r_u;
1667 uint32 status = 0x0;
1669 struct sam_passwd *sam_pass;
1670 DOM_GID *gids = NULL;
1674 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1676 /* find the policy handle. open a policy on it. */
1677 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1679 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1682 /* find the user's rid */
1683 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1685 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1691 sam_pass = getsam21pwrid(rid);
1694 if (sam_pass == NULL)
1696 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1703 get_domain_user_groups(groups, sam_pass->smb_name);
1705 num_groups = make_dom_gids(groups, &gids);
1708 /* construct the response. lkclXXXX: gids are not copied! */
1709 init_samr_r_query_usergroups(&r_u, num_groups, gids, status);
1711 /* store the response in the SMB stream */
1712 if(!samr_io_r_query_usergroups("", &r_u, rdata, 0)) {
1721 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1726 /*******************************************************************
1727 api_samr_query_usergroups
1728 ********************************************************************/
1729 static BOOL api_samr_query_usergroups(pipes_struct *p)
1731 SAMR_Q_QUERY_USERGROUPS q_u;
1732 prs_struct *data = &p->in_data.data;
1733 prs_struct *rdata = &p->out_data.rdata;
1735 /* grab the samr unknown 32 */
1736 if(!samr_io_q_query_usergroups("", &q_u, data, 0))
1739 /* construct reply. */
1740 if(!samr_reply_query_usergroups(&q_u, rdata))
1747 /*******************************************************************
1748 samr_reply_query_dom_info
1749 ********************************************************************/
1750 static BOOL samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_struct *rdata)
1752 SAMR_R_QUERY_DOMAIN_INFO r_u;
1754 uint16 switch_value = 0x0;
1755 uint32 status = 0x0;
1762 DEBUG(5,("samr_reply_query_dom_info: %d\n", __LINE__));
1764 /* find the policy handle. open a policy on it. */
1765 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
1767 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1768 DEBUG(5,("samr_reply_query_dom_info: invalid handle\n"));
1773 switch (q_u->switch_value)
1778 init_unk_info2(&ctr.info.inf2, global_myworkgroup, global_myname);
1784 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
1790 init_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
1792 /* store the response in the SMB stream */
1793 if(!samr_io_r_query_dom_info("", &r_u, rdata, 0))
1796 DEBUG(5,("samr_query_dom_info: %d\n", __LINE__));
1801 /*******************************************************************
1802 api_samr_query_dom_info
1803 ********************************************************************/
1804 static BOOL api_samr_query_dom_info(pipes_struct *p)
1806 SAMR_Q_QUERY_DOMAIN_INFO q_e;
1807 prs_struct *data = &p->in_data.data;
1808 prs_struct *rdata = &p->out_data.rdata;
1810 /* grab the samr unknown 8 command */
1811 if(!samr_io_q_query_dom_info("", &q_e, data, 0))
1814 /* construct reply. */
1815 if(!samr_reply_query_dom_info(&q_e, rdata))
1821 /*******************************************************************
1822 samr_reply_unknown_32
1823 ********************************************************************/
1824 static BOOL samr_reply_unknown_32(SAMR_Q_UNKNOWN_32 *q_u,
1829 SAMR_R_UNKNOWN_32 r_u;
1831 /* set up the SAMR unknown_32 response */
1832 memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
1835 for (i = 4; i < POL_HND_SIZE; i++)
1837 r_u.pol.data[i] = i+1;
1841 init_dom_rid4(&(r_u.rid4), 0x0030, 0, 0);
1842 r_u.status = status;
1844 DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
1846 /* store the response in the SMB stream */
1847 if(!samr_io_r_unknown_32("", &r_u, rdata, 0))
1850 DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
1855 /*******************************************************************
1857 ********************************************************************/
1858 static BOOL api_samr_unknown_32(pipes_struct *p)
1861 struct sam_passwd *sam_pass;
1863 prs_struct *data = &p->in_data.data;
1864 prs_struct *rdata = &p->out_data.rdata;
1866 SAMR_Q_UNKNOWN_32 q_u;
1868 /* grab the samr unknown 32 */
1869 samr_io_q_unknown_32("", &q_u, data, 0);
1871 /* find the machine account: tell the caller if it exists.
1872 lkclXXXX i have *no* idea if this is a problem or not
1873 or even if you are supposed to construct a different
1874 reply if the account already exists...
1877 fstrcpy(mach_acct, dos_unistrn2(q_u.uni_mach_acct.buffer,
1878 q_u.uni_mach_acct.uni_str_len));
1881 sam_pass = getsam21pwnam(mach_acct);
1884 if (sam_pass != NULL)
1886 /* machine account exists: say so */
1887 status = 0xC0000000 | NT_STATUS_USER_EXISTS;
1891 /* this could cause trouble... */
1892 DEBUG(0,("trouble!\n"));
1896 /* construct reply. */
1897 if(!samr_reply_unknown_32(&q_u, rdata, status))
1904 /*******************************************************************
1905 samr_reply_connect_anon
1906 ********************************************************************/
1907 static BOOL samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u, prs_struct *rdata)
1909 SAMR_R_CONNECT_ANON r_u;
1910 BOOL pol_open = False;
1912 /* set up the SAMR connect_anon response */
1915 /* get a (unique) handle. open a policy on it. */
1916 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1918 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1921 /* associate the domain SID with the (unique) handle. */
1922 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1924 /* oh, whoops. don't know what error message to return, here */
1925 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1928 if (r_u.status != 0 && pol_open)
1930 close_lsa_policy_hnd(&(r_u.connect_pol));
1933 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1935 /* store the response in the SMB stream */
1936 if(!samr_io_r_connect_anon("", &r_u, rdata, 0))
1939 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1944 /*******************************************************************
1945 api_samr_connect_anon
1946 ********************************************************************/
1947 static BOOL api_samr_connect_anon(pipes_struct *p)
1949 SAMR_Q_CONNECT_ANON q_u;
1950 prs_struct *data = &p->in_data.data;
1951 prs_struct *rdata = &p->out_data.rdata;
1953 /* grab the samr open policy */
1954 if(!samr_io_q_connect_anon("", &q_u, data, 0))
1957 /* construct reply. always indicate success */
1958 if(!samr_reply_connect_anon(&q_u, rdata))
1964 /*******************************************************************
1966 ********************************************************************/
1967 static BOOL samr_reply_connect(SAMR_Q_CONNECT *q_u, prs_struct *rdata)
1970 BOOL pol_open = False;
1972 /* set up the SAMR connect response */
1975 /* get a (unique) handle. open a policy on it. */
1976 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1978 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1981 /* associate the domain SID with the (unique) handle. */
1982 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1984 /* oh, whoops. don't know what error message to return, here */
1985 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1988 if (r_u.status != 0 && pol_open)
1990 close_lsa_policy_hnd(&(r_u.connect_pol));
1993 DEBUG(5,("samr_connect: %d\n", __LINE__));
1995 /* store the response in the SMB stream */
1996 if(!samr_io_r_connect("", &r_u, rdata, 0))
1999 DEBUG(5,("samr_connect: %d\n", __LINE__));
2004 /*******************************************************************
2006 ********************************************************************/
2007 static BOOL api_samr_connect(pipes_struct *p)
2010 prs_struct *data = &p->in_data.data;
2011 prs_struct *rdata = &p->out_data.rdata;
2013 /* grab the samr open policy */
2014 if(!samr_io_q_connect("", &q_u, data, 0))
2017 /* construct reply. always indicate success */
2018 if(!samr_reply_connect(&q_u, rdata))
2024 /**********************************************************************
2025 api_reply_lookup_domain
2026 **********************************************************************/
2027 static BOOL samr_reply_lookup_domain(SAMR_Q_LOOKUP_DOMAIN* q_u, prs_struct* rdata)
2029 SAMR_R_LOOKUP_DOMAIN r_u;
2032 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->connect_pol)) == -1))
2034 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
2035 DEBUG(5,("samr_reply_lookup_domain: invalid handle\n"));
2038 /* assume the domain name sent is our global_myname and
2039 send global_sam_sid */
2040 init_samr_r_lookup_domain(&r_u, &global_sam_sid, r_u.status);
2042 if(!samr_io_r_lookup_domain("", &r_u, rdata, 0))
2045 DEBUG(5,("samr_reply_lookup_domain: %d\n", __LINE__));
2050 /**********************************************************************
2051 api_samr_lookup_domain
2052 **********************************************************************/
2053 static BOOL api_samr_lookup_domain(pipes_struct *p)
2055 SAMR_Q_LOOKUP_DOMAIN q_u;
2056 prs_struct *data = &p->in_data.data;
2057 prs_struct *rdata = &p->out_data.rdata;
2059 if(!samr_io_q_lookup_domain("", &q_u, data, 0))
2062 if(!samr_reply_lookup_domain(&q_u, rdata))
2068 /**********************************************************************
2069 samr_reply_enum_domains
2070 **********************************************************************/
2071 static BOOL samr_reply_enum_domains(SAMR_Q_ENUM_DOMAINS* q_u, prs_struct* rdata)
2073 SAMR_R_ENUM_DOMAINS r_u;
2076 fstrcpy(dom[0],global_myname);
2077 fstrcpy(dom[1],"Builtin");
2080 init_samr_r_enum_domains(&r_u, q_u->start_idx, dom, 2);
2081 if(!samr_io_r_enum_domains("", &r_u, rdata, 0)) {
2083 free(r_u.uni_dom_name);
2088 free(r_u.uni_dom_name);
2093 /**********************************************************************
2094 api_samr_enum_domains
2095 **********************************************************************/
2096 static BOOL api_samr_enum_domains(pipes_struct *p)
2098 SAMR_Q_ENUM_DOMAINS q_u;
2099 prs_struct *data = &p->in_data.data;
2100 prs_struct *rdata = &p->out_data.rdata;
2102 if(!samr_io_q_enum_domains("", &q_u, data, 0))
2105 if(!samr_reply_enum_domains(&q_u, rdata))
2111 /*******************************************************************
2112 samr_reply_open_alias
2113 ********************************************************************/
2114 static BOOL samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u, prs_struct *rdata)
2116 SAMR_R_OPEN_ALIAS r_u;
2117 BOOL pol_open = False;
2119 /* set up the SAMR open_alias response */
2122 /* get a (unique) handle. open a policy on it. */
2123 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.pol))))
2125 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2128 /* associate a RID with the (unique) handle. */
2129 if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.pol), q_u->rid_alias))
2131 /* oh, whoops. don't know what error message to return, here */
2132 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2135 if (r_u.status != 0 && pol_open)
2137 close_lsa_policy_hnd(&(r_u.pol));
2140 DEBUG(5,("samr_open_alias: %d\n", __LINE__));
2142 /* store the response in the SMB stream */
2143 if(!samr_io_r_open_alias("", &r_u, rdata, 0))
2146 DEBUG(5,("samr_open_alias: %d\n", __LINE__));
2151 /*******************************************************************
2153 ********************************************************************/
2154 static BOOL api_samr_open_alias(pipes_struct *p)
2156 SAMR_Q_OPEN_ALIAS q_u;
2157 prs_struct *data = &p->in_data.data;
2158 prs_struct *rdata = &p->out_data.rdata;
2160 /* grab the samr open policy */
2161 if(!samr_io_q_open_alias("", &q_u, data, 0))
2164 /* construct reply. always indicate success */
2165 if(!samr_reply_open_alias(&q_u, rdata))
2171 /*******************************************************************
2172 array of \PIPE\samr operations
2173 ********************************************************************/
2174 static struct api_struct api_samr_cmds [] =
2176 { "SAMR_CLOSE_HND" , SAMR_CLOSE_HND , api_samr_close_hnd },
2177 { "SAMR_CONNECT" , SAMR_CONNECT , api_samr_connect },
2178 { "SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON , api_samr_connect_anon },
2179 { "SAMR_ENUM_DOM_USERS" , SAMR_ENUM_DOM_USERS , api_samr_enum_dom_users },
2180 { "SAMR_ENUM_DOM_GROUPS" , SAMR_ENUM_DOM_GROUPS , api_samr_enum_dom_groups },
2181 { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
2182 { "SAMR_LOOKUP_IDS" , SAMR_LOOKUP_IDS , api_samr_lookup_ids },
2183 { "SAMR_LOOKUP_NAMES" , SAMR_LOOKUP_NAMES , api_samr_lookup_names },
2184 { "SAMR_OPEN_USER" , SAMR_OPEN_USER , api_samr_open_user },
2185 { "SAMR_QUERY_USERINFO" , SAMR_QUERY_USERINFO , api_samr_query_userinfo },
2186 { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
2187 { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
2188 { "SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo },
2189 { "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo },
2190 { "SAMR_0x32" , 0x32 , api_samr_unknown_32 },
2191 { "SAMR_UNKNOWN_12" , SAMR_UNKNOWN_12 , api_samr_unknown_12 },
2192 { "SAMR_UNKNOWN_38" , SAMR_UNKNOWN_38 , api_samr_unknown_38 },
2193 { "SAMR_CHGPASSWD_USER" , SAMR_CHGPASSWD_USER , api_samr_chgpasswd_user },
2194 { "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias },
2195 { "SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain },
2196 { "SAMR_UNKNOWN_3" , SAMR_UNKNOWN_3 , api_samr_unknown_3 },
2197 { "SAMR_UNKNOWN_2C" , SAMR_UNKNOWN_2C , api_samr_unknown_2c },
2198 { "SAMR_LOOKUP_DOMAIN" , SAMR_LOOKUP_DOMAIN , api_samr_lookup_domain },
2199 { "SAMR_ENUM_DOMAINS" , SAMR_ENUM_DOMAINS , api_samr_enum_domains },
2203 /*******************************************************************
2204 receives a samr pipe and responds.
2205 ********************************************************************/
2206 BOOL api_samr_rpc(pipes_struct *p)
2208 return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds);