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, int start_idx,
44 int *total_entries, int *num_entries,
45 int max_num_entries, uint16 acb_mask)
47 SAM_ACCOUNT *pwd = NULL;
55 if (!pdb_setsampwent(False))
57 DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n"));
61 while ( ((pwd=pdb_getsampwent()) != NULL) && ((*num_entries) < max_num_entries) )
66 /* skip the requested number of entries.
67 not very efficient, but hey...
73 user_name_len = strlen(pdb_get_username(pwd))+1;
74 init_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pdb_get_username(pwd), user_name_len);
75 init_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
76 pw_buf[(*num_entries)].user_rid = pdb_get_user_rid(pwd);
77 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
79 /* Now check if the NT compatible password is available. */
80 if (pdb_get_nt_passwd(pwd) != NULL)
82 memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
85 pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
87 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
88 (*num_entries), pdb_get_username(pwd),
89 pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd)));
91 if (acb_mask == 0 || (pdb_get_acct_ctrl(pwd) & acb_mask))
93 DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
98 DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
106 return (*num_entries) > 0;
109 /*******************************************************************
110 This function uses the username map file and tries to map a UNIX
111 user name to an DOS name. (Sort of the reverse of the
112 map_username() function.) Since more than one DOS name can map
113 to the UNIX name, to reverse the mapping you have to specify
114 which corresponding DOS name you want; that's where the name_idx
115 parameter comes in. Returns the string requested or NULL if it
116 fails or can't complete the request for any reason. This doesn't
117 handle group names (starting with '@') or names starting with
118 '+' or '&'. If they are encountered, they are skipped.
119 ********************************************************************/
121 static char *unmap_unixname(char *unix_user_name, int name_idx)
123 char *mapfile = lp_username_map();
128 if (!*unix_user_name) return NULL;
129 if (!*mapfile) return NULL;
131 lines = file_lines_load(mapfile, NULL,False);
133 DEBUG(0,("unmap_unixname: can't open username map %s\n", mapfile));
137 DEBUG(5,("unmap_unixname: scanning username map %s, index: %d\n", mapfile, name_idx));
139 for (i=0; lines[i]; i++) {
140 char *unixname = lines[i];
141 char *dosname = strchr(unixname,'=');
148 while (isspace(*unixname))
150 if ('!' == *unixname) {
152 while (*unixname && isspace(*unixname))
156 if (!*unixname || strchr("#;",*unixname))
159 if (strncmp(unixname, unix_user_name, strlen(unix_user_name)))
162 /* We have matched the UNIX user name */
164 while(next_token(&dosname, tok, LIST_SEP, sizeof(tok))) {
165 if (!strchr("@&+", *tok)) {
174 DEBUG(0,("unmap_unixname: index too high - not that many DOS names\n"));
175 file_lines_free(lines);
178 file_lines_free(lines);
183 DEBUG(0,("unmap_unixname: Couldn't find the UNIX user name\n"));
184 file_lines_free(lines);
188 /*******************************************************************
189 This function sets up a list of users taken from the list of
190 users that UNIX knows about, as well as all the user names that
191 Samba maps to a valid UNIX user name. (This should work with
193 ********************************************************************/
195 static BOOL get_passwd_entries(SAM_USER_INFO_21 *pw_buf,
197 int *total_entries, int *num_entries,
201 static struct passwd *pwd = NULL;
202 static uint32 pw_rid;
203 static BOOL orig_done = False;
204 static int current_idx = 0;
205 static int mapped_idx = 0;
208 DEBUG(5, ("get_passwd_entries: retrieving a list of UNIX users\n"));
211 (*total_entries) = 0;
213 /* Skip all this stuff if we're in appliance mode */
215 if (lp_hide_local_users()) goto done;
217 if (pw_buf == NULL) return False;
219 if (current_idx == 0) {
223 /* These two cases are inefficient, but should be called very rarely */
224 /* they are the cases where the starting index isn't picking up */
225 /* where we left off last time. It is efficient when it starts over */
226 /* at zero though. */
227 if (start_idx > current_idx) {
228 /* We aren't far enough; advance to start_idx */
229 while (current_idx < start_idx) {
233 if ((pwd = sys_getpwent()) == NULL) break;
238 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
239 (current_idx < start_idx)) {
244 if (unmap_name == NULL) {
249 } else if (start_idx < current_idx) {
250 /* We are already too far; start over and advance to start_idx */
256 while (current_idx < start_idx) {
260 if ((pwd = sys_getpwent()) == NULL) break;
265 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
266 (current_idx < start_idx)) {
271 if (unmap_name == NULL) {
278 sep = lp_winbind_separator();
280 /* now current_idx == start_idx */
281 while ((*num_entries) < max_num_entries) {
285 /* This does the original UNIX user itself */
287 if ((pwd = sys_getpwent()) == NULL) break;
289 /* Don't enumerate winbind users as they are not local */
291 if (strchr(pwd->pw_name, *sep) != NULL) {
295 user_name_len = strlen(pwd->pw_name);
296 pw_rid = pdb_uid_to_user_rid(pwd->pw_uid);
297 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
298 init_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->pw_name, user_name_len);
299 init_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
300 pw_buf[(*num_entries)].user_rid = pw_rid;
301 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
303 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
305 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
313 /* This does all the user names that map to the UNIX user */
314 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
315 (*num_entries < max_num_entries)) {
316 user_name_len = strlen(unmap_name);
317 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
318 init_unistr2(&(pw_buf[(*num_entries)].uni_user_name), unmap_name, user_name_len);
319 init_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
320 pw_buf[(*num_entries)].user_rid = pw_rid;
321 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
323 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
325 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
333 if (unmap_name == NULL) {
334 /* done with 'aliases', go on to next UNIX user */
341 /* totally done, reset everything */
348 return (*num_entries) > 0;
351 /*******************************************************************
353 ********************************************************************/
354 static BOOL samr_reply_close_hnd(SAMR_Q_CLOSE_HND *q_u,
357 SAMR_R_CLOSE_HND r_u;
359 /* set up the SAMR unknown_1 response */
360 memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
362 /* close the policy handle */
363 if (close_lsa_policy_hnd(&(q_u->pol)))
369 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_INVALID;
372 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
374 /* store the response in the SMB stream */
375 if(!samr_io_r_close_hnd("", &r_u, rdata, 0))
378 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
383 /*******************************************************************
385 ********************************************************************/
386 static BOOL api_samr_close_hnd(pipes_struct *p)
388 SAMR_Q_CLOSE_HND q_u;
389 prs_struct *data = &p->in_data.data;
390 prs_struct *rdata = &p->out_data.rdata;
392 /* grab the samr unknown 1 */
393 if(!samr_io_q_close_hnd("", &q_u, data, 0))
396 /* construct reply. always indicate success */
397 if(!samr_reply_close_hnd(&q_u, rdata))
404 /*******************************************************************
405 samr_reply_open_domain
406 ********************************************************************/
407 static BOOL samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
410 SAMR_R_OPEN_DOMAIN r_u;
411 BOOL pol_open = False;
415 /* find the connection policy handle. */
416 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
418 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
421 /* get a (unique) handle. open a policy on it. */
422 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.domain_pol))))
424 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
427 /* associate the domain SID with the (unique) handle. */
428 if (r_u.status == 0x0 && !set_lsa_policy_samr_sid(&(r_u.domain_pol), &(q_u->dom_sid.sid)))
430 /* oh, whoops. don't know what error message to return, here */
431 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
434 if (r_u.status != 0 && pol_open)
436 close_lsa_policy_hnd(&(r_u.domain_pol));
439 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
441 /* store the response in the SMB stream */
442 if(!samr_io_r_open_domain("", &r_u, rdata, 0))
445 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
450 /*******************************************************************
452 ********************************************************************/
453 static BOOL api_samr_open_domain(pipes_struct *p)
455 SAMR_Q_OPEN_DOMAIN q_u;
456 prs_struct *data = &p->in_data.data;
457 prs_struct *rdata = &p->out_data.rdata;
459 /* grab the samr open */
460 if(!samr_io_q_open_domain("", &q_u, data, 0))
463 /* construct reply. always indicate success */
464 if(!samr_reply_open_domain(&q_u, rdata))
471 /*******************************************************************
472 samr_reply_unknown_2c
473 ********************************************************************/
474 static BOOL samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u,
477 SAMR_R_UNKNOWN_2C r_u;
480 /* find the policy handle. open a policy on it. */
481 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
483 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
486 /* find the user's rid */
487 if ((status == 0x0) && (get_lsa_policy_samr_rid(&(q_u->user_pol)) == 0xffffffff))
489 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
492 init_samr_r_unknown_2c(&r_u, status);
494 DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
496 /* store the response in the SMB stream */
497 if(!samr_io_r_unknown_2c("", &r_u, rdata, 0))
500 DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
505 /*******************************************************************
507 ********************************************************************/
508 static BOOL api_samr_unknown_2c(pipes_struct *p)
510 SAMR_Q_UNKNOWN_2C q_u;
511 prs_struct *data = &p->in_data.data;
512 prs_struct *rdata = &p->out_data.rdata;
514 /* grab the samr open */
515 if(!samr_io_q_unknown_2c("", &q_u, data, 0))
518 /* construct reply. always indicate success */
519 if(!samr_reply_unknown_2c(&q_u, rdata))
526 /*******************************************************************
528 ********************************************************************/
529 static BOOL samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
532 SAMR_R_UNKNOWN_3 r_u;
533 DOM_SID3 sid[MAX_SAM_SIDS];
539 /* find the policy handle. open a policy on it. */
540 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
542 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
545 /* find the user's rid */
546 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->user_pol))) == 0xffffffff)
548 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
554 DOM_SID everyone_sid;
556 user_sid = global_sam_sid;
558 SMB_ASSERT_ARRAY(user_sid.sub_auths, user_sid.num_auths+1);
563 user_sid.sub_auths[user_sid.num_auths++] = rid;
565 string_to_sid(&everyone_sid, "S-1-1");
567 /* maybe need another 1 or 2 (S-1-5-0x20-0x220 and S-1-5-20-0x224) */
568 /* these two are DOMAIN_ADMIN and DOMAIN_ACCT_OP group RIDs */
569 init_dom_sid3(&(sid[0]), 0x035b, 0x0002, &everyone_sid);
570 init_dom_sid3(&(sid[1]), 0x0044, 0x0002, &user_sid);
573 init_samr_r_unknown_3(&r_u,
575 0x00000014, 0x0002, 0x0070,
578 DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
580 /* store the response in the SMB stream */
581 if(!samr_io_r_unknown_3("", &r_u, rdata, 0))
584 DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
589 /*******************************************************************
591 ********************************************************************/
592 static BOOL api_samr_unknown_3(pipes_struct *p)
594 SAMR_Q_UNKNOWN_3 q_u;
595 prs_struct *data = &p->in_data.data;
596 prs_struct *rdata = &p->out_data.rdata;
598 /* grab the samr open */
599 if(!samr_io_q_unknown_3("", &q_u, data, 0))
602 /* construct reply. always indicate success */
603 if(!samr_reply_unknown_3(&q_u, rdata))
610 /*******************************************************************
611 samr_reply_enum_dom_users
612 ********************************************************************/
613 static BOOL samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
616 SAMR_R_ENUM_DOM_USERS r_e;
617 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
624 r_e.total_num_entries = 0;
626 /* find the policy handle. open a policy on it. */
627 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
629 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
632 DEBUG(5,("samr_reply_enum_dom_users: %d\n", __LINE__));
635 get_sampwd_entries(pass, 0, &total_entries, &num_entries, MAX_SAM_ENTRIES, q_u->acb_mask);
638 init_samr_r_enum_dom_users(&r_e, total_entries,
639 q_u->unknown_0, num_entries,
642 /* store the response in the SMB stream */
643 if(!samr_io_r_enum_dom_users("", &r_e, rdata, 0))
646 DEBUG(5,("samr_enum_dom_users: %d\n", __LINE__));
651 /*******************************************************************
652 api_samr_enum_dom_users
653 ********************************************************************/
654 static BOOL api_samr_enum_dom_users(pipes_struct *p)
656 SAMR_Q_ENUM_DOM_USERS q_e;
657 prs_struct *data = &p->in_data.data;
658 prs_struct *rdata = &p->out_data.rdata;
660 /* grab the samr open */
661 if(!samr_io_q_enum_dom_users("", &q_e, data, 0))
664 /* construct reply. */
665 if(!samr_reply_enum_dom_users(&q_e, rdata))
671 /*******************************************************************
672 samr_reply_enum_dom_groups
673 ********************************************************************/
674 static BOOL samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u,
677 SAMR_R_ENUM_DOM_GROUPS r_e;
678 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
681 char *dummy_group = "Domain Admins";
688 /* find the policy handle. open a policy on it. */
689 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
691 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
694 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
698 ZERO_STRUCTP(&pass[0]);
699 init_unistr2(&(pass[0].uni_user_name), dummy_group, strlen(dummy_group)+1);
700 pass[0].user_rid = DOMAIN_GROUP_RID_ADMINS;
702 if (r_e.status == 0 && got_grps)
704 init_samr_r_enum_dom_groups(&r_e, q_u->start_idx, num_entries, pass, r_e.status);
707 /* store the response in the SMB stream */
708 if(!samr_io_r_enum_dom_groups("", &r_e, rdata, 0))
711 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
716 /*******************************************************************
717 api_samr_enum_dom_groups
718 ********************************************************************/
719 static BOOL api_samr_enum_dom_groups(pipes_struct *p)
721 SAMR_Q_ENUM_DOM_GROUPS q_e;
722 prs_struct *data = &p->in_data.data;
723 prs_struct *rdata = &p->out_data.rdata;
725 /* grab the samr open */
726 if(!samr_io_q_enum_dom_groups("", &q_e, data, 0))
729 /* construct reply. */
730 if(!samr_reply_enum_dom_groups(&q_e, rdata))
736 /*******************************************************************
737 samr_reply_enum_dom_aliases
738 ********************************************************************/
739 static BOOL samr_reply_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_u,
742 SAMR_R_ENUM_DOM_ALIASES r_e;
743 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
752 /* find the policy handle. open a policy on it. */
753 if (r_e.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &sid))
755 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
758 sid_to_string(sid_str, &sid);
759 sid_to_string(sam_sid_str, &global_sam_sid);
761 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
763 /* well-known aliases */
764 if (strequal(sid_str, "S-1-5-32"))
767 while (!lp_hide_local_users() &&
768 num_entries < MAX_SAM_ENTRIES &&
769 ((name = builtin_alias_rids[num_entries].name) != NULL))
771 init_unistr2(&(pass[num_entries].uni_user_name), name, strlen(name)+1);
772 pass[num_entries].user_rid = builtin_alias_rids[num_entries].rid;
776 else if (strequal(sid_str, sam_sid_str) && !lp_hide_local_users())
781 sep = lp_winbind_separator();
784 /* we return the UNIX groups here. This seems to be the right */
785 /* thing to do, since NT member servers return their local */
786 /* groups in the same situation. */
789 while (num_entries < MAX_SAM_ENTRIES && ((grp = getgrent()) != NULL))
795 /* Don't return winbind groups as they are not local! */
797 if (strchr(name, *sep) != NULL) {
801 trid = pdb_gid_to_group_rid(grp->gr_gid);
802 for( i = 0; i < num_entries; i++)
803 if ( pass[i].user_rid == trid ) break;
804 if ( i < num_entries )
805 continue; /* rid was there, dup! */
807 init_unistr2(&(pass[num_entries].uni_user_name), name, strlen(name)+1);
808 pass[num_entries].user_rid = trid;
815 init_samr_r_enum_dom_aliases(&r_e, num_entries, pass, r_e.status);
817 /* store the response in the SMB stream */
818 if(!samr_io_r_enum_dom_aliases("", &r_e, rdata, 0))
821 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
826 /*******************************************************************
827 api_samr_enum_dom_aliases
828 ********************************************************************/
829 static BOOL api_samr_enum_dom_aliases(pipes_struct *p)
831 SAMR_Q_ENUM_DOM_ALIASES q_e;
832 prs_struct *data = &p->in_data.data;
833 prs_struct *rdata = &p->out_data.rdata;
837 /* grab the samr open */
838 if(!samr_io_q_enum_dom_aliases("", &q_e, data, 0))
841 /* construct reply. */
842 if(!samr_reply_enum_dom_aliases(&q_e, rdata))
849 /*******************************************************************
850 samr_reply_query_dispinfo
851 ********************************************************************/
852 static BOOL samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u, prs_struct *rdata)
854 SAMR_R_QUERY_DISPINFO r_e;
858 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
860 int total_entries = 0;
862 uint16 switch_level = 0x0;
866 DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
868 /* find the policy handle. open a policy on it. */
869 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
871 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
872 DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n"));
875 if (r_e.status == 0x0)
877 /* decide how many entries to get depending on the max_entries
878 and max_size passed by client */
881 if(q_u->max_entries > MAX_SAM_ENTRIES)
882 q_u->max_entries = MAX_SAM_ENTRIES;
884 retsize = (q_u->max_entries * (sizeof(SAM_ENTRY1)+sizeof(SAM_STR1)))
887 if(retsize > q_u->max_size)
889 /* determine max_entries based on max_size */
890 q_u->max_entries = (q_u->max_size - 3*sizeof(uint32)) /
891 (sizeof(SAM_ENTRY1)+sizeof(SAM_STR1));
892 q_u->max_entries = (q_u->max_entries>0?q_u->max_entries:1);
895 DEBUG(10,("samr_reply_query_dispinfo: Setting q_u->max_entries to %u\n",q_u->max_entries));
898 got_pwds = get_passwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, q_u->max_entries, 0);
901 /* more left - set resume handle */
902 if(total_entries > num_entries)
907 switch (q_u->switch_level)
912 /* query disp info is for users */
915 init_sam_info_1(&info1, ACB_NORMAL,
916 q_u->start_idx, num_entries, pass);
918 ctr.sam.info1 = &info1;
924 /* query disp info is for servers */
927 init_sam_info_2(&info2, ACB_WSTRUST,
928 q_u->start_idx, num_entries, pass);
930 ctr.sam.info2 = &info2;
937 /* more left - set resume handle */
938 if(total_entries > num_entries)
943 if (r_e.status == 0 || r_e.status == 0x105)
945 init_samr_r_query_dispinfo(&r_e, switch_level, &ctr, r_e.status);
948 /* store the response in the SMB stream */
949 if(!samr_io_r_query_dispinfo("", &r_e, rdata, 0))
952 DEBUG(5,("samr_query_dispinfo: %d\n", __LINE__));
957 /*******************************************************************
958 api_samr_query_dispinfo
959 ********************************************************************/
960 static BOOL api_samr_query_dispinfo(pipes_struct *p)
962 SAMR_Q_QUERY_DISPINFO q_e;
963 prs_struct *data = &p->in_data.data;
964 prs_struct *rdata = &p->out_data.rdata;
966 /* grab the samr open */
967 if(!samr_io_q_query_dispinfo("", &q_e, data, 0))
970 /* construct reply. */
971 if(!samr_reply_query_dispinfo(&q_e, rdata))
978 /*******************************************************************
979 samr_reply_query_aliasinfo
980 ********************************************************************/
981 static BOOL samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
984 SAMR_R_QUERY_ALIASINFO r_e;
985 fstring alias_desc = "Local Unix group";
987 enum SID_NAME_USE type;
992 DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__));
994 /* find the policy handle. open a policy on it. */
995 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
997 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1000 alias_rid = get_lsa_policy_samr_rid(&q_u->pol);
1001 if(alias_rid == 0xffffffff)
1002 r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
1004 if(!local_lookup_rid(alias_rid, alias, &type))
1006 r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
1009 init_samr_r_query_aliasinfo(&r_e, q_u->switch_level, alias, alias_desc);
1011 /* store the response in the SMB stream */
1012 if(!samr_io_r_query_aliasinfo("", &r_e, rdata, 0))
1015 DEBUG(5,("samr_query_aliasinfo: %d\n", __LINE__));
1020 /*******************************************************************
1021 api_samr_query_aliasinfo
1022 ********************************************************************/
1023 static BOOL api_samr_query_aliasinfo(pipes_struct *p)
1025 SAMR_Q_QUERY_ALIASINFO q_e;
1026 prs_struct *data = &p->in_data.data;
1027 prs_struct *rdata = &p->out_data.rdata;
1029 /* grab the samr open */
1030 if(!samr_io_q_query_aliasinfo("", &q_e, data, 0))
1033 /* construct reply. */
1034 if(!samr_reply_query_aliasinfo(&q_e, rdata))
1041 /*******************************************************************
1042 samr_reply_lookup_ids
1043 ********************************************************************/
1044 static BOOL samr_reply_lookup_ids(SAMR_Q_LOOKUP_IDS *q_u,
1047 uint32 rid[MAX_SAM_ENTRIES];
1049 int num_rids = q_u->num_sids1;
1051 SAMR_R_LOOKUP_IDS r_u;
1053 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
1055 if (num_rids > MAX_SAM_ENTRIES)
1057 num_rids = MAX_SAM_ENTRIES;
1058 DEBUG(5,("samr_lookup_ids: truncating entries to %d\n", num_rids));
1063 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1065 for (i = 0; i < num_rids && status == 0; i++)
1067 SAM_ACCOUNT *sam_pass;
1071 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1072 q_u->uni_user_name[i].uni_str_len));
1074 /* find the user account */
1076 sam_pass = pdb_getsampwnam(user_name);
1079 if (sam_pass == NULL)
1081 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1086 rid[i] = pdb_get_user_rid(sam_pass);
1092 rid[0] = BUILTIN_ALIAS_RID_USERS;
1094 init_samr_r_lookup_ids(&r_u, num_rids, rid, status);
1096 /* store the response in the SMB stream */
1097 if(!samr_io_r_lookup_ids("", &r_u, rdata, 0))
1100 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
1105 /*******************************************************************
1107 ********************************************************************/
1108 static BOOL api_samr_lookup_ids(pipes_struct *p)
1110 SAMR_Q_LOOKUP_IDS q_u;
1111 prs_struct *data = &p->in_data.data;
1112 prs_struct *rdata = &p->out_data.rdata;
1114 /* grab the samr 0x10 */
1115 if(!samr_io_q_lookup_ids("", &q_u, data, 0))
1118 /* construct reply. always indicate success */
1119 if(!samr_reply_lookup_ids(&q_u, rdata))
1125 /*******************************************************************
1126 samr_reply_lookup_names
1127 ********************************************************************/
1129 static BOOL samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
1132 uint32 rid[MAX_SAM_ENTRIES];
1133 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1136 int num_rids = q_u->num_names1;
1139 SAMR_R_LOOKUP_NAMES r_u;
1141 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1146 if (!get_lsa_policy_samr_sid(&q_u->pol, &pol_sid)) {
1147 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
1148 init_samr_r_lookup_names(&r_u, 0, rid, type, status);
1149 if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
1150 DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
1156 if (num_rids > MAX_SAM_ENTRIES) {
1157 num_rids = MAX_SAM_ENTRIES;
1158 DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
1161 SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
1163 for (i = 0; i < num_rids; i++) {
1166 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
1168 rid [i] = 0xffffffff;
1169 type[i] = SID_NAME_UNKNOWN;
1171 fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer,
1172 q_u->uni_name[i].uni_str_len));
1174 if(sid_equal(&pol_sid, &global_sam_sid))
1177 if(local_lookup_name(global_myname, name,
1180 sid_split_rid( &sid, &rid[i]);
1186 init_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
1188 /* store the response in the SMB stream */
1189 if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
1190 DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
1194 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1199 /*******************************************************************
1200 api_samr_lookup_names
1201 ********************************************************************/
1203 static BOOL api_samr_lookup_names(pipes_struct *p)
1205 SAMR_Q_LOOKUP_NAMES q_u;
1206 prs_struct *data = &p->in_data.data;
1207 prs_struct *rdata = &p->out_data.rdata;
1209 memset(&q_u, '\0', sizeof(q_u));
1211 /* grab the samr lookup names */
1212 if(!samr_io_q_lookup_names("", &q_u, data, 0)) {
1213 DEBUG(0,("api_samr_lookup_names: failed to unmarshall SAMR_Q_LOOKUP_NAMES.\n"));
1217 /* construct reply. always indicate success */
1218 if(!samr_reply_lookup_names(&q_u, rdata))
1224 /*******************************************************************
1225 samr_reply_chgpasswd_user
1226 ********************************************************************/
1228 static BOOL samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
1231 SAMR_R_CHGPASSWD_USER r_u;
1232 uint32 status = 0x0;
1236 fstrcpy(user_name, dos_unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len));
1237 fstrcpy(wks , dos_unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len));
1239 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1241 if (!pass_oem_change(user_name,
1242 q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1243 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1245 status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
1248 init_samr_r_chgpasswd_user(&r_u, status);
1250 /* store the response in the SMB stream */
1251 if(!samr_io_r_chgpasswd_user("", &r_u, rdata, 0)) {
1252 DEBUG(0,("samr_reply_chgpasswd_user: Failed to marshall SAMR_R_CHGPASSWD_USER struct.\n" ));
1256 DEBUG(5,("samr_chgpasswd_user: %d\n", __LINE__));
1260 /*******************************************************************
1261 api_samr_chgpasswd_user
1262 ********************************************************************/
1264 static BOOL api_samr_chgpasswd_user(pipes_struct *p)
1266 SAMR_Q_CHGPASSWD_USER q_u;
1267 prs_struct *data = &p->in_data.data;
1268 prs_struct *rdata = &p->out_data.rdata;
1270 /* unknown 38 command */
1271 if (!samr_io_q_chgpasswd_user("", &q_u, data, 0)) {
1272 DEBUG(0,("api_samr_chgpasswd_user: samr_io_q_chgpasswd_user failed to parse RPC packet.\n"));
1276 /* construct reply. */
1277 if(!samr_reply_chgpasswd_user(&q_u, rdata)) {
1278 DEBUG(0,("api_samr_chgpasswd_user: samr_reply_chgpasswd_user failed to create reply packet.\n"));
1286 /*******************************************************************
1287 samr_reply_unknown_38
1288 ********************************************************************/
1289 static BOOL samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u, prs_struct *rdata)
1291 SAMR_R_UNKNOWN_38 r_u;
1293 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1295 init_samr_r_unknown_38(&r_u);
1297 /* store the response in the SMB stream */
1298 if(!samr_io_r_unknown_38("", &r_u, rdata, 0))
1301 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1305 /*******************************************************************
1307 ********************************************************************/
1308 static BOOL api_samr_unknown_38(pipes_struct *p)
1310 SAMR_Q_UNKNOWN_38 q_u;
1311 prs_struct *data = &p->in_data.data;
1312 prs_struct *rdata = &p->out_data.rdata;
1314 /* unknown 38 command */
1315 if(!samr_io_q_unknown_38("", &q_u, data, 0))
1318 /* construct reply. always indicate success */
1319 if(!samr_reply_unknown_38(&q_u, rdata))
1326 /*******************************************************************
1327 samr_reply_lookup_rids
1328 ********************************************************************/
1329 static BOOL samr_reply_lookup_rids(SAMR_Q_LOOKUP_RIDS *q_u,
1332 fstring group_names[MAX_SAM_ENTRIES];
1333 uint32 group_attrs[MAX_SAM_ENTRIES];
1335 int num_gids = q_u->num_gids1;
1337 SAMR_R_LOOKUP_RIDS r_u;
1339 DEBUG(5,("samr_reply_lookup_rids: %d\n", __LINE__));
1341 /* find the policy handle. open a policy on it. */
1342 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1344 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1350 if (num_gids > MAX_SAM_ENTRIES)
1352 num_gids = MAX_SAM_ENTRIES;
1353 DEBUG(5,("samr_reply_lookup_rids: truncating entries to %d\n", num_gids));
1356 for (i = 0; i < num_gids && status == 0; i++)
1358 fstrcpy(group_names[i], "dummy group");
1359 group_attrs[i] = 0x2;
1363 init_samr_r_lookup_rids(&r_u, num_gids, group_names, group_attrs, status);
1365 /* store the response in the SMB stream */
1366 if(!samr_io_r_lookup_rids("", &r_u, rdata, 0))
1369 DEBUG(5,("samr_reply_lookup_rids: %d\n", __LINE__));
1374 /*******************************************************************
1375 api_samr_lookup_rids
1376 ********************************************************************/
1377 static BOOL api_samr_lookup_rids(pipes_struct *p)
1379 SAMR_Q_LOOKUP_RIDS q_u;
1380 prs_struct *data = &p->in_data.data;
1381 prs_struct *rdata = &p->out_data.rdata;
1383 /* grab the samr lookup names */
1384 if(!samr_io_q_lookup_rids("", &q_u, data, 0))
1387 /* construct reply. always indicate success */
1388 if(!samr_reply_lookup_rids(&q_u, rdata))
1395 /*******************************************************************
1397 ********************************************************************/
1398 static uint32 _api_samr_open_user(POLICY_HND domain_pol, uint32 user_rid, POLICY_HND *user_pol)
1400 SAM_ACCOUNT *sam_pass;
1403 /* find the domain policy handle. */
1404 if (find_lsa_policy_by_hnd(&domain_pol) == -1)
1405 return NT_STATUS_INVALID_HANDLE;
1407 /* get a (unique) handle. open a policy on it. */
1408 if (!open_lsa_policy_hnd(user_pol))
1409 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1412 sam_pass = pdb_getsampwrid(user_rid);
1415 /* check that the RID exists in our domain. */
1416 if (sam_pass == NULL) {
1417 close_lsa_policy_hnd(user_pol);
1418 return NT_STATUS_NO_SUCH_USER;
1421 /* Get the domain SID stored in the domain policy */
1422 if(!get_lsa_policy_samr_sid(&domain_pol, &sid)) {
1423 close_lsa_policy_hnd(user_pol);
1424 return NT_STATUS_INVALID_HANDLE;
1427 /* append the user's RID to it */
1428 if(!sid_append_rid(&sid, user_rid)) {
1429 close_lsa_policy_hnd(user_pol);
1430 return NT_STATUS_NO_SUCH_USER;
1433 /* associate the user's SID with the handle. */
1434 if (!set_lsa_policy_samr_sid(user_pol, &sid)) {
1435 /* oh, whoops. don't know what error message to return, here */
1436 close_lsa_policy_hnd(user_pol);
1437 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1440 return NT_STATUS_NO_PROBLEMO;
1443 /*******************************************************************
1445 ********************************************************************/
1446 static BOOL api_samr_open_user(pipes_struct *p)
1448 SAMR_Q_OPEN_USER q_u;
1449 SAMR_R_OPEN_USER r_u;
1450 prs_struct *data = &p->in_data.data;
1451 prs_struct *rdata = &p->out_data.rdata;
1456 /* grab the samr unknown 22 */
1457 if(!samr_io_q_open_user("", &q_u, data, 0))
1460 r_u.status = _api_samr_open_user(q_u.domain_pol, q_u.user_rid, &r_u.user_pol);
1462 /* store the response in the SMB stream */
1463 if(!samr_io_r_open_user("", &r_u, rdata, 0))
1466 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1471 /*************************************************************************
1473 *************************************************************************/
1474 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1476 SAM_ACCOUNT *sampass;
1478 if (!pdb_rid_is_user(user_rid))
1480 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1485 sampass = pdb_getsampwrid(user_rid);
1488 if (sampass == NULL)
1490 DEBUG(4,("User 0x%x not found\n", user_rid));
1494 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass)));
1496 init_sam_user_info10(id10, pdb_get_acct_ctrl(sampass));
1501 /*************************************************************************
1503 *************************************************************************/
1504 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1506 SAM_ACCOUNT *sam_pass;
1508 if (!pdb_rid_is_user(user_rid))
1510 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1515 sam_pass = pdb_getsampwrid(user_rid);
1518 if (sam_pass == NULL)
1520 DEBUG(4,("User 0x%x not found\n", user_rid));
1524 DEBUG(3,("User:[%s]\n", pdb_get_username(sam_pass)));
1526 init_sam_user_info21(id21, sam_pass);
1531 /*******************************************************************
1532 samr_reply_query_userinfo
1533 ********************************************************************/
1534 static BOOL samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
1537 SAMR_R_QUERY_USERINFO r_u;
1539 SAM_USER_INFO_11 id11;
1541 SAM_USER_INFO_10 id10;
1542 SAM_USER_INFO_21 id21;
1545 uint32 status = 0x0;
1548 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1550 /* search for the handle */
1551 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1553 status = NT_STATUS_INVALID_HANDLE;
1556 /* find the user's rid */
1557 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1559 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1562 DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
1564 /* ok! user info levels (there are lots: see MSDEV help), off we go... */
1567 switch (q_u->switch_value)
1571 info = (void*)&id10;
1572 status = get_user_info_10(&id10, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1576 /* whoops - got this wrong. i think. or don't understand what's happening. */
1580 info = (void*)&id11;
1582 expire.low = 0xffffffff;
1583 expire.high = 0x7fffffff;
1585 make_sam_user_info11(&id11, &expire, "BROOKFIELDS$", 0x03ef, 0x201, 0x0080);
1592 info = (void*)&id21;
1593 status = get_user_info_21(&id21, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1599 status = NT_STATUS_INVALID_INFO_CLASS;
1606 init_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
1608 /* store the response in the SMB stream */
1609 if(!samr_io_r_query_userinfo("", &r_u, rdata, 0))
1612 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1617 /*******************************************************************
1618 api_samr_query_userinfo
1619 ********************************************************************/
1620 static BOOL api_samr_query_userinfo(pipes_struct *p)
1622 SAMR_Q_QUERY_USERINFO q_u;
1623 prs_struct *data = &p->in_data.data;
1624 prs_struct *rdata = &p->out_data.rdata;
1626 /* grab the samr unknown 24 */
1627 if(!samr_io_q_query_userinfo("", &q_u, data, 0))
1630 /* construct reply. always indicate success */
1631 if(!samr_reply_query_userinfo(&q_u, rdata))
1638 /*******************************************************************
1639 samr_reply_query_usergroups
1640 ********************************************************************/
1641 static BOOL samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
1644 SAMR_R_QUERY_USERGROUPS r_u;
1645 uint32 status = 0x0;
1647 SAM_ACCOUNT *sam_pass;
1648 DOM_GID *gids = NULL;
1652 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1654 /* find the policy handle. open a policy on it. */
1655 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1657 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1660 /* find the user's rid */
1661 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1663 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1669 sam_pass = pdb_getsampwrid(rid);
1672 if (sam_pass == NULL)
1674 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1681 get_domain_user_groups(groups, pdb_get_username(sam_pass));
1683 num_groups = make_dom_gids(groups, &gids);
1686 /* construct the response. lkclXXXX: gids are not copied! */
1687 init_samr_r_query_usergroups(&r_u, num_groups, gids, status);
1689 /* store the response in the SMB stream */
1690 if(!samr_io_r_query_usergroups("", &r_u, rdata, 0)) {
1699 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1704 /*******************************************************************
1705 api_samr_query_usergroups
1706 ********************************************************************/
1707 static BOOL api_samr_query_usergroups(pipes_struct *p)
1709 SAMR_Q_QUERY_USERGROUPS q_u;
1710 prs_struct *data = &p->in_data.data;
1711 prs_struct *rdata = &p->out_data.rdata;
1713 /* grab the samr unknown 32 */
1714 if(!samr_io_q_query_usergroups("", &q_u, data, 0))
1717 /* construct reply. */
1718 if(!samr_reply_query_usergroups(&q_u, rdata))
1725 /*******************************************************************
1726 api_samr_query_dom_info
1727 ********************************************************************/
1728 static BOOL api_samr_query_dom_info(pipes_struct *p)
1730 SAMR_Q_QUERY_DOMAIN_INFO q_u;
1731 SAMR_R_QUERY_DOMAIN_INFO r_u;
1733 prs_struct *data = &p->in_data.data;
1734 prs_struct *rdata = &p->out_data.rdata;
1736 uint16 switch_value = 0x0;
1737 uint32 status = 0x0;
1743 DEBUG(5,("api_samr_query_dom_info: %d\n", __LINE__));
1745 /* grab the samr unknown 8 command */
1746 if(!samr_io_q_query_dom_info("", &q_u, data, 0))
1749 /* find the policy handle. open a policy on it. */
1750 if (find_lsa_policy_by_hnd(&q_u.domain_pol) == -1) {
1751 status = NT_STATUS_INVALID_HANDLE;
1752 DEBUG(5,("api_samr_query_dom_info: invalid handle\n"));
1755 if (status == 0x0) {
1756 switch (q_u.switch_value) {
1759 init_unk_info1(&ctr.info.inf1);
1763 init_unk_info2(&ctr.info.inf2, global_myworkgroup, global_myname);
1767 init_unk_info3(&ctr.info.inf3);
1771 init_unk_info6(&ctr.info.inf6);
1775 init_unk_info7(&ctr.info.inf7);
1779 init_unk_info12(&ctr.info.inf12);
1782 status = NT_STATUS_INVALID_INFO_CLASS;
1787 init_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
1789 /* store the response in the SMB stream */
1790 if(!samr_io_r_query_dom_info("", &r_u, rdata, 0))
1793 DEBUG(5,("api_samr_query_dom_info: %d\n", __LINE__));
1799 /*******************************************************************
1800 _api_samr_create_user
1801 ********************************************************************/
1802 static BOOL _api_samr_create_user(POLICY_HND dom_pol, UNISTR2 user_account, uint32 acb_info, uint32 access_mask,
1803 POLICY_HND *user_pol, uint32 *unknown0, uint32 *user_rid)
1805 SAM_ACCOUNT *sam_pass;
1812 /* find the policy handle. open a policy on it. */
1813 if (find_lsa_policy_by_hnd(&dom_pol) == -1)
1814 return NT_STATUS_INVALID_HANDLE;
1816 /* find the machine account: tell the caller if it exists.
1817 lkclXXXX i have *no* idea if this is a problem or not
1818 or even if you are supposed to construct a different
1819 reply if the account already exists...
1822 fstrcpy(mach_acct, dos_unistrn2(user_account.buffer, user_account.uni_str_len));
1823 strlower(mach_acct);
1826 sam_pass = pdb_getsampwnam(mach_acct);
1828 if (sam_pass != NULL)
1830 /* machine account exists: say so */
1831 return NT_STATUS_USER_EXISTS;
1834 /* get a (unique) handle. open a policy on it. */
1835 if (!open_lsa_policy_hnd(user_pol))
1836 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1838 local_flags=LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_SET_NO_PASSWORD;
1839 local_flags|= (acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0;
1842 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
1843 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
1844 * that only people with write access to the smbpasswd file will be able
1845 * to create a user. JRA.
1848 /* add the user in the /etc/passwd file or the unix authority system */
1849 if (lp_adduser_script())
1850 smb_create_user(mach_acct,NULL);
1852 /* add the user in the smbpasswd file or the Samba authority database */
1853 if (!local_password_change(mach_acct, local_flags, NULL, err_str,
1854 sizeof(err_str), msg_str, sizeof(msg_str)))
1856 DEBUG(0, ("%s\n", err_str));
1857 close_lsa_policy_hnd(user_pol);
1858 return NT_STATUS_ACCESS_DENIED;
1862 sam_pass = pdb_getsampwnam(mach_acct);
1864 if (sam_pass == NULL) {
1865 /* account doesn't exist: say so */
1866 close_lsa_policy_hnd(user_pol);
1867 return NT_STATUS_ACCESS_DENIED;
1870 /* Get the domain SID stored in the domain policy */
1871 if(!get_lsa_policy_samr_sid(&dom_pol, &sid)) {
1872 close_lsa_policy_hnd(user_pol);
1873 return NT_STATUS_INVALID_HANDLE;
1876 /* append the user's RID to it */
1877 if(!sid_append_rid(&sid, sam_pass->user_rid)) {
1878 close_lsa_policy_hnd(user_pol);
1879 return NT_STATUS_NO_SUCH_USER;
1882 /* associate the RID with the (unique) handle. */
1883 if (!set_lsa_policy_samr_sid(user_pol, &sid)) {
1884 /* oh, whoops. don't know what error message to return, here */
1885 close_lsa_policy_hnd(user_pol);
1886 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1889 *unknown0 = 0x000703ff;
1890 *user_rid = pdb_get_user_rid(sam_pass);
1892 return NT_STATUS_NO_PROBLEMO;
1895 /*******************************************************************
1896 api_samr_create_user
1897 ********************************************************************/
1898 static BOOL api_samr_create_user(pipes_struct *p)
1900 prs_struct *data = &p->in_data.data;
1901 prs_struct *rdata = &p->out_data.rdata;
1903 SAMR_Q_CREATE_USER q_u;
1904 SAMR_R_CREATE_USER r_u;
1909 /* grab the samr create user */
1910 if (!samr_io_q_create_user("", &q_u, data, 0)) {
1911 DEBUG(0,("api_samr_create_user: Unable to unmarshall SAMR_Q_CREATE_USER.\n"));
1915 r_u.status=_api_samr_create_user(q_u.pol, q_u.uni_mach_acct, q_u.acb_info, q_u.access_mask,
1916 &r_u.pol, &r_u.unknown_0, &r_u.user_rid);
1918 /* store the response in the SMB stream */
1919 if(!samr_io_r_create_user("", &r_u, rdata, 0)) {
1920 DEBUG(0,("api_samr_create_user: Unable to marshall SAMR_R_CREATE_USER.\n"));
1928 /*******************************************************************
1929 samr_reply_connect_anon
1930 ********************************************************************/
1931 static BOOL samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u, prs_struct *rdata)
1933 SAMR_R_CONNECT_ANON r_u;
1934 BOOL pol_open = False;
1936 /* set up the SAMR connect_anon response */
1939 /* get a (unique) handle. open a policy on it. */
1940 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1942 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1945 /* associate the domain SID with the (unique) handle. */
1946 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1948 /* oh, whoops. don't know what error message to return, here */
1949 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1952 if (r_u.status != 0 && pol_open)
1954 close_lsa_policy_hnd(&(r_u.connect_pol));
1957 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1959 /* store the response in the SMB stream */
1960 if(!samr_io_r_connect_anon("", &r_u, rdata, 0))
1963 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1968 /*******************************************************************
1969 api_samr_connect_anon
1970 ********************************************************************/
1971 static BOOL api_samr_connect_anon(pipes_struct *p)
1973 SAMR_Q_CONNECT_ANON q_u;
1974 prs_struct *data = &p->in_data.data;
1975 prs_struct *rdata = &p->out_data.rdata;
1977 /* grab the samr open policy */
1978 if(!samr_io_q_connect_anon("", &q_u, data, 0))
1981 /* construct reply. always indicate success */
1982 if(!samr_reply_connect_anon(&q_u, rdata))
1988 /*******************************************************************
1990 ********************************************************************/
1991 static BOOL samr_reply_connect(SAMR_Q_CONNECT *q_u, prs_struct *rdata)
1994 BOOL pol_open = False;
1996 /* set up the SAMR connect response */
1999 /* get a (unique) handle. open a policy on it. */
2000 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
2002 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2005 /* associate the domain SID with the (unique) handle. */
2006 if (r_u.status == 0x0 &&
2007 !set_lsa_policy_samr_pol_status(&(r_u.connect_pol),
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))
2051 /**********************************************************************
2052 api_samr_lookup_domain
2053 **********************************************************************/
2054 static BOOL api_samr_lookup_domain(pipes_struct *p)
2056 SAMR_Q_LOOKUP_DOMAIN q_u;
2057 SAMR_R_LOOKUP_DOMAIN r_u;
2058 prs_struct *data = &p->in_data.data;
2059 prs_struct *rdata = &p->out_data.rdata;
2064 if(!samr_io_q_lookup_domain("", &q_u, data, 0)) {
2065 DEBUG(0,("api_samr_lookup_domain: Unable to unmarshall SAMR_Q_LOOKUP_DOMAIN.\n"));
2071 if (find_lsa_policy_by_hnd(&q_u.connect_pol) == -1){
2072 r_u.status = NT_STATUS_INVALID_HANDLE;
2073 DEBUG(5,("api_samr_lookup_domain: invalid handle\n"));
2076 /* assume the domain name sent is our global_myname and
2077 send global_sam_sid */
2078 init_samr_r_lookup_domain(&r_u, &global_sam_sid, r_u.status);
2080 if(!samr_io_r_lookup_domain("", &r_u, rdata, 0)){
2081 DEBUG(0,("api_samr_lookup_domain: Unable to marshall SAMR_R_LOOKUP_DOMAIN.\n"));
2088 /**********************************************************************
2089 api_samr_enum_domains
2090 **********************************************************************/
2091 static BOOL api_samr_enum_domains(pipes_struct *p)
2093 SAMR_Q_ENUM_DOMAINS q_u;
2094 SAMR_R_ENUM_DOMAINS r_u;
2095 prs_struct *data = &p->in_data.data;
2096 prs_struct *rdata = &p->out_data.rdata;
2103 fstrcpy(dom[0],global_myworkgroup);
2104 fstrcpy(dom[1],"Builtin");
2106 if(!samr_io_q_enum_domains("", &q_u, data, 0)) {
2107 DEBUG(0,("api_samr_enum_domains: Unable to unmarshall SAMR_Q_ENUM_DOMAINS.\n"));
2111 r_u.status = NT_STATUS_NO_PROBLEMO;
2113 init_samr_r_enum_domains(&r_u, q_u.start_idx, dom, 2);
2115 if(!samr_io_r_enum_domains("", &r_u, rdata, 0)) {
2116 DEBUG(0,("api_samr_enum_domains: Unable to marshall SAMR_R_ENUM_DOMAINS.\n"));
2118 free(r_u.uni_dom_name);
2123 free(r_u.uni_dom_name);
2129 /*******************************************************************
2131 ********************************************************************/
2132 static uint32 _api_samr_open_alias(POLICY_HND domain_pol, uint32 alias_rid, POLICY_HND *alias_pol)
2136 /* get the domain policy. */
2137 if (find_lsa_policy_by_hnd(&domain_pol) == -1)
2138 return NT_STATUS_INVALID_HANDLE;
2140 /* get a (unique) handle. open a policy on it. */
2141 if (!open_lsa_policy_hnd(alias_pol))
2142 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2144 /* Get the domain SID stored in the domain policy */
2145 if(!get_lsa_policy_samr_sid(&domain_pol, &sid)) {
2146 close_lsa_policy_hnd(alias_pol);
2147 return NT_STATUS_INVALID_HANDLE;
2150 /* append the alias' RID to it */
2151 if(!sid_append_rid(&sid, alias_rid)) {
2152 close_lsa_policy_hnd(alias_pol);
2153 return NT_STATUS_NO_SUCH_USER;
2156 /* associate a RID with the (unique) handle. */
2157 if (!set_lsa_policy_samr_sid(alias_pol, &sid)) {
2158 /* oh, whoops. don't know what error message to return, here */
2159 close_lsa_policy_hnd(alias_pol);
2160 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2163 return NT_STATUS_NO_PROBLEMO;
2166 /*******************************************************************
2168 ********************************************************************/
2169 static BOOL api_samr_open_alias(pipes_struct *p)
2171 SAMR_Q_OPEN_ALIAS q_u;
2172 SAMR_R_OPEN_ALIAS r_u;
2173 prs_struct *data = &p->in_data.data;
2174 prs_struct *rdata = &p->out_data.rdata;
2179 /* grab the samr open policy */
2180 if(!samr_io_q_open_alias("", &q_u, data, 0)) {
2181 DEBUG(0,("api_samr_open_alias: Unable to unmarshall SAMR_Q_OPEN_ALIAS.\n"));
2185 r_u.status=_api_samr_open_alias(q_u.dom_pol, q_u.rid_alias, &r_u.pol);
2187 /* store the response in the SMB stream */
2188 if(!samr_io_r_open_alias("", &r_u, rdata, 0)) {
2189 DEBUG(0,("api_samr_open_alias: Unable to marshall SAMR_R_OPEN_ALIAS.\n"));
2196 /*******************************************************************
2198 ********************************************************************/
2199 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid)
2201 SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2204 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2211 pdb_set_acct_ctrl(pwd, id10->acb_info);
2213 if(!pdb_update_sam_account(pwd, True))
2219 /*******************************************************************
2221 ********************************************************************/
2222 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, uint32 rid)
2224 SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2230 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2234 pdb_set_lanman_passwd (pwd, id12->lm_pwd);
2235 pdb_set_nt_passwd (pwd, id12->nt_pwd);
2237 if(!pdb_update_sam_account(pwd, True))
2243 /*******************************************************************
2245 ********************************************************************/
2246 static BOOL set_user_info_21 (SAM_USER_INFO_21 *id21, uint32 rid)
2248 SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2249 SAM_ACCOUNT new_pwd;
2252 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2259 /* we make a copy so that we can modify stuff */
2260 copy_sam_passwd(&new_pwd, pwd);
2261 copy_id21_to_sam_passwd(&new_pwd, id21);
2264 * The funny part about the previous two calls is
2265 * that pwd still has the password hashes from the
2266 * passdb entry. These have not been updated from
2267 * id21. I don't know if they need to be set. --jerry
2270 /* write the change out */
2271 if(!pdb_update_sam_account(&new_pwd, True))
2277 /*******************************************************************
2279 ********************************************************************/
2280 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
2282 SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2283 SAM_ACCOUNT new_pwd;
2290 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2297 copy_sam_passwd(&new_pwd, pwd);
2298 copy_id23_to_sam_passwd(&new_pwd, id23);
2300 if (!decode_pw_buffer((char*)id23->pass, buf, 256, &len))
2303 nt_lm_owf_gen(buf, nt_hash, lm_hash);
2305 pdb_set_lanman_passwd (&new_pwd, lm_hash);
2306 pdb_set_nt_passwd (&new_pwd, nt_hash);
2308 /* update the UNIX password */
2309 if (lp_unix_password_sync())
2310 if(!chgpasswd(pdb_get_username(&new_pwd), "", buf, True))
2313 memset(buf, 0, sizeof(buf));
2315 if(!pdb_update_sam_account(&new_pwd, True))
2321 /*******************************************************************
2323 ********************************************************************/
2324 static BOOL set_user_info_24(const SAM_USER_INFO_24 *id24, uint32 rid)
2326 SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2335 memset(buf, 0, sizeof(buf));
2337 if (!decode_pw_buffer((char*)id24->pass, buf, 256, &len))
2340 DEBUG(0,("set_user_info_24:nt_lm_owf_gen\n"));
2342 nt_lm_owf_gen(buf, nt_hash, lm_hash);
2344 pdb_set_lanman_passwd (pwd, lm_hash);
2345 pdb_set_nt_passwd (pwd, nt_hash);
2347 /* update the UNIX password */
2348 if (lp_unix_password_sync())
2349 if(!chgpasswd(pdb_get_username(pwd), "", buf, True))
2352 memset(buf, 0, sizeof(buf));
2354 DEBUG(0,("set_user_info_24: pdb_update_sam_account()\n"));
2356 /* update the SAMBA password */
2357 if(!pdb_update_sam_account(pwd, True))
2363 /*******************************************************************
2364 samr_reply_set_userinfo
2365 ********************************************************************/
2366 static uint32 _samr_set_userinfo(POLICY_HND *pol, uint16 switch_value,
2367 SAM_USERINFO_CTR *ctr, pipes_struct *p)
2371 struct current_user user;
2372 SAM_ACCOUNT *sam_pass;
2373 unsigned char sess_key[16];
2375 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2377 if (p->ntlmssp_auth_validated)
2379 memcpy(&user, &p->pipe_user, sizeof(user));
2383 extern struct current_user current_user;
2384 memcpy(&user, ¤t_user, sizeof(user));
2387 /* search for the handle */
2388 if (find_lsa_policy_by_hnd(pol) == -1)
2389 return NT_STATUS_INVALID_HANDLE;
2391 /* find the policy handle. open a policy on it. */
2392 if (!get_lsa_policy_samr_sid(pol, &sid))
2393 return NT_STATUS_INVALID_HANDLE;
2395 sid_split_rid(&sid, &rid);
2397 DEBUG(5, ("_samr_set_userinfo: rid:0x%x, level:%d\n", rid, switch_value));
2400 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2401 return NT_STATUS_INVALID_INFO_CLASS;
2406 * We need the NT hash of the user who is changing the user's password.
2407 * This NT hash is used to generate a "user session key"
2408 * This "user session key" is in turn used to encrypt/decrypt the user's password.
2412 sam_pass = pdb_getsampwuid(user.uid);
2414 if(sam_pass == NULL) {
2415 DEBUG(0,("_samr_set_userinfo: Unable to get passdb entry for uid %u\n",
2416 (unsigned int)pdb_get_uid(sam_pass) ));
2417 return NT_STATUS_ACCESS_DENIED;
2420 memset(sess_key, '\0', 16);
2421 mdfour(sess_key, pdb_get_nt_passwd(sam_pass), 16);
2423 /* ok! user info levels (lots: see MSDEV help), off we go... */
2424 switch (switch_value) {
2426 if (!set_user_info_12(ctr->info.id12, rid))
2427 return NT_STATUS_ACCESS_DENIED;
2431 SamOEMhash(ctr->info.id24->pass, sess_key, 1);
2432 if (!set_user_info_24(ctr->info.id24, rid))
2433 return NT_STATUS_ACCESS_DENIED;
2437 SamOEMhash(ctr->info.id23->pass, sess_key, 1);
2438 if (!set_user_info_23(ctr->info.id23, rid))
2439 return NT_STATUS_ACCESS_DENIED;
2443 return NT_STATUS_INVALID_INFO_CLASS;
2446 return NT_STATUS_NOPROBLEMO;
2449 /*******************************************************************
2450 api_samr_set_userinfo
2451 ********************************************************************/
2452 static BOOL api_samr_set_userinfo(pipes_struct *p)
2454 SAMR_Q_SET_USERINFO q_u;
2455 SAMR_R_SET_USERINFO r_u;
2457 prs_struct *data = &p->in_data.data;
2458 prs_struct *rdata = &p->out_data.rdata;
2460 SAM_USERINFO_CTR ctr;
2467 if (!samr_io_q_set_userinfo("", &q_u, data, 0)) {
2468 DEBUG(0,("api_samr_set_userinfo: Unable to unmarshall SAMR_Q_SET_USERINFO.\n"));
2472 r_u.status = _samr_set_userinfo(&q_u.pol, q_u.switch_value, &ctr, p);
2474 free_samr_q_set_userinfo(&q_u);
2476 if(!samr_io_r_set_userinfo("", &r_u, rdata, 0)) {
2477 DEBUG(0,("api_samr_set_userinfo: Unable to marshall SAMR_R_SET_USERINFO.\n"));
2484 /*******************************************************************
2485 samr_reply_set_userinfo2
2486 ********************************************************************/
2487 static uint32 _samr_set_userinfo2(POLICY_HND *pol, uint16 switch_value, SAM_USERINFO_CTR *ctr)
2492 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
2494 /* search for the handle */
2495 if (find_lsa_policy_by_hnd(pol) == -1)
2496 return NT_STATUS_INVALID_HANDLE;
2498 /* find the policy handle. open a policy on it. */
2499 if (!get_lsa_policy_samr_sid(pol, &sid))
2500 return NT_STATUS_INVALID_HANDLE;
2502 sid_split_rid(&sid, &rid);
2504 DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid));
2507 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
2508 return NT_STATUS_INVALID_INFO_CLASS;
2511 ctr->switch_value = switch_value;
2513 /* ok! user info levels (lots: see MSDEV help), off we go... */
2514 switch (switch_value) {
2516 if (!set_user_info_21(ctr->info.id21, rid))
2517 return NT_STATUS_ACCESS_DENIED;
2520 if (!set_user_info_10(ctr->info.id10, rid))
2521 return NT_STATUS_ACCESS_DENIED;
2524 return NT_STATUS_INVALID_INFO_CLASS;
2527 return NT_STATUS_NOPROBLEMO;
2530 /*******************************************************************
2531 api_samr_set_userinfo2
2532 ********************************************************************/
2533 static BOOL api_samr_set_userinfo2(pipes_struct *p)
2535 SAMR_Q_SET_USERINFO2 q_u;
2536 SAMR_R_SET_USERINFO2 r_u;
2537 SAM_USERINFO_CTR ctr;
2539 prs_struct *data = &p->in_data.data;
2540 prs_struct *rdata = &p->out_data.rdata;
2547 if (!samr_io_q_set_userinfo2("", &q_u, data, 0)) {
2548 DEBUG(0,("api_samr_set_userinfo2: Unable to unmarshall SAMR_Q_SET_USERINFO2.\n"));
2552 r_u.status = _samr_set_userinfo2(&q_u.pol, q_u.switch_value, &ctr);
2554 free_samr_q_set_userinfo2(&q_u);
2556 if(!samr_io_r_set_userinfo2("", &r_u, rdata, 0)) {
2557 DEBUG(0,("api_samr_set_userinfo2: Unable to marshall SAMR_R_SET_USERINFO2.\n"));
2565 /*******************************************************************
2566 array of \PIPE\samr operations
2567 ********************************************************************/
2568 static struct api_struct api_samr_cmds [] =
2570 { "SAMR_CLOSE_HND" , SAMR_CLOSE_HND , api_samr_close_hnd },
2571 { "SAMR_CONNECT" , SAMR_CONNECT , api_samr_connect },
2572 { "SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON , api_samr_connect_anon },
2573 { "SAMR_ENUM_DOM_USERS" , SAMR_ENUM_DOM_USERS , api_samr_enum_dom_users },
2574 { "SAMR_ENUM_DOM_GROUPS" , SAMR_ENUM_DOM_GROUPS , api_samr_enum_dom_groups },
2575 { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
2576 { "SAMR_LOOKUP_IDS" , SAMR_LOOKUP_IDS , api_samr_lookup_ids },
2577 { "SAMR_LOOKUP_NAMES" , SAMR_LOOKUP_NAMES , api_samr_lookup_names },
2578 { "SAMR_OPEN_USER" , SAMR_OPEN_USER , api_samr_open_user },
2579 { "SAMR_QUERY_USERINFO" , SAMR_QUERY_USERINFO , api_samr_query_userinfo },
2580 { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
2581 { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
2582 { "SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo },
2583 { "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo },
2584 { "SAMR_CREATE_USER" , SAMR_CREATE_USER , api_samr_create_user },
2585 { "SAMR_LOOKUP_RIDS" , SAMR_LOOKUP_RIDS , api_samr_lookup_rids },
2586 { "SAMR_UNKNOWN_38" , SAMR_UNKNOWN_38 , api_samr_unknown_38 },
2587 { "SAMR_CHGPASSWD_USER" , SAMR_CHGPASSWD_USER , api_samr_chgpasswd_user },
2588 { "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias },
2589 { "SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain },
2590 { "SAMR_UNKNOWN_3" , SAMR_UNKNOWN_3 , api_samr_unknown_3 },
2591 { "SAMR_UNKNOWN_2C" , SAMR_UNKNOWN_2C , api_samr_unknown_2c },
2592 { "SAMR_LOOKUP_DOMAIN" , SAMR_LOOKUP_DOMAIN , api_samr_lookup_domain },
2593 { "SAMR_ENUM_DOMAINS" , SAMR_ENUM_DOMAINS , api_samr_enum_domains },
2594 { "SAMR_SET_USERINFO" , SAMR_SET_USERINFO , api_samr_set_userinfo },
2595 { "SAMR_SET_USERINFO2" , SAMR_SET_USERINFO2 , api_samr_set_userinfo2 },
2599 /*******************************************************************
2600 receives a samr pipe and responds.
2601 ********************************************************************/
2602 BOOL api_samr_rpc(pipes_struct *p)
2604 return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds);