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";
969 enum SID_NAME_USE type;
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 enum SID_NAME_USE 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_lookup_rids
1310 ********************************************************************/
1311 static BOOL samr_reply_lookup_rids(SAMR_Q_LOOKUP_RIDS *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_LOOKUP_RIDS r_u;
1321 DEBUG(5,("samr_reply_lookup_rids: %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_reply_lookup_rids: 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_lookup_rids(&r_u, num_gids, group_names, group_attrs, status);
1347 /* store the response in the SMB stream */
1348 if(!samr_io_r_lookup_rids("", &r_u, rdata, 0))
1351 DEBUG(5,("samr_reply_lookup_rids: %d\n", __LINE__));
1356 /*******************************************************************
1357 api_samr_lookup_rids
1358 ********************************************************************/
1359 static BOOL api_samr_lookup_rids(pipes_struct *p)
1361 SAMR_Q_LOOKUP_RIDS 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_lookup_rids("", &q_u, data, 0))
1369 /* construct reply. always indicate success */
1370 if(!samr_reply_lookup_rids(&q_u, rdata))
1377 /*******************************************************************
1379 ********************************************************************/
1380 static uint32 _api_samr_open_user(POLICY_HND domain_pol, uint32 user_rid, POLICY_HND *user_pol)
1382 struct sam_passwd *sam_pass;
1385 /* find the domain policy handle. */
1386 if (find_lsa_policy_by_hnd(&domain_pol) == -1)
1387 return NT_STATUS_INVALID_HANDLE;
1389 /* get a (unique) handle. open a policy on it. */
1390 if (!open_lsa_policy_hnd(user_pol))
1391 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1394 sam_pass = getsam21pwrid(user_rid);
1397 /* check that the RID exists in our domain. */
1398 if (sam_pass == NULL) {
1399 close_lsa_policy_hnd(user_pol);
1400 return NT_STATUS_NO_SUCH_USER;
1403 /* Get the domain SID stored in the domain policy */
1404 if(!get_lsa_policy_samr_sid(&domain_pol, &sid)) {
1405 close_lsa_policy_hnd(user_pol);
1406 return NT_STATUS_INVALID_HANDLE;
1409 /* append the user's RID to it */
1410 if(!sid_append_rid(&sid, user_rid)) {
1411 close_lsa_policy_hnd(user_pol);
1412 return NT_STATUS_NO_SUCH_USER;
1415 /* associate the user's SID with the handle. */
1416 if (!set_lsa_policy_samr_sid(user_pol, &sid)) {
1417 /* oh, whoops. don't know what error message to return, here */
1418 close_lsa_policy_hnd(user_pol);
1419 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1422 return NT_STATUS_NO_PROBLEMO;
1425 /*******************************************************************
1427 ********************************************************************/
1428 static BOOL api_samr_open_user(pipes_struct *p)
1430 SAMR_Q_OPEN_USER q_u;
1431 SAMR_R_OPEN_USER r_u;
1432 prs_struct *data = &p->in_data.data;
1433 prs_struct *rdata = &p->out_data.rdata;
1438 /* grab the samr unknown 22 */
1439 if(!samr_io_q_open_user("", &q_u, data, 0))
1442 r_u.status = _api_samr_open_user(q_u.domain_pol, q_u.user_rid, &r_u.user_pol);
1444 /* store the response in the SMB stream */
1445 if(!samr_io_r_open_user("", &r_u, rdata, 0))
1448 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1453 /*************************************************************************
1455 *************************************************************************/
1456 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1458 struct smb_passwd *smb_pass;
1460 if (!pdb_rid_is_user(user_rid))
1462 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1467 smb_pass = getsmbpwrid(user_rid);
1470 if (smb_pass == NULL)
1472 DEBUG(4,("User 0x%x not found\n", user_rid));
1476 DEBUG(3,("User:[%s]\n", smb_pass->smb_name));
1478 init_sam_user_info10(id10, smb_pass->acct_ctrl);
1483 /*************************************************************************
1485 *************************************************************************/
1486 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1489 struct sam_passwd *sam_pass;
1493 if (!pdb_rid_is_user(user_rid))
1495 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1500 sam_pass = getsam21pwrid(user_rid);
1503 if (sam_pass == NULL)
1505 DEBUG(4,("User 0x%x not found\n", user_rid));
1509 DEBUG(3,("User:[%s]\n", sam_pass->smb_name));
1511 dummy_time.low = 0xffffffff;
1512 dummy_time.high = 0x7fffffff;
1514 DEBUG(5,("get_user_info_21 - TODO: convert unix times to NTTIMEs\n"));
1516 /* create a LOGON_HRS structure */
1517 hrs.len = sam_pass->hours_len;
1518 SMB_ASSERT_ARRAY(hrs.hours, hrs.len);
1519 for (i = 0; i < hrs.len; i++)
1521 hrs.hours[i] = sam_pass->hours[i];
1524 init_sam_user_info21(id21,
1526 &dummy_time, /* logon_time */
1527 &dummy_time, /* logoff_time */
1528 &dummy_time, /* kickoff_time */
1529 &dummy_time, /* pass_last_set_time */
1530 &dummy_time, /* pass_can_change_time */
1531 &dummy_time, /* pass_must_change_time */
1533 sam_pass->smb_name, /* user_name */
1534 sam_pass->full_name, /* full_name */
1535 sam_pass->home_dir, /* home_dir */
1536 sam_pass->dir_drive, /* dir_drive */
1537 sam_pass->logon_script, /* logon_script */
1538 sam_pass->profile_path, /* profile_path */
1539 sam_pass->acct_desc, /* description */
1540 sam_pass->workstations, /* workstations user can log in from */
1541 sam_pass->unknown_str, /* don't know, yet */
1542 sam_pass->munged_dial, /* dialin info. contains dialin path and tel no */
1544 sam_pass->user_rid, /* RID user_id */
1545 sam_pass->group_rid, /* RID group_id */
1546 sam_pass->acct_ctrl,
1548 sam_pass->unknown_3, /* unknown_3 */
1549 sam_pass->logon_divs, /* divisions per week */
1550 &hrs, /* logon hours */
1551 sam_pass->unknown_5,
1552 sam_pass->unknown_6);
1557 /*******************************************************************
1558 samr_reply_query_userinfo
1559 ********************************************************************/
1560 static BOOL samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
1563 SAMR_R_QUERY_USERINFO r_u;
1565 SAM_USER_INFO_11 id11;
1567 SAM_USER_INFO_10 id10;
1568 SAM_USER_INFO_21 id21;
1571 uint32 status = 0x0;
1574 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1576 /* search for the handle */
1577 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1579 status = NT_STATUS_INVALID_HANDLE;
1582 /* find the user's rid */
1583 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1585 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1588 DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
1590 /* ok! user info levels (there are lots: see MSDEV help), off we go... */
1593 switch (q_u->switch_value)
1597 info = (void*)&id10;
1598 status = get_user_info_10(&id10, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1602 /* whoops - got this wrong. i think. or don't understand what's happening. */
1606 info = (void*)&id11;
1608 expire.low = 0xffffffff;
1609 expire.high = 0x7fffffff;
1611 make_sam_user_info11(&id11, &expire, "BROOKFIELDS$", 0x03ef, 0x201, 0x0080);
1618 info = (void*)&id21;
1619 status = get_user_info_21(&id21, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1625 status = NT_STATUS_INVALID_INFO_CLASS;
1632 init_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
1634 /* store the response in the SMB stream */
1635 if(!samr_io_r_query_userinfo("", &r_u, rdata, 0))
1638 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1643 /*******************************************************************
1644 api_samr_query_userinfo
1645 ********************************************************************/
1646 static BOOL api_samr_query_userinfo(pipes_struct *p)
1648 SAMR_Q_QUERY_USERINFO q_u;
1649 prs_struct *data = &p->in_data.data;
1650 prs_struct *rdata = &p->out_data.rdata;
1652 /* grab the samr unknown 24 */
1653 if(!samr_io_q_query_userinfo("", &q_u, data, 0))
1656 /* construct reply. always indicate success */
1657 if(!samr_reply_query_userinfo(&q_u, rdata))
1664 /*******************************************************************
1665 samr_reply_query_usergroups
1666 ********************************************************************/
1667 static BOOL samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
1670 SAMR_R_QUERY_USERGROUPS r_u;
1671 uint32 status = 0x0;
1673 struct sam_passwd *sam_pass;
1674 DOM_GID *gids = NULL;
1678 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1680 /* find the policy handle. open a policy on it. */
1681 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1683 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1686 /* find the user's rid */
1687 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1689 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1695 sam_pass = getsam21pwrid(rid);
1698 if (sam_pass == NULL)
1700 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1707 get_domain_user_groups(groups, sam_pass->smb_name);
1709 num_groups = make_dom_gids(groups, &gids);
1712 /* construct the response. lkclXXXX: gids are not copied! */
1713 init_samr_r_query_usergroups(&r_u, num_groups, gids, status);
1715 /* store the response in the SMB stream */
1716 if(!samr_io_r_query_usergroups("", &r_u, rdata, 0)) {
1725 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1730 /*******************************************************************
1731 api_samr_query_usergroups
1732 ********************************************************************/
1733 static BOOL api_samr_query_usergroups(pipes_struct *p)
1735 SAMR_Q_QUERY_USERGROUPS q_u;
1736 prs_struct *data = &p->in_data.data;
1737 prs_struct *rdata = &p->out_data.rdata;
1739 /* grab the samr unknown 32 */
1740 if(!samr_io_q_query_usergroups("", &q_u, data, 0))
1743 /* construct reply. */
1744 if(!samr_reply_query_usergroups(&q_u, rdata))
1751 /*******************************************************************
1752 api_samr_query_dom_info
1753 ********************************************************************/
1754 static BOOL api_samr_query_dom_info(pipes_struct *p)
1756 SAMR_Q_QUERY_DOMAIN_INFO q_u;
1757 SAMR_R_QUERY_DOMAIN_INFO r_u;
1759 prs_struct *data = &p->in_data.data;
1760 prs_struct *rdata = &p->out_data.rdata;
1762 uint16 switch_value = 0x0;
1763 uint32 status = 0x0;
1769 DEBUG(5,("api_samr_query_dom_info: %d\n", __LINE__));
1771 /* grab the samr unknown 8 command */
1772 if(!samr_io_q_query_dom_info("", &q_u, data, 0))
1775 /* find the policy handle. open a policy on it. */
1776 if (find_lsa_policy_by_hnd(&q_u.domain_pol) == -1) {
1777 status = NT_STATUS_INVALID_HANDLE;
1778 DEBUG(5,("api_samr_query_dom_info: invalid handle\n"));
1781 if (status == 0x0) {
1782 switch (q_u.switch_value) {
1785 init_unk_info1(&ctr.info.inf1);
1789 init_unk_info2(&ctr.info.inf2, global_myworkgroup, global_myname);
1793 init_unk_info3(&ctr.info.inf3);
1797 init_unk_info6(&ctr.info.inf6);
1801 init_unk_info7(&ctr.info.inf7);
1805 init_unk_info12(&ctr.info.inf12);
1808 status = NT_STATUS_INVALID_INFO_CLASS;
1813 init_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
1815 /* store the response in the SMB stream */
1816 if(!samr_io_r_query_dom_info("", &r_u, rdata, 0))
1819 DEBUG(5,("api_samr_query_dom_info: %d\n", __LINE__));
1825 /*******************************************************************
1826 _api_samr_create_user
1827 ********************************************************************/
1828 static BOOL _api_samr_create_user(POLICY_HND dom_pol, UNISTR2 user_account, uint32 acb_info, uint32 access_mask,
1829 POLICY_HND *user_pol, uint32 *unknown0, uint32 *user_rid)
1831 struct sam_passwd *sam_pass;
1838 /* find the policy handle. open a policy on it. */
1839 if (find_lsa_policy_by_hnd(&dom_pol) == -1)
1840 return NT_STATUS_INVALID_HANDLE;
1842 /* find the machine account: tell the caller if it exists.
1843 lkclXXXX i have *no* idea if this is a problem or not
1844 or even if you are supposed to construct a different
1845 reply if the account already exists...
1848 fstrcpy(mach_acct, dos_unistrn2(user_account.buffer, user_account.uni_str_len));
1849 strlower(mach_acct);
1852 sam_pass = getsam21pwnam(mach_acct);
1854 if (sam_pass != NULL) {
1855 /* machine account exists: say so */
1856 return NT_STATUS_USER_EXISTS;
1859 /* get a (unique) handle. open a policy on it. */
1860 if (!open_lsa_policy_hnd(user_pol))
1861 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1863 local_flags=LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_SET_NO_PASSWORD;
1864 local_flags|= (acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0;
1867 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
1868 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
1869 * that only people with write access to the smbpasswd file will be able
1870 * to create a user. JRA.
1873 /* add the user in the /etc/passwd file or the unix authority system */
1874 if (lp_adduser_script())
1875 smb_create_user(mach_acct);
1877 /* add the user in the smbpasswd file or the Samba authority database */
1878 if (!local_password_change(mach_acct, local_flags, NULL, err_str, sizeof(err_str), msg_str, sizeof(msg_str))) {
1879 DEBUG(0, ("%s\n", err_str));
1880 close_lsa_policy_hnd(user_pol);
1881 return NT_STATUS_ACCESS_DENIED;
1885 sam_pass = getsam21pwnam(mach_acct);
1887 if (sam_pass == NULL) {
1888 /* account doesn't exist: say so */
1889 close_lsa_policy_hnd(user_pol);
1890 return NT_STATUS_ACCESS_DENIED;
1893 /* Get the domain SID stored in the domain policy */
1894 if(!get_lsa_policy_samr_sid(&dom_pol, &sid)) {
1895 close_lsa_policy_hnd(user_pol);
1896 return NT_STATUS_INVALID_HANDLE;
1899 /* append the user's RID to it */
1900 if(!sid_append_rid(&sid, sam_pass->user_rid)) {
1901 close_lsa_policy_hnd(user_pol);
1902 return NT_STATUS_NO_SUCH_USER;
1905 /* associate the RID with the (unique) handle. */
1906 if (!set_lsa_policy_samr_sid(user_pol, &sid)) {
1907 /* oh, whoops. don't know what error message to return, here */
1908 close_lsa_policy_hnd(user_pol);
1909 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1912 *unknown0=0x000703ff;
1913 *user_rid=sam_pass->user_rid;
1915 return NT_STATUS_NO_PROBLEMO;
1918 /*******************************************************************
1919 api_samr_create_user
1920 ********************************************************************/
1921 static BOOL api_samr_create_user(pipes_struct *p)
1923 prs_struct *data = &p->in_data.data;
1924 prs_struct *rdata = &p->out_data.rdata;
1926 SAMR_Q_CREATE_USER q_u;
1927 SAMR_R_CREATE_USER r_u;
1932 /* grab the samr create user */
1933 if (!samr_io_q_create_user("", &q_u, data, 0)) {
1934 DEBUG(0,("api_samr_create_user: Unable to unmarshall SAMR_Q_CREATE_USER.\n"));
1938 r_u.status=_api_samr_create_user(q_u.pol, q_u.uni_mach_acct, q_u.acb_info, q_u.access_mask,
1939 &r_u.pol, &r_u.unknown_0, &r_u.user_rid);
1941 /* store the response in the SMB stream */
1942 if(!samr_io_r_create_user("", &r_u, rdata, 0)) {
1943 DEBUG(0,("api_samr_create_user: Unable to marshall SAMR_R_CREATE_USER.\n"));
1951 /*******************************************************************
1952 samr_reply_connect_anon
1953 ********************************************************************/
1954 static BOOL samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u, prs_struct *rdata)
1956 SAMR_R_CONNECT_ANON r_u;
1957 BOOL pol_open = False;
1959 /* set up the SAMR connect_anon response */
1962 /* get a (unique) handle. open a policy on it. */
1963 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1965 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1968 /* associate the domain SID with the (unique) handle. */
1969 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1971 /* oh, whoops. don't know what error message to return, here */
1972 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1975 if (r_u.status != 0 && pol_open)
1977 close_lsa_policy_hnd(&(r_u.connect_pol));
1980 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1982 /* store the response in the SMB stream */
1983 if(!samr_io_r_connect_anon("", &r_u, rdata, 0))
1986 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1991 /*******************************************************************
1992 api_samr_connect_anon
1993 ********************************************************************/
1994 static BOOL api_samr_connect_anon(pipes_struct *p)
1996 SAMR_Q_CONNECT_ANON q_u;
1997 prs_struct *data = &p->in_data.data;
1998 prs_struct *rdata = &p->out_data.rdata;
2000 /* grab the samr open policy */
2001 if(!samr_io_q_connect_anon("", &q_u, data, 0))
2004 /* construct reply. always indicate success */
2005 if(!samr_reply_connect_anon(&q_u, rdata))
2011 /*******************************************************************
2013 ********************************************************************/
2014 static BOOL samr_reply_connect(SAMR_Q_CONNECT *q_u, prs_struct *rdata)
2017 BOOL pol_open = False;
2019 /* set up the SAMR connect response */
2022 /* get a (unique) handle. open a policy on it. */
2023 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
2025 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2028 /* associate the domain SID with the (unique) handle. */
2029 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
2031 /* oh, whoops. don't know what error message to return, here */
2032 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2035 if (r_u.status != 0 && pol_open)
2037 close_lsa_policy_hnd(&(r_u.connect_pol));
2040 DEBUG(5,("samr_connect: %d\n", __LINE__));
2042 /* store the response in the SMB stream */
2043 if(!samr_io_r_connect("", &r_u, rdata, 0))
2046 DEBUG(5,("samr_connect: %d\n", __LINE__));
2051 /*******************************************************************
2053 ********************************************************************/
2054 static BOOL api_samr_connect(pipes_struct *p)
2057 prs_struct *data = &p->in_data.data;
2058 prs_struct *rdata = &p->out_data.rdata;
2060 /* grab the samr open policy */
2061 if(!samr_io_q_connect("", &q_u, data, 0))
2064 /* construct reply. always indicate success */
2065 if(!samr_reply_connect(&q_u, rdata))
2072 /**********************************************************************
2073 api_samr_lookup_domain
2074 **********************************************************************/
2075 static BOOL api_samr_lookup_domain(pipes_struct *p)
2077 SAMR_Q_LOOKUP_DOMAIN q_u;
2078 SAMR_R_LOOKUP_DOMAIN r_u;
2079 prs_struct *data = &p->in_data.data;
2080 prs_struct *rdata = &p->out_data.rdata;
2085 if(!samr_io_q_lookup_domain("", &q_u, data, 0)) {
2086 DEBUG(0,("api_samr_lookup_domain: Unable to unmarshall SAMR_Q_LOOKUP_DOMAIN.\n"));
2092 if (find_lsa_policy_by_hnd(&q_u.connect_pol) == -1){
2093 r_u.status = NT_STATUS_INVALID_HANDLE;
2094 DEBUG(5,("api_samr_lookup_domain: invalid handle\n"));
2097 /* assume the domain name sent is our global_myname and
2098 send global_sam_sid */
2099 init_samr_r_lookup_domain(&r_u, &global_sam_sid, r_u.status);
2101 if(!samr_io_r_lookup_domain("", &r_u, rdata, 0)){
2102 DEBUG(0,("api_samr_lookup_domain: Unable to marshall SAMR_R_LOOKUP_DOMAIN.\n"));
2109 /**********************************************************************
2110 api_samr_enum_domains
2111 **********************************************************************/
2112 static BOOL api_samr_enum_domains(pipes_struct *p)
2114 SAMR_Q_ENUM_DOMAINS q_u;
2115 SAMR_R_ENUM_DOMAINS r_u;
2116 prs_struct *data = &p->in_data.data;
2117 prs_struct *rdata = &p->out_data.rdata;
2124 fstrcpy(dom[0],global_myname);
2125 fstrcpy(dom[1],"Builtin");
2127 if(!samr_io_q_enum_domains("", &q_u, data, 0)) {
2128 DEBUG(0,("api_samr_enum_domains: Unable to unmarshall SAMR_Q_ENUM_DOMAINS.\n"));
2132 r_u.status = NT_STATUS_NO_PROBLEMO;
2134 init_samr_r_enum_domains(&r_u, q_u.start_idx, dom, 2);
2136 if(!samr_io_r_enum_domains("", &r_u, rdata, 0)) {
2137 DEBUG(0,("api_samr_enum_domains: Unable to marshall SAMR_R_ENUM_DOMAINS.\n"));
2139 free(r_u.uni_dom_name);
2144 free(r_u.uni_dom_name);
2150 /*******************************************************************
2152 ********************************************************************/
2153 static uint32 _api_samr_open_alias(POLICY_HND domain_pol, uint32 alias_rid, POLICY_HND *alias_pol)
2157 /* get the domain policy. */
2158 if (find_lsa_policy_by_hnd(&domain_pol) == -1)
2159 return NT_STATUS_INVALID_HANDLE;
2161 /* get a (unique) handle. open a policy on it. */
2162 if (!open_lsa_policy_hnd(alias_pol))
2163 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2165 /* Get the domain SID stored in the domain policy */
2166 if(!get_lsa_policy_samr_sid(&domain_pol, &sid)) {
2167 close_lsa_policy_hnd(alias_pol);
2168 return NT_STATUS_INVALID_HANDLE;
2171 /* append the alias' RID to it */
2172 if(!sid_append_rid(&sid, alias_rid)) {
2173 close_lsa_policy_hnd(alias_pol);
2174 return NT_STATUS_NO_SUCH_USER;
2177 /* associate a RID with the (unique) handle. */
2178 if (!set_lsa_policy_samr_sid(alias_pol, &sid)) {
2179 /* oh, whoops. don't know what error message to return, here */
2180 close_lsa_policy_hnd(alias_pol);
2181 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2184 return NT_STATUS_NO_PROBLEMO;
2187 /*******************************************************************
2189 ********************************************************************/
2190 static BOOL api_samr_open_alias(pipes_struct *p)
2192 SAMR_Q_OPEN_ALIAS q_u;
2193 SAMR_R_OPEN_ALIAS r_u;
2194 prs_struct *data = &p->in_data.data;
2195 prs_struct *rdata = &p->out_data.rdata;
2200 /* grab the samr open policy */
2201 if(!samr_io_q_open_alias("", &q_u, data, 0)) {
2202 DEBUG(0,("api_samr_open_alias: Unable to unmarshall SAMR_Q_OPEN_ALIAS.\n"));
2206 r_u.status=_api_samr_open_alias(q_u.dom_pol, q_u.rid_alias, &r_u.pol);
2208 /* store the response in the SMB stream */
2209 if(!samr_io_r_open_alias("", &r_u, rdata, 0)) {
2210 DEBUG(0,("api_samr_open_alias: Unable to marshall SAMR_R_OPEN_ALIAS.\n"));
2217 /*******************************************************************
2219 ********************************************************************/
2220 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid)
2222 struct sam_passwd *pwd = getsam21pwrid(rid);
2223 struct sam_passwd new_pwd;
2226 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2233 copy_sam_passwd(&new_pwd, pwd);
2235 new_pwd.acct_ctrl = id10->acb_info;
2237 if(!mod_sam21pwd_entry(&new_pwd, True))
2243 /*******************************************************************
2245 ********************************************************************/
2246 static BOOL set_user_info_12(const SAM_USER_INFO_12 *id12, uint32 rid)
2248 struct sam_passwd *pwd = getsam21pwrid(rid);
2249 struct sam_passwd new_pwd;
2250 static uchar nt_hash[16];
2251 static uchar lm_hash[16];
2257 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2261 pdb_init_sam(&new_pwd);
2262 copy_sam_passwd(&new_pwd, pwd);
2264 memcpy(nt_hash, id12->nt_pwd, sizeof(nt_hash));
2265 memcpy(lm_hash, id12->lm_pwd, sizeof(lm_hash));
2267 new_pwd.smb_passwd = lm_hash;
2268 new_pwd.smb_nt_passwd = nt_hash;
2270 if(!mod_sam21pwd_entry(&new_pwd, True))
2276 /*******************************************************************
2278 ********************************************************************/
2279 static BOOL set_user_info_21(SAM_USER_INFO_21 * id21, uint32 rid)
2281 struct sam_passwd *pwd = getsam21pwrid(rid);
2282 struct sam_passwd new_pwd;
2283 static uchar nt_hash[16];
2284 static uchar lm_hash[16];
2287 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2294 pdb_init_sam(&new_pwd);
2295 copy_sam_passwd(&new_pwd, pwd);
2296 copy_id21_to_sam_passwd(&new_pwd, id21);
2298 if (pwd->smb_nt_passwd != NULL) {
2299 memcpy(nt_hash, pwd->smb_nt_passwd, 16);
2300 new_pwd.smb_nt_passwd = nt_hash;
2302 new_pwd.smb_nt_passwd = NULL;
2304 if (pwd->smb_nt_passwd != NULL) {
2305 memcpy(lm_hash, pwd->smb_passwd, 16);
2306 new_pwd.smb_passwd = lm_hash;
2308 new_pwd.smb_passwd = NULL;
2310 if(!mod_sam21pwd_entry(&new_pwd, True))
2316 /*******************************************************************
2318 ********************************************************************/
2319 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
2321 struct sam_passwd *pwd = getsam21pwrid(rid);
2322 struct sam_passwd new_pwd;
2323 static uchar nt_hash[16];
2324 static uchar lm_hash[16];
2329 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2336 pdb_init_sam(&new_pwd);
2337 copy_sam_passwd(&new_pwd, pwd);
2338 copy_id23_to_sam_passwd(&new_pwd, id23);
2340 if (!decode_pw_buffer(id23->pass, buf, 256, &len))
2343 nt_lm_owf_gen(buf, nt_hash, lm_hash);
2345 new_pwd.smb_passwd = lm_hash;
2346 new_pwd.smb_nt_passwd = nt_hash;
2348 /* update the UNIX password */
2349 if (lp_unix_password_sync())
2350 if(!chgpasswd(new_pwd.smb_name, "", buf, True))
2353 memset(buf, 0, sizeof(buf));
2355 if(!mod_sam21pwd_entry(&new_pwd, True))
2361 /*******************************************************************
2363 ********************************************************************/
2364 static BOOL set_user_info_24(const SAM_USER_INFO_24 *id24, uint32 rid)
2366 struct sam_passwd *pwd = getsam21pwrid(rid);
2367 struct sam_passwd new_pwd;
2368 static uchar nt_hash[16];
2369 static uchar lm_hash[16];
2376 pdb_init_sam(&new_pwd);
2377 copy_sam_passwd(&new_pwd, pwd);
2379 if (!decode_pw_buffer(id24->pass, buf, 256, &len))
2382 nt_lm_owf_gen(buf, nt_hash, lm_hash);
2384 new_pwd.smb_passwd = lm_hash;
2385 new_pwd.smb_nt_passwd = nt_hash;
2387 /* update the UNIX password */
2388 if (lp_unix_password_sync())
2389 if(!chgpasswd(new_pwd.smb_name, "", buf, True))
2392 memset(buf, 0, sizeof(buf));
2394 /* update the SAMBA password */
2395 if(!mod_sam21pwd_entry(&new_pwd, True))
2401 /*******************************************************************
2402 samr_reply_set_userinfo
2403 ********************************************************************/
2404 static uint32 _samr_set_userinfo(POLICY_HND *pol, uint16 switch_value, SAM_USERINFO_CTR *ctr, pipes_struct *p)
2408 struct current_user user;
2409 struct smb_passwd *smb_pass;
2410 unsigned char sess_key[16];
2412 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2414 if (p->ntlmssp_auth_validated) {
2415 memcpy(&user, &p->pipe_user, sizeof(user));
2417 extern struct current_user current_user;
2418 memcpy(&user, ¤t_user, sizeof(user));
2421 /* search for the handle */
2422 if (find_lsa_policy_by_hnd(pol) == -1)
2423 return NT_STATUS_INVALID_HANDLE;
2425 /* find the policy handle. open a policy on it. */
2426 if (!get_lsa_policy_samr_sid(pol, &sid))
2427 return NT_STATUS_INVALID_HANDLE;
2429 sid_split_rid(&sid, &rid);
2431 DEBUG(5, ("_samr_set_userinfo: rid:0x%x, level:%d\n", rid, switch_value));
2434 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2435 return NT_STATUS_INVALID_INFO_CLASS;
2440 * We need the NT hash of the user who is changing the user's password.
2441 * This NT hash is used to generate a "user session key"
2442 * This "user session key" is in turn used to encrypt/decrypt the user's password.
2446 smb_pass = getsmbpwuid(user.uid);
2448 if(smb_pass == NULL) {
2449 DEBUG(0,("_samr_set_userinfo: Unable to get smbpasswd entry for uid %u\n", (unsigned int)user.uid ));
2450 return NT_STATUS_ACCESS_DENIED;
2453 memset(sess_key, '\0', 16);
2454 mdfour(sess_key, smb_pass->smb_nt_passwd, 16);
2456 /* ok! user info levels (lots: see MSDEV help), off we go... */
2457 switch (switch_value) {
2459 if (!set_user_info_12(ctr->info.id12, rid))
2460 return NT_STATUS_ACCESS_DENIED;
2464 SamOEMhash(ctr->info.id24->pass, sess_key, 1);
2465 if (!set_user_info_24(ctr->info.id24, rid))
2466 return NT_STATUS_ACCESS_DENIED;
2470 SamOEMhash(ctr->info.id23->pass, sess_key, 1);
2471 if (!set_user_info_23(ctr->info.id23, rid))
2472 return NT_STATUS_ACCESS_DENIED;
2476 return NT_STATUS_INVALID_INFO_CLASS;
2479 return NT_STATUS_NOPROBLEMO;
2482 /*******************************************************************
2483 api_samr_set_userinfo
2484 ********************************************************************/
2485 static BOOL api_samr_set_userinfo(pipes_struct *p)
2487 SAMR_Q_SET_USERINFO q_u;
2488 SAMR_R_SET_USERINFO r_u;
2490 prs_struct *data = &p->in_data.data;
2491 prs_struct *rdata = &p->out_data.rdata;
2493 SAM_USERINFO_CTR ctr;
2500 if (!samr_io_q_set_userinfo("", &q_u, data, 0)) {
2501 DEBUG(0,("api_samr_set_userinfo: Unable to unmarshall SAMR_Q_SET_USERINFO.\n"));
2505 r_u.status = _samr_set_userinfo(&q_u.pol, q_u.switch_value, &ctr, p);
2507 free_samr_q_set_userinfo(&q_u);
2509 if(!samr_io_r_set_userinfo("", &r_u, rdata, 0)) {
2510 DEBUG(0,("api_samr_set_userinfo: Unable to marshall SAMR_R_SET_USERINFO.\n"));
2517 /*******************************************************************
2518 samr_reply_set_userinfo2
2519 ********************************************************************/
2520 static uint32 _samr_set_userinfo2(POLICY_HND *pol, uint16 switch_value, SAM_USERINFO_CTR *ctr)
2525 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
2527 /* search for the handle */
2528 if (find_lsa_policy_by_hnd(pol) == -1)
2529 return NT_STATUS_INVALID_HANDLE;
2531 /* find the policy handle. open a policy on it. */
2532 if (!get_lsa_policy_samr_sid(pol, &sid))
2533 return NT_STATUS_INVALID_HANDLE;
2535 sid_split_rid(&sid, &rid);
2537 DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid));
2540 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
2541 return NT_STATUS_INVALID_INFO_CLASS;
2544 ctr->switch_value = switch_value;
2546 /* ok! user info levels (lots: see MSDEV help), off we go... */
2547 switch (switch_value) {
2549 if (!set_user_info_21(ctr->info.id21, rid))
2550 return NT_STATUS_ACCESS_DENIED;
2553 if (!set_user_info_10(ctr->info.id10, rid))
2554 return NT_STATUS_ACCESS_DENIED;
2557 return NT_STATUS_INVALID_INFO_CLASS;
2560 return NT_STATUS_NOPROBLEMO;
2563 /*******************************************************************
2564 api_samr_set_userinfo2
2565 ********************************************************************/
2566 static BOOL api_samr_set_userinfo2(pipes_struct *p)
2568 SAMR_Q_SET_USERINFO2 q_u;
2569 SAMR_R_SET_USERINFO2 r_u;
2570 SAM_USERINFO_CTR ctr;
2572 prs_struct *data = &p->in_data.data;
2573 prs_struct *rdata = &p->out_data.rdata;
2580 if (!samr_io_q_set_userinfo2("", &q_u, data, 0)) {
2581 DEBUG(0,("api_samr_set_userinfo2: Unable to unmarshall SAMR_Q_SET_USERINFO2.\n"));
2585 r_u.status = _samr_set_userinfo2(&q_u.pol, q_u.switch_value, &ctr);
2587 free_samr_q_set_userinfo2(&q_u);
2589 if(!samr_io_r_set_userinfo2("", &r_u, rdata, 0)) {
2590 DEBUG(0,("api_samr_set_userinfo2: Unable to marshall SAMR_R_SET_USERINFO2.\n"));
2598 /*******************************************************************
2599 array of \PIPE\samr operations
2600 ********************************************************************/
2601 static struct api_struct api_samr_cmds [] =
2603 { "SAMR_CLOSE_HND" , SAMR_CLOSE_HND , api_samr_close_hnd },
2604 { "SAMR_CONNECT" , SAMR_CONNECT , api_samr_connect },
2605 { "SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON , api_samr_connect_anon },
2606 { "SAMR_ENUM_DOM_USERS" , SAMR_ENUM_DOM_USERS , api_samr_enum_dom_users },
2607 { "SAMR_ENUM_DOM_GROUPS" , SAMR_ENUM_DOM_GROUPS , api_samr_enum_dom_groups },
2608 { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
2609 { "SAMR_LOOKUP_IDS" , SAMR_LOOKUP_IDS , api_samr_lookup_ids },
2610 { "SAMR_LOOKUP_NAMES" , SAMR_LOOKUP_NAMES , api_samr_lookup_names },
2611 { "SAMR_OPEN_USER" , SAMR_OPEN_USER , api_samr_open_user },
2612 { "SAMR_QUERY_USERINFO" , SAMR_QUERY_USERINFO , api_samr_query_userinfo },
2613 { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
2614 { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
2615 { "SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo },
2616 { "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo },
2617 { "SAMR_CREATE_USER" , SAMR_CREATE_USER , api_samr_create_user },
2618 { "SAMR_LOOKUP_RIDS" , SAMR_LOOKUP_RIDS , api_samr_lookup_rids },
2619 { "SAMR_UNKNOWN_38" , SAMR_UNKNOWN_38 , api_samr_unknown_38 },
2620 { "SAMR_CHGPASSWD_USER" , SAMR_CHGPASSWD_USER , api_samr_chgpasswd_user },
2621 { "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias },
2622 { "SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain },
2623 { "SAMR_UNKNOWN_3" , SAMR_UNKNOWN_3 , api_samr_unknown_3 },
2624 { "SAMR_UNKNOWN_2C" , SAMR_UNKNOWN_2C , api_samr_unknown_2c },
2625 { "SAMR_LOOKUP_DOMAIN" , SAMR_LOOKUP_DOMAIN , api_samr_lookup_domain },
2626 { "SAMR_ENUM_DOMAINS" , SAMR_ENUM_DOMAINS , api_samr_enum_domains },
2627 { "SAMR_SET_USERINFO" , SAMR_SET_USERINFO , api_samr_set_userinfo },
2628 { "SAMR_SET_USERINFO2" , SAMR_SET_USERINFO2 , api_samr_set_userinfo2 },
2632 /*******************************************************************
2633 receives a samr pipe and responds.
2634 ********************************************************************/
2635 BOOL api_samr_rpc(pipes_struct *p)
2637 return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds);