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))
1829 /*******************************************************************
1830 samr_reply_unknown_32
1831 ********************************************************************/
1832 static BOOL samr_reply_unknown_32(SAMR_Q_UNKNOWN_32 *q_u,
1837 SAMR_R_UNKNOWN_32 r_u;
1839 /* set up the SAMR unknown_32 response */
1840 memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
1843 for (i = 4; i < POL_HND_SIZE; i++)
1845 r_u.pol.data[i] = i+1;
1849 init_dom_rid4(&(r_u.rid4), 0x0030, 0, 0);
1850 r_u.status = status;
1852 DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
1854 /* store the response in the SMB stream */
1855 if(!samr_io_r_unknown_32("", &r_u, rdata, 0))
1858 DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
1863 /*******************************************************************
1865 ********************************************************************/
1866 static BOOL api_samr_unknown_32(pipes_struct *p)
1869 struct sam_passwd *sam_pass;
1871 prs_struct *data = &p->in_data.data;
1872 prs_struct *rdata = &p->out_data.rdata;
1874 SAMR_Q_UNKNOWN_32 q_u;
1876 /* grab the samr unknown 32 */
1877 samr_io_q_unknown_32("", &q_u, data, 0);
1879 /* find the machine account: tell the caller if it exists.
1880 lkclXXXX i have *no* idea if this is a problem or not
1881 or even if you are supposed to construct a different
1882 reply if the account already exists...
1885 fstrcpy(mach_acct, dos_unistrn2(q_u.uni_mach_acct.buffer,
1886 q_u.uni_mach_acct.uni_str_len));
1889 sam_pass = getsam21pwnam(mach_acct);
1892 if (sam_pass != NULL)
1894 /* machine account exists: say so */
1895 status = 0xC0000000 | NT_STATUS_USER_EXISTS;
1899 /* this could cause trouble... */
1900 DEBUG(0,("trouble!\n"));
1904 /* construct reply. */
1905 if(!samr_reply_unknown_32(&q_u, rdata, status))
1912 /*******************************************************************
1913 samr_reply_connect_anon
1914 ********************************************************************/
1915 static BOOL samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u, prs_struct *rdata)
1917 SAMR_R_CONNECT_ANON r_u;
1918 BOOL pol_open = False;
1920 /* set up the SAMR connect_anon response */
1923 /* get a (unique) handle. open a policy on it. */
1924 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1926 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1929 /* associate the domain SID with the (unique) handle. */
1930 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1932 /* oh, whoops. don't know what error message to return, here */
1933 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1936 if (r_u.status != 0 && pol_open)
1938 close_lsa_policy_hnd(&(r_u.connect_pol));
1941 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1943 /* store the response in the SMB stream */
1944 if(!samr_io_r_connect_anon("", &r_u, rdata, 0))
1947 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1952 /*******************************************************************
1953 api_samr_connect_anon
1954 ********************************************************************/
1955 static BOOL api_samr_connect_anon(pipes_struct *p)
1957 SAMR_Q_CONNECT_ANON q_u;
1958 prs_struct *data = &p->in_data.data;
1959 prs_struct *rdata = &p->out_data.rdata;
1961 /* grab the samr open policy */
1962 if(!samr_io_q_connect_anon("", &q_u, data, 0))
1965 /* construct reply. always indicate success */
1966 if(!samr_reply_connect_anon(&q_u, rdata))
1972 /*******************************************************************
1974 ********************************************************************/
1975 static BOOL samr_reply_connect(SAMR_Q_CONNECT *q_u, prs_struct *rdata)
1978 BOOL pol_open = False;
1980 /* set up the SAMR connect response */
1983 /* get a (unique) handle. open a policy on it. */
1984 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1986 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1989 /* associate the domain SID with the (unique) handle. */
1990 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1992 /* oh, whoops. don't know what error message to return, here */
1993 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1996 if (r_u.status != 0 && pol_open)
1998 close_lsa_policy_hnd(&(r_u.connect_pol));
2001 DEBUG(5,("samr_connect: %d\n", __LINE__));
2003 /* store the response in the SMB stream */
2004 if(!samr_io_r_connect("", &r_u, rdata, 0))
2007 DEBUG(5,("samr_connect: %d\n", __LINE__));
2012 /*******************************************************************
2014 ********************************************************************/
2015 static BOOL api_samr_connect(pipes_struct *p)
2018 prs_struct *data = &p->in_data.data;
2019 prs_struct *rdata = &p->out_data.rdata;
2021 /* grab the samr open policy */
2022 if(!samr_io_q_connect("", &q_u, data, 0))
2025 /* construct reply. always indicate success */
2026 if(!samr_reply_connect(&q_u, rdata))
2032 /**********************************************************************
2033 api_reply_lookup_domain
2034 **********************************************************************/
2035 static BOOL samr_reply_lookup_domain(SAMR_Q_LOOKUP_DOMAIN* q_u, prs_struct* rdata)
2037 SAMR_R_LOOKUP_DOMAIN r_u;
2040 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->connect_pol)) == -1))
2042 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
2043 DEBUG(5,("samr_reply_lookup_domain: invalid handle\n"));
2046 /* assume the domain name sent is our global_myname and
2047 send global_sam_sid */
2048 init_samr_r_lookup_domain(&r_u, &global_sam_sid, r_u.status);
2050 if(!samr_io_r_lookup_domain("", &r_u, rdata, 0))
2053 DEBUG(5,("samr_reply_lookup_domain: %d\n", __LINE__));
2058 /**********************************************************************
2059 api_samr_lookup_domain
2060 **********************************************************************/
2061 static BOOL api_samr_lookup_domain(pipes_struct *p)
2063 SAMR_Q_LOOKUP_DOMAIN q_u;
2064 prs_struct *data = &p->in_data.data;
2065 prs_struct *rdata = &p->out_data.rdata;
2067 if(!samr_io_q_lookup_domain("", &q_u, data, 0))
2070 if(!samr_reply_lookup_domain(&q_u, rdata))
2076 /**********************************************************************
2077 samr_reply_enum_domains
2078 **********************************************************************/
2079 static BOOL samr_reply_enum_domains(SAMR_Q_ENUM_DOMAINS* q_u, prs_struct* rdata)
2081 SAMR_R_ENUM_DOMAINS r_u;
2086 fstrcpy(dom[0],global_myname);
2087 fstrcpy(dom[1],"Builtin");
2090 init_samr_r_enum_domains(&r_u, q_u->start_idx, dom, 2);
2091 if(!samr_io_r_enum_domains("", &r_u, rdata, 0)) {
2093 free(r_u.uni_dom_name);
2098 free(r_u.uni_dom_name);
2103 /**********************************************************************
2104 api_samr_enum_domains
2105 **********************************************************************/
2106 static BOOL api_samr_enum_domains(pipes_struct *p)
2108 SAMR_Q_ENUM_DOMAINS q_u;
2109 prs_struct *data = &p->in_data.data;
2110 prs_struct *rdata = &p->out_data.rdata;
2112 if(!samr_io_q_enum_domains("", &q_u, data, 0))
2115 if(!samr_reply_enum_domains(&q_u, rdata))
2121 /*******************************************************************
2122 samr_reply_open_alias
2123 ********************************************************************/
2124 static BOOL samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u, prs_struct *rdata)
2126 SAMR_R_OPEN_ALIAS r_u;
2127 BOOL pol_open = False;
2129 /* set up the SAMR open_alias response */
2132 /* get a (unique) handle. open a policy on it. */
2133 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.pol))))
2135 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2138 /* associate a RID with the (unique) handle. */
2139 if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.pol), q_u->rid_alias))
2141 /* oh, whoops. don't know what error message to return, here */
2142 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2145 if (r_u.status != 0 && pol_open)
2147 close_lsa_policy_hnd(&(r_u.pol));
2150 DEBUG(5,("samr_open_alias: %d\n", __LINE__));
2152 /* store the response in the SMB stream */
2153 if(!samr_io_r_open_alias("", &r_u, rdata, 0))
2156 DEBUG(5,("samr_open_alias: %d\n", __LINE__));
2161 /*******************************************************************
2163 ********************************************************************/
2164 static BOOL api_samr_open_alias(pipes_struct *p)
2166 SAMR_Q_OPEN_ALIAS q_u;
2167 prs_struct *data = &p->in_data.data;
2168 prs_struct *rdata = &p->out_data.rdata;
2170 /* grab the samr open policy */
2171 if(!samr_io_q_open_alias("", &q_u, data, 0))
2174 /* construct reply. always indicate success */
2175 if(!samr_reply_open_alias(&q_u, rdata))
2181 /*******************************************************************
2182 array of \PIPE\samr operations
2183 ********************************************************************/
2184 static struct api_struct api_samr_cmds [] =
2186 { "SAMR_CLOSE_HND" , SAMR_CLOSE_HND , api_samr_close_hnd },
2187 { "SAMR_CONNECT" , SAMR_CONNECT , api_samr_connect },
2188 { "SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON , api_samr_connect_anon },
2189 { "SAMR_ENUM_DOM_USERS" , SAMR_ENUM_DOM_USERS , api_samr_enum_dom_users },
2190 { "SAMR_ENUM_DOM_GROUPS" , SAMR_ENUM_DOM_GROUPS , api_samr_enum_dom_groups },
2191 { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
2192 { "SAMR_LOOKUP_IDS" , SAMR_LOOKUP_IDS , api_samr_lookup_ids },
2193 { "SAMR_LOOKUP_NAMES" , SAMR_LOOKUP_NAMES , api_samr_lookup_names },
2194 { "SAMR_OPEN_USER" , SAMR_OPEN_USER , api_samr_open_user },
2195 { "SAMR_QUERY_USERINFO" , SAMR_QUERY_USERINFO , api_samr_query_userinfo },
2196 { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
2197 { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
2198 { "SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo },
2199 { "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo },
2200 { "SAMR_0x32" , 0x32 , api_samr_unknown_32 },
2201 { "SAMR_UNKNOWN_12" , SAMR_UNKNOWN_12 , api_samr_unknown_12 },
2202 { "SAMR_UNKNOWN_38" , SAMR_UNKNOWN_38 , api_samr_unknown_38 },
2203 { "SAMR_CHGPASSWD_USER" , SAMR_CHGPASSWD_USER , api_samr_chgpasswd_user },
2204 { "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias },
2205 { "SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain },
2206 { "SAMR_UNKNOWN_3" , SAMR_UNKNOWN_3 , api_samr_unknown_3 },
2207 { "SAMR_UNKNOWN_2C" , SAMR_UNKNOWN_2C , api_samr_unknown_2c },
2208 { "SAMR_LOOKUP_DOMAIN" , SAMR_LOOKUP_DOMAIN , api_samr_lookup_domain },
2209 { "SAMR_ENUM_DOMAINS" , SAMR_ENUM_DOMAINS , api_samr_enum_domains },
2213 /*******************************************************************
2214 receives a samr pipe and responds.
2215 ********************************************************************/
2216 BOOL api_samr_rpc(pipes_struct *p)
2218 return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds);