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];
616 r_e.total_num_entries = 0;
618 /* find the policy handle. open a policy on it. */
619 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
621 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
624 DEBUG(5,("samr_reply_enum_dom_users: %d\n", __LINE__));
627 get_sampwd_entries(pass, 0, &total_entries, &num_entries, MAX_SAM_ENTRIES, q_u->acb_mask);
630 init_samr_r_enum_dom_users(&r_e, total_entries,
631 q_u->unknown_0, num_entries,
634 /* store the response in the SMB stream */
635 if(!samr_io_r_enum_dom_users("", &r_e, rdata, 0))
638 DEBUG(5,("samr_enum_dom_users: %d\n", __LINE__));
643 /*******************************************************************
644 api_samr_enum_dom_users
645 ********************************************************************/
646 static BOOL api_samr_enum_dom_users(pipes_struct *p)
648 SAMR_Q_ENUM_DOM_USERS q_e;
649 prs_struct *data = &p->in_data.data;
650 prs_struct *rdata = &p->out_data.rdata;
652 /* grab the samr open */
653 if(!samr_io_q_enum_dom_users("", &q_e, data, 0))
656 /* construct reply. */
657 if(!samr_reply_enum_dom_users(&q_e, rdata))
663 /*******************************************************************
664 samr_reply_enum_dom_groups
665 ********************************************************************/
666 static BOOL samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u,
669 SAMR_R_ENUM_DOM_GROUPS r_e;
670 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
673 char *dummy_group = "Domain Admins";
680 /* find the policy handle. open a policy on it. */
681 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
683 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
686 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
690 ZERO_STRUCTP(&pass[0]);
691 init_unistr2(&(pass[0].uni_user_name), dummy_group, strlen(dummy_group));
692 pass[0].user_rid = DOMAIN_GROUP_RID_ADMINS;
694 if (r_e.status == 0 && got_grps)
696 init_samr_r_enum_dom_groups(&r_e, q_u->start_idx, num_entries, pass, r_e.status);
699 /* store the response in the SMB stream */
700 if(!samr_io_r_enum_dom_groups("", &r_e, rdata, 0))
703 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
708 /*******************************************************************
709 api_samr_enum_dom_groups
710 ********************************************************************/
711 static BOOL api_samr_enum_dom_groups(pipes_struct *p)
713 SAMR_Q_ENUM_DOM_GROUPS q_e;
714 prs_struct *data = &p->in_data.data;
715 prs_struct *rdata = &p->out_data.rdata;
717 /* grab the samr open */
718 if(!samr_io_q_enum_dom_groups("", &q_e, data, 0))
721 /* construct reply. */
722 if(!samr_reply_enum_dom_groups(&q_e, rdata))
728 /*******************************************************************
729 samr_reply_enum_dom_aliases
730 ********************************************************************/
731 static BOOL samr_reply_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_u,
734 SAMR_R_ENUM_DOM_ALIASES r_e;
735 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
744 /* find the policy handle. open a policy on it. */
745 if (r_e.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &sid))
747 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
750 sid_to_string(sid_str, &sid);
751 sid_to_string(sam_sid_str, &global_sam_sid);
753 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
755 /* well-known aliases */
756 if (strequal(sid_str, "S-1-5-32"))
759 while (num_entries < MAX_SAM_ENTRIES && ((name = builtin_alias_rids[num_entries].name) != NULL))
761 init_unistr2(&(pass[num_entries].uni_user_name), name, strlen(name));
762 pass[num_entries].user_rid = builtin_alias_rids[num_entries].rid;
766 else if (strequal(sid_str, sam_sid_str))
771 sep = lp_winbind_separator();
774 /* we return the UNIX groups here. This seems to be the right */
775 /* thing to do, since NT member servers return their local */
776 /* groups in the same situation. */
779 while (num_entries < MAX_SAM_ENTRIES && ((grp = getgrent()) != NULL))
783 /* Don't return winbind groups as they are not local! */
785 if (strchr(name, *sep) != NULL) {
789 init_unistr2(&(pass[num_entries].uni_user_name), name, strlen(name));
790 pass[num_entries].user_rid = pdb_gid_to_group_rid(grp->gr_gid);
797 init_samr_r_enum_dom_aliases(&r_e, num_entries, pass, r_e.status);
799 /* store the response in the SMB stream */
800 if(!samr_io_r_enum_dom_aliases("", &r_e, rdata, 0))
803 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
808 /*******************************************************************
809 api_samr_enum_dom_aliases
810 ********************************************************************/
811 static BOOL api_samr_enum_dom_aliases(pipes_struct *p)
813 SAMR_Q_ENUM_DOM_ALIASES q_e;
814 prs_struct *data = &p->in_data.data;
815 prs_struct *rdata = &p->out_data.rdata;
819 /* grab the samr open */
820 if(!samr_io_q_enum_dom_aliases("", &q_e, data, 0))
823 /* construct reply. */
824 if(!samr_reply_enum_dom_aliases(&q_e, rdata))
831 /*******************************************************************
832 samr_reply_query_dispinfo
833 ********************************************************************/
834 static BOOL samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u, prs_struct *rdata)
836 SAMR_R_QUERY_DISPINFO r_e;
840 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
842 int total_entries = 0;
844 uint16 switch_level = 0x0;
848 DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
850 /* find the policy handle. open a policy on it. */
851 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
853 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
854 DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n"));
857 if (r_e.status == 0x0)
859 /* decide how many entries to get depending on the max_entries
860 and max_size passed by client */
863 if(q_u->max_entries > MAX_SAM_ENTRIES)
864 q_u->max_entries = MAX_SAM_ENTRIES;
866 retsize = (q_u->max_entries * (sizeof(SAM_ENTRY1)+sizeof(SAM_STR1)))
869 if(retsize > q_u->max_size)
871 /* determine max_entries based on max_size */
872 q_u->max_entries = (q_u->max_size - 3*sizeof(uint32)) /
873 (sizeof(SAM_ENTRY1)+sizeof(SAM_STR1));
874 q_u->max_entries = (q_u->max_entries>0?q_u->max_entries:1);
877 DEBUG(10,("samr_reply_query_dispinfo: Setting q_u->max_entries to %u\n",q_u->max_entries));
880 got_pwds = get_passwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, q_u->max_entries, 0);
883 /* more left - set resume handle */
884 if(total_entries > num_entries)
889 switch (q_u->switch_level)
894 /* query disp info is for users */
897 init_sam_info_1(&info1, ACB_NORMAL,
898 q_u->start_idx, num_entries, pass);
900 ctr.sam.info1 = &info1;
906 /* query disp info is for servers */
909 init_sam_info_2(&info2, ACB_WSTRUST,
910 q_u->start_idx, num_entries, pass);
912 ctr.sam.info2 = &info2;
919 /* more left - set resume handle */
920 if(total_entries > num_entries)
925 if (r_e.status == 0 || r_e.status == 0x105)
927 init_samr_r_query_dispinfo(&r_e, switch_level, &ctr, r_e.status);
930 /* store the response in the SMB stream */
931 if(!samr_io_r_query_dispinfo("", &r_e, rdata, 0))
934 DEBUG(5,("samr_query_dispinfo: %d\n", __LINE__));
939 /*******************************************************************
940 api_samr_query_dispinfo
941 ********************************************************************/
942 static BOOL api_samr_query_dispinfo(pipes_struct *p)
944 SAMR_Q_QUERY_DISPINFO q_e;
945 prs_struct *data = &p->in_data.data;
946 prs_struct *rdata = &p->out_data.rdata;
948 /* grab the samr open */
949 if(!samr_io_q_query_dispinfo("", &q_e, data, 0))
952 /* construct reply. */
953 if(!samr_reply_query_dispinfo(&q_e, rdata))
960 /*******************************************************************
961 samr_reply_query_aliasinfo
962 ********************************************************************/
963 static BOOL samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
966 SAMR_R_QUERY_ALIASINFO r_e;
967 fstring alias_desc = "Local Unix group";
974 DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__));
976 /* find the policy handle. open a policy on it. */
977 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
979 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
982 alias_rid = get_lsa_policy_samr_rid(&q_u->pol);
983 if(alias_rid == 0xffffffff)
984 r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
986 if(!local_lookup_rid(alias_rid, alias, &type))
988 r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
991 init_samr_r_query_aliasinfo(&r_e, q_u->switch_level, alias, alias_desc);
993 /* store the response in the SMB stream */
994 if(!samr_io_r_query_aliasinfo("", &r_e, rdata, 0))
997 DEBUG(5,("samr_query_aliasinfo: %d\n", __LINE__));
1002 /*******************************************************************
1003 api_samr_query_aliasinfo
1004 ********************************************************************/
1005 static BOOL api_samr_query_aliasinfo(pipes_struct *p)
1007 SAMR_Q_QUERY_ALIASINFO q_e;
1008 prs_struct *data = &p->in_data.data;
1009 prs_struct *rdata = &p->out_data.rdata;
1011 /* grab the samr open */
1012 if(!samr_io_q_query_aliasinfo("", &q_e, data, 0))
1015 /* construct reply. */
1016 if(!samr_reply_query_aliasinfo(&q_e, rdata))
1023 /*******************************************************************
1024 samr_reply_lookup_ids
1025 ********************************************************************/
1026 static BOOL samr_reply_lookup_ids(SAMR_Q_LOOKUP_IDS *q_u,
1029 uint32 rid[MAX_SAM_ENTRIES];
1031 int num_rids = q_u->num_sids1;
1033 SAMR_R_LOOKUP_IDS r_u;
1035 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
1037 if (num_rids > MAX_SAM_ENTRIES)
1039 num_rids = MAX_SAM_ENTRIES;
1040 DEBUG(5,("samr_lookup_ids: truncating entries to %d\n", num_rids));
1045 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1047 for (i = 0; i < num_rids && status == 0; i++)
1049 struct sam_passwd *sam_pass;
1053 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1054 q_u->uni_user_name[i].uni_str_len));
1056 /* find the user account */
1058 sam_pass = get_smb21pwd_entry(user_name, 0);
1061 if (sam_pass == NULL)
1063 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1068 rid[i] = sam_pass->user_rid;
1074 rid[0] = BUILTIN_ALIAS_RID_USERS;
1076 init_samr_r_lookup_ids(&r_u, num_rids, rid, status);
1078 /* store the response in the SMB stream */
1079 if(!samr_io_r_lookup_ids("", &r_u, rdata, 0))
1082 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
1087 /*******************************************************************
1089 ********************************************************************/
1090 static BOOL api_samr_lookup_ids(pipes_struct *p)
1092 SAMR_Q_LOOKUP_IDS q_u;
1093 prs_struct *data = &p->in_data.data;
1094 prs_struct *rdata = &p->out_data.rdata;
1096 /* grab the samr 0x10 */
1097 if(!samr_io_q_lookup_ids("", &q_u, data, 0))
1100 /* construct reply. always indicate success */
1101 if(!samr_reply_lookup_ids(&q_u, rdata))
1107 /*******************************************************************
1108 samr_reply_lookup_names
1109 ********************************************************************/
1111 static BOOL samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
1114 uint32 rid[MAX_SAM_ENTRIES];
1115 uint8 type[MAX_SAM_ENTRIES];
1118 int num_rids = q_u->num_names1;
1121 SAMR_R_LOOKUP_NAMES r_u;
1123 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1128 if (!get_lsa_policy_samr_sid(&q_u->pol, &pol_sid)) {
1129 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
1130 init_samr_r_lookup_names(&r_u, 0, rid, type, status);
1131 if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
1132 DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
1138 if (num_rids > MAX_SAM_ENTRIES) {
1139 num_rids = MAX_SAM_ENTRIES;
1140 DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
1143 SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
1145 for (i = 0; i < num_rids; i++) {
1148 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
1150 rid [i] = 0xffffffff;
1151 type[i] = SID_NAME_UNKNOWN;
1153 fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer,
1154 q_u->uni_name[i].uni_str_len));
1156 if(sid_equal(&pol_sid, &global_sam_sid))
1159 if(local_lookup_name(global_myname, name,
1162 sid_split_rid( &sid, &rid[i]);
1168 init_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
1170 /* store the response in the SMB stream */
1171 if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
1172 DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
1176 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1181 /*******************************************************************
1182 api_samr_lookup_names
1183 ********************************************************************/
1185 static BOOL api_samr_lookup_names(pipes_struct *p)
1187 SAMR_Q_LOOKUP_NAMES q_u;
1188 prs_struct *data = &p->in_data.data;
1189 prs_struct *rdata = &p->out_data.rdata;
1191 memset(&q_u, '\0', sizeof(q_u));
1193 /* grab the samr lookup names */
1194 if(!samr_io_q_lookup_names("", &q_u, data, 0)) {
1195 DEBUG(0,("api_samr_lookup_names: failed to unmarshall SAMR_Q_LOOKUP_NAMES.\n"));
1199 /* construct reply. always indicate success */
1200 if(!samr_reply_lookup_names(&q_u, rdata))
1206 /*******************************************************************
1207 samr_reply_chgpasswd_user
1208 ********************************************************************/
1210 static BOOL samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
1213 SAMR_R_CHGPASSWD_USER r_u;
1214 uint32 status = 0x0;
1218 fstrcpy(user_name, dos_unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len));
1219 fstrcpy(wks , dos_unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len));
1221 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1223 if (!pass_oem_change(user_name,
1224 q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1225 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1227 status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
1230 init_samr_r_chgpasswd_user(&r_u, status);
1232 /* store the response in the SMB stream */
1233 if(!samr_io_r_chgpasswd_user("", &r_u, rdata, 0)) {
1234 DEBUG(0,("samr_reply_chgpasswd_user: Failed to marshall SAMR_R_CHGPASSWD_USER struct.\n" ));
1238 DEBUG(5,("samr_chgpasswd_user: %d\n", __LINE__));
1242 /*******************************************************************
1243 api_samr_chgpasswd_user
1244 ********************************************************************/
1246 static BOOL api_samr_chgpasswd_user(pipes_struct *p)
1248 SAMR_Q_CHGPASSWD_USER q_u;
1249 prs_struct *data = &p->in_data.data;
1250 prs_struct *rdata = &p->out_data.rdata;
1252 /* unknown 38 command */
1253 if (!samr_io_q_chgpasswd_user("", &q_u, data, 0)) {
1254 DEBUG(0,("api_samr_chgpasswd_user: samr_io_q_chgpasswd_user failed to parse RPC packet.\n"));
1258 /* construct reply. */
1259 if(!samr_reply_chgpasswd_user(&q_u, rdata)) {
1260 DEBUG(0,("api_samr_chgpasswd_user: samr_reply_chgpasswd_user failed to create reply packet.\n"));
1268 /*******************************************************************
1269 samr_reply_unknown_38
1270 ********************************************************************/
1271 static BOOL samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u, prs_struct *rdata)
1273 SAMR_R_UNKNOWN_38 r_u;
1275 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1277 init_samr_r_unknown_38(&r_u);
1279 /* store the response in the SMB stream */
1280 if(!samr_io_r_unknown_38("", &r_u, rdata, 0))
1283 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1287 /*******************************************************************
1289 ********************************************************************/
1290 static BOOL api_samr_unknown_38(pipes_struct *p)
1292 SAMR_Q_UNKNOWN_38 q_u;
1293 prs_struct *data = &p->in_data.data;
1294 prs_struct *rdata = &p->out_data.rdata;
1296 /* unknown 38 command */
1297 if(!samr_io_q_unknown_38("", &q_u, data, 0))
1300 /* construct reply. always indicate success */
1301 if(!samr_reply_unknown_38(&q_u, rdata))
1308 /*******************************************************************
1309 samr_reply_unknown_12
1310 ********************************************************************/
1311 static BOOL samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
1314 fstring group_names[MAX_SAM_ENTRIES];
1315 uint32 group_attrs[MAX_SAM_ENTRIES];
1317 int num_gids = q_u->num_gids1;
1319 SAMR_R_UNKNOWN_12 r_u;
1321 DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
1323 /* find the policy handle. open a policy on it. */
1324 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1326 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1332 if (num_gids > MAX_SAM_ENTRIES)
1334 num_gids = MAX_SAM_ENTRIES;
1335 DEBUG(5,("samr_unknown_12: truncating entries to %d\n", num_gids));
1338 for (i = 0; i < num_gids && status == 0; i++)
1340 fstrcpy(group_names[i], "dummy group");
1341 group_attrs[i] = 0x2;
1345 init_samr_r_unknown_12(&r_u, num_gids, group_names, group_attrs, status);
1347 /* store the response in the SMB stream */
1348 if(!samr_io_r_unknown_12("", &r_u, rdata, 0))
1351 DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
1356 /*******************************************************************
1358 ********************************************************************/
1359 static BOOL api_samr_unknown_12(pipes_struct *p)
1361 SAMR_Q_UNKNOWN_12 q_u;
1362 prs_struct *data = &p->in_data.data;
1363 prs_struct *rdata = &p->out_data.rdata;
1365 /* grab the samr lookup names */
1366 if(!samr_io_q_unknown_12("", &q_u, data, 0))
1369 /* construct reply. always indicate success */
1370 if(!samr_reply_unknown_12(&q_u, rdata))
1377 /*******************************************************************
1378 samr_reply_open_user
1379 ********************************************************************/
1380 static BOOL samr_reply_open_user(SAMR_Q_OPEN_USER *q_u, prs_struct *rdata, int status)
1382 SAMR_R_OPEN_USER r_u;
1383 struct sam_passwd *sam_pass;
1384 BOOL pol_open = False;
1386 /* set up the SAMR open_user response */
1387 memset((char *)r_u.user_pol.data, '\0', POL_HND_SIZE);
1391 /* find the policy handle. open a policy on it. */
1392 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
1394 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1397 /* get a (unique) handle. open a policy on it. */
1398 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.user_pol))))
1400 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1404 sam_pass = getsam21pwrid(q_u->user_rid);
1407 /* check that the RID exists in our domain. */
1408 if (r_u.status == 0x0 && sam_pass == NULL)
1410 r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1413 /* associate the RID with the (unique) handle. */
1414 if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.user_pol), q_u->user_rid))
1416 /* oh, whoops. don't know what error message to return, here */
1417 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1420 if (r_u.status != 0 && pol_open)
1422 close_lsa_policy_hnd(&(r_u.user_pol));
1425 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1427 /* store the response in the SMB stream */
1428 if(!samr_io_r_open_user("", &r_u, rdata, 0))
1431 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1436 /*******************************************************************
1438 ********************************************************************/
1439 static BOOL api_samr_open_user(pipes_struct *p)
1441 SAMR_Q_OPEN_USER q_u;
1442 prs_struct *data = &p->in_data.data;
1443 prs_struct *rdata = &p->out_data.rdata;
1445 /* grab the samr unknown 22 */
1446 if(!samr_io_q_open_user("", &q_u, data, 0))
1449 /* construct reply. always indicate success */
1450 if(!samr_reply_open_user(&q_u, rdata, 0x0))
1457 /*************************************************************************
1459 *************************************************************************/
1460 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1462 struct smb_passwd *smb_pass;
1464 if (!pdb_rid_is_user(user_rid))
1466 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1471 smb_pass = getsmbpwrid(user_rid);
1474 if (smb_pass == NULL)
1476 DEBUG(4,("User 0x%x not found\n", user_rid));
1480 DEBUG(3,("User:[%s]\n", smb_pass->smb_name));
1482 init_sam_user_info10(id10, smb_pass->acct_ctrl);
1487 /*************************************************************************
1489 *************************************************************************/
1490 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1493 struct sam_passwd *sam_pass;
1497 if (!pdb_rid_is_user(user_rid))
1499 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1504 sam_pass = getsam21pwrid(user_rid);
1507 if (sam_pass == NULL)
1509 DEBUG(4,("User 0x%x not found\n", user_rid));
1513 DEBUG(3,("User:[%s]\n", sam_pass->smb_name));
1515 dummy_time.low = 0xffffffff;
1516 dummy_time.high = 0x7fffffff;
1518 DEBUG(5,("get_user_info_21 - TODO: convert unix times to NTTIMEs\n"));
1520 /* create a LOGON_HRS structure */
1521 hrs.len = sam_pass->hours_len;
1522 SMB_ASSERT_ARRAY(hrs.hours, hrs.len);
1523 for (i = 0; i < hrs.len; i++)
1525 hrs.hours[i] = sam_pass->hours[i];
1528 init_sam_user_info21(id21,
1530 &dummy_time, /* logon_time */
1531 &dummy_time, /* logoff_time */
1532 &dummy_time, /* kickoff_time */
1533 &dummy_time, /* pass_last_set_time */
1534 &dummy_time, /* pass_can_change_time */
1535 &dummy_time, /* pass_must_change_time */
1537 sam_pass->smb_name, /* user_name */
1538 sam_pass->full_name, /* full_name */
1539 sam_pass->home_dir, /* home_dir */
1540 sam_pass->dir_drive, /* dir_drive */
1541 sam_pass->logon_script, /* logon_script */
1542 sam_pass->profile_path, /* profile_path */
1543 sam_pass->acct_desc, /* description */
1544 sam_pass->workstations, /* workstations user can log in from */
1545 sam_pass->unknown_str, /* don't know, yet */
1546 sam_pass->munged_dial, /* dialin info. contains dialin path and tel no */
1548 sam_pass->user_rid, /* RID user_id */
1549 sam_pass->group_rid, /* RID group_id */
1550 sam_pass->acct_ctrl,
1552 sam_pass->unknown_3, /* unknown_3 */
1553 sam_pass->logon_divs, /* divisions per week */
1554 &hrs, /* logon hours */
1555 sam_pass->unknown_5,
1556 sam_pass->unknown_6);
1561 /*******************************************************************
1562 samr_reply_query_userinfo
1563 ********************************************************************/
1564 static BOOL samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
1567 SAMR_R_QUERY_USERINFO r_u;
1569 SAM_USER_INFO_11 id11;
1571 SAM_USER_INFO_10 id10;
1572 SAM_USER_INFO_21 id21;
1575 uint32 status = 0x0;
1578 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1580 /* search for the handle */
1581 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1583 status = NT_STATUS_INVALID_HANDLE;
1586 /* find the user's rid */
1587 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1589 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1592 DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
1594 /* ok! user info levels (there are lots: see MSDEV help), off we go... */
1597 switch (q_u->switch_value)
1601 info = (void*)&id10;
1602 status = get_user_info_10(&id10, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1606 /* whoops - got this wrong. i think. or don't understand what's happening. */
1610 info = (void*)&id11;
1612 expire.low = 0xffffffff;
1613 expire.high = 0x7fffffff;
1615 make_sam_user_info11(&id11, &expire, "BROOKFIELDS$", 0x03ef, 0x201, 0x0080);
1622 info = (void*)&id21;
1623 status = get_user_info_21(&id21, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1629 status = NT_STATUS_INVALID_INFO_CLASS;
1636 init_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
1638 /* store the response in the SMB stream */
1639 if(!samr_io_r_query_userinfo("", &r_u, rdata, 0))
1642 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1647 /*******************************************************************
1648 api_samr_query_userinfo
1649 ********************************************************************/
1650 static BOOL api_samr_query_userinfo(pipes_struct *p)
1652 SAMR_Q_QUERY_USERINFO q_u;
1653 prs_struct *data = &p->in_data.data;
1654 prs_struct *rdata = &p->out_data.rdata;
1656 /* grab the samr unknown 24 */
1657 if(!samr_io_q_query_userinfo("", &q_u, data, 0))
1660 /* construct reply. always indicate success */
1661 if(!samr_reply_query_userinfo(&q_u, rdata))
1668 /*******************************************************************
1669 samr_reply_query_usergroups
1670 ********************************************************************/
1671 static BOOL samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
1674 SAMR_R_QUERY_USERGROUPS r_u;
1675 uint32 status = 0x0;
1677 struct sam_passwd *sam_pass;
1678 DOM_GID *gids = NULL;
1682 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1684 /* find the policy handle. open a policy on it. */
1685 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1687 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1690 /* find the user's rid */
1691 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1693 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1699 sam_pass = getsam21pwrid(rid);
1702 if (sam_pass == NULL)
1704 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1711 get_domain_user_groups(groups, sam_pass->smb_name);
1713 num_groups = make_dom_gids(groups, &gids);
1716 /* construct the response. lkclXXXX: gids are not copied! */
1717 init_samr_r_query_usergroups(&r_u, num_groups, gids, status);
1719 /* store the response in the SMB stream */
1720 if(!samr_io_r_query_usergroups("", &r_u, rdata, 0)) {
1729 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1734 /*******************************************************************
1735 api_samr_query_usergroups
1736 ********************************************************************/
1737 static BOOL api_samr_query_usergroups(pipes_struct *p)
1739 SAMR_Q_QUERY_USERGROUPS q_u;
1740 prs_struct *data = &p->in_data.data;
1741 prs_struct *rdata = &p->out_data.rdata;
1743 /* grab the samr unknown 32 */
1744 if(!samr_io_q_query_usergroups("", &q_u, data, 0))
1747 /* construct reply. */
1748 if(!samr_reply_query_usergroups(&q_u, rdata))
1755 /*******************************************************************
1756 samr_reply_query_dom_info
1757 ********************************************************************/
1758 static BOOL samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_struct *rdata)
1760 SAMR_R_QUERY_DOMAIN_INFO r_u;
1762 uint16 switch_value = 0x0;
1763 uint32 status = 0x0;
1770 DEBUG(5,("samr_reply_query_dom_info: %d\n", __LINE__));
1772 /* find the policy handle. open a policy on it. */
1773 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
1775 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1776 DEBUG(5,("samr_reply_query_dom_info: invalid handle\n"));
1781 switch (q_u->switch_value)
1786 init_unk_info2(&ctr.info.inf2, global_myworkgroup, global_myname);
1792 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
1798 init_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
1800 /* store the response in the SMB stream */
1801 if(!samr_io_r_query_dom_info("", &r_u, rdata, 0))
1804 DEBUG(5,("samr_query_dom_info: %d\n", __LINE__));
1809 /*******************************************************************
1810 api_samr_query_dom_info
1811 ********************************************************************/
1812 static BOOL api_samr_query_dom_info(pipes_struct *p)
1814 SAMR_Q_QUERY_DOMAIN_INFO q_e;
1815 prs_struct *data = &p->in_data.data;
1816 prs_struct *rdata = &p->out_data.rdata;
1818 /* grab the samr unknown 8 command */
1819 if(!samr_io_q_query_dom_info("", &q_e, data, 0))
1822 /* construct reply. */
1823 if(!samr_reply_query_dom_info(&q_e, rdata))
1830 /*******************************************************************
1831 api_samr_create_user
1832 ********************************************************************/
1833 static BOOL api_samr_create_user(pipes_struct *p)
1835 struct sam_passwd *sam_pass;
1841 prs_struct *data = &p->in_data.data;
1842 prs_struct *rdata = &p->out_data.rdata;
1844 SAMR_Q_CREATE_USER q_u;
1845 SAMR_R_CREATE_USER r_u;
1850 DEBUG(5,("api_samr_create_user: %d\n", __LINE__));
1852 /* grab the samr create user */
1853 samr_io_q_create_user("", &q_u, data, 0);
1855 /* find the policy handle. open a policy on it. */
1856 if ((find_lsa_policy_by_hnd(&q_u.pol) == -1)) {
1857 r_u.status = NT_STATUS_INVALID_HANDLE;
1861 /* find the machine account: tell the caller if it exists.
1862 lkclXXXX i have *no* idea if this is a problem or not
1863 or even if you are supposed to construct a different
1864 reply if the account already exists...
1867 fstrcpy(mach_acct, dos_unistrn2(q_u.uni_mach_acct.buffer, q_u.uni_mach_acct.uni_str_len));
1868 strlower(mach_acct);
1871 sam_pass = getsam21pwnam(mach_acct);
1873 if (sam_pass != NULL) {
1874 /* machine account exists: say so */
1875 r_u.status = NT_STATUS_USER_EXISTS;
1879 /* get a (unique) handle. open a policy on it. */
1880 if (!open_lsa_policy_hnd(&r_u.pol)) {
1881 r_u.status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1885 local_flags=LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_SET_NO_PASSWORD;
1886 local_flags|= (q_u.acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0;
1888 if (!local_password_change(mach_acct, local_flags, NULL, err_str, sizeof(err_str), msg_str, sizeof(msg_str))) {
1889 DEBUG(0, ("%s\n", err_str));
1890 r_u.status = NT_STATUS_ACCESS_DENIED;
1891 close_lsa_policy_hnd(&r_u.pol);
1892 memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
1897 sam_pass = getsam21pwnam(mach_acct);
1899 if (sam_pass == NULL) {
1900 /* account doesn't exist: say so */
1901 r_u.status = NT_STATUS_ACCESS_DENIED;
1902 close_lsa_policy_hnd(&r_u.pol);
1903 memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
1907 /* associate the RID with the (unique) handle. */
1908 if (!set_lsa_policy_samr_rid(&r_u.pol, sam_pass->user_rid)) {
1909 /* oh, whoops. don't know what error message to return, here */
1910 r_u.status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1911 close_lsa_policy_hnd(&r_u.pol);
1912 memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
1916 r_u.unknown_0=0x000703ff;
1917 r_u.user_rid=sam_pass->user_rid;
1920 /* store the response in the SMB stream */
1921 if(!samr_io_r_create_user("", &r_u, rdata, 0))
1924 DEBUG(5,("api_samr_create_user: %d\n", __LINE__));
1930 /*******************************************************************
1931 samr_reply_connect_anon
1932 ********************************************************************/
1933 static BOOL samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u, prs_struct *rdata)
1935 SAMR_R_CONNECT_ANON r_u;
1936 BOOL pol_open = False;
1938 /* set up the SAMR connect_anon response */
1941 /* get a (unique) handle. open a policy on it. */
1942 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1944 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1947 /* associate the domain SID with the (unique) handle. */
1948 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1950 /* oh, whoops. don't know what error message to return, here */
1951 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1954 if (r_u.status != 0 && pol_open)
1956 close_lsa_policy_hnd(&(r_u.connect_pol));
1959 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1961 /* store the response in the SMB stream */
1962 if(!samr_io_r_connect_anon("", &r_u, rdata, 0))
1965 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1970 /*******************************************************************
1971 api_samr_connect_anon
1972 ********************************************************************/
1973 static BOOL api_samr_connect_anon(pipes_struct *p)
1975 SAMR_Q_CONNECT_ANON q_u;
1976 prs_struct *data = &p->in_data.data;
1977 prs_struct *rdata = &p->out_data.rdata;
1979 /* grab the samr open policy */
1980 if(!samr_io_q_connect_anon("", &q_u, data, 0))
1983 /* construct reply. always indicate success */
1984 if(!samr_reply_connect_anon(&q_u, rdata))
1990 /*******************************************************************
1992 ********************************************************************/
1993 static BOOL samr_reply_connect(SAMR_Q_CONNECT *q_u, prs_struct *rdata)
1996 BOOL pol_open = False;
1998 /* set up the SAMR connect response */
2001 /* get a (unique) handle. open a policy on it. */
2002 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
2004 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2007 /* associate the domain SID with the (unique) handle. */
2008 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
2010 /* oh, whoops. don't know what error message to return, here */
2011 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2014 if (r_u.status != 0 && pol_open)
2016 close_lsa_policy_hnd(&(r_u.connect_pol));
2019 DEBUG(5,("samr_connect: %d\n", __LINE__));
2021 /* store the response in the SMB stream */
2022 if(!samr_io_r_connect("", &r_u, rdata, 0))
2025 DEBUG(5,("samr_connect: %d\n", __LINE__));
2030 /*******************************************************************
2032 ********************************************************************/
2033 static BOOL api_samr_connect(pipes_struct *p)
2036 prs_struct *data = &p->in_data.data;
2037 prs_struct *rdata = &p->out_data.rdata;
2039 /* grab the samr open policy */
2040 if(!samr_io_q_connect("", &q_u, data, 0))
2043 /* construct reply. always indicate success */
2044 if(!samr_reply_connect(&q_u, rdata))
2050 /**********************************************************************
2051 api_reply_lookup_domain
2052 **********************************************************************/
2053 static BOOL samr_reply_lookup_domain(SAMR_Q_LOOKUP_DOMAIN* q_u, prs_struct* rdata)
2055 SAMR_R_LOOKUP_DOMAIN r_u;
2058 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->connect_pol)) == -1))
2060 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
2061 DEBUG(5,("samr_reply_lookup_domain: invalid handle\n"));
2064 /* assume the domain name sent is our global_myname and
2065 send global_sam_sid */
2066 init_samr_r_lookup_domain(&r_u, &global_sam_sid, r_u.status);
2068 if(!samr_io_r_lookup_domain("", &r_u, rdata, 0))
2071 DEBUG(5,("samr_reply_lookup_domain: %d\n", __LINE__));
2076 /**********************************************************************
2077 api_samr_lookup_domain
2078 **********************************************************************/
2079 static BOOL api_samr_lookup_domain(pipes_struct *p)
2081 SAMR_Q_LOOKUP_DOMAIN q_u;
2082 prs_struct *data = &p->in_data.data;
2083 prs_struct *rdata = &p->out_data.rdata;
2085 if(!samr_io_q_lookup_domain("", &q_u, data, 0))
2088 if(!samr_reply_lookup_domain(&q_u, rdata))
2094 /**********************************************************************
2095 samr_reply_enum_domains
2096 **********************************************************************/
2097 static BOOL samr_reply_enum_domains(SAMR_Q_ENUM_DOMAINS* q_u, prs_struct* rdata)
2099 SAMR_R_ENUM_DOMAINS r_u;
2104 fstrcpy(dom[0],global_myname);
2105 fstrcpy(dom[1],"Builtin");
2108 init_samr_r_enum_domains(&r_u, q_u->start_idx, dom, 2);
2109 if(!samr_io_r_enum_domains("", &r_u, rdata, 0)) {
2111 free(r_u.uni_dom_name);
2116 free(r_u.uni_dom_name);
2121 /**********************************************************************
2122 api_samr_enum_domains
2123 **********************************************************************/
2124 static BOOL api_samr_enum_domains(pipes_struct *p)
2126 SAMR_Q_ENUM_DOMAINS q_u;
2127 prs_struct *data = &p->in_data.data;
2128 prs_struct *rdata = &p->out_data.rdata;
2130 if(!samr_io_q_enum_domains("", &q_u, data, 0))
2133 if(!samr_reply_enum_domains(&q_u, rdata))
2139 /*******************************************************************
2140 samr_reply_open_alias
2141 ********************************************************************/
2142 static BOOL samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u, prs_struct *rdata)
2144 SAMR_R_OPEN_ALIAS r_u;
2145 BOOL pol_open = False;
2147 /* set up the SAMR open_alias response */
2150 /* get a (unique) handle. open a policy on it. */
2151 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.pol))))
2153 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2156 /* associate a RID with the (unique) handle. */
2157 if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.pol), q_u->rid_alias))
2159 /* oh, whoops. don't know what error message to return, here */
2160 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2163 if (r_u.status != 0 && pol_open)
2165 close_lsa_policy_hnd(&(r_u.pol));
2168 DEBUG(5,("samr_open_alias: %d\n", __LINE__));
2170 /* store the response in the SMB stream */
2171 if(!samr_io_r_open_alias("", &r_u, rdata, 0))
2174 DEBUG(5,("samr_open_alias: %d\n", __LINE__));
2179 /*******************************************************************
2181 ********************************************************************/
2182 static BOOL api_samr_open_alias(pipes_struct *p)
2184 SAMR_Q_OPEN_ALIAS q_u;
2185 prs_struct *data = &p->in_data.data;
2186 prs_struct *rdata = &p->out_data.rdata;
2188 /* grab the samr open policy */
2189 if(!samr_io_q_open_alias("", &q_u, data, 0))
2192 /* construct reply. always indicate success */
2193 if(!samr_reply_open_alias(&q_u, rdata))
2199 /*******************************************************************
2200 array of \PIPE\samr operations
2201 ********************************************************************/
2202 static struct api_struct api_samr_cmds [] =
2204 { "SAMR_CLOSE_HND" , SAMR_CLOSE_HND , api_samr_close_hnd },
2205 { "SAMR_CONNECT" , SAMR_CONNECT , api_samr_connect },
2206 { "SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON , api_samr_connect_anon },
2207 { "SAMR_ENUM_DOM_USERS" , SAMR_ENUM_DOM_USERS , api_samr_enum_dom_users },
2208 { "SAMR_ENUM_DOM_GROUPS" , SAMR_ENUM_DOM_GROUPS , api_samr_enum_dom_groups },
2209 { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
2210 { "SAMR_LOOKUP_IDS" , SAMR_LOOKUP_IDS , api_samr_lookup_ids },
2211 { "SAMR_LOOKUP_NAMES" , SAMR_LOOKUP_NAMES , api_samr_lookup_names },
2212 { "SAMR_OPEN_USER" , SAMR_OPEN_USER , api_samr_open_user },
2213 { "SAMR_QUERY_USERINFO" , SAMR_QUERY_USERINFO , api_samr_query_userinfo },
2214 { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
2215 { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
2216 { "SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo },
2217 { "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo },
2218 { "SAMR_CREATE_USER" , SAMR_CREATE_USER , api_samr_create_user },
2219 { "SAMR_UNKNOWN_12" , SAMR_UNKNOWN_12 , api_samr_unknown_12 },
2220 { "SAMR_UNKNOWN_38" , SAMR_UNKNOWN_38 , api_samr_unknown_38 },
2221 { "SAMR_CHGPASSWD_USER" , SAMR_CHGPASSWD_USER , api_samr_chgpasswd_user },
2222 { "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias },
2223 { "SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain },
2224 { "SAMR_UNKNOWN_3" , SAMR_UNKNOWN_3 , api_samr_unknown_3 },
2225 { "SAMR_UNKNOWN_2C" , SAMR_UNKNOWN_2C , api_samr_unknown_2c },
2226 { "SAMR_LOOKUP_DOMAIN" , SAMR_LOOKUP_DOMAIN , api_samr_lookup_domain },
2227 { "SAMR_ENUM_DOMAINS" , SAMR_ENUM_DOMAINS , api_samr_enum_domains },
2231 /*******************************************************************
2232 receives a samr pipe and responds.
2233 ********************************************************************/
2234 BOOL api_samr_rpc(pipes_struct *p)
2236 return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds);