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.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 extern int DEBUGLEVEL;
31 extern fstring global_sam_name;
32 extern pstring global_myname;
33 extern DOM_SID global_sam_sid;
34 extern DOM_SID global_sid_S_1_1;
35 extern DOM_SID global_sid_S_1_5_20;
37 /*******************************************************************
38 This next function should be replaced with something that
39 dynamically returns the correct user info..... JRA.
40 ********************************************************************/
42 static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf,
44 int *total_entries, int *num_entries,
49 struct sam_passwd *pwd = NULL;
54 if (pw_buf == NULL) return False;
56 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)
69 /* skip the requested number of entries.
70 not very efficient, but hey...
72 if (acb_mask == 0 || IS_BITS_SET_SOME(pwd->acct_ctrl, acb_mask))
79 user_name_len = strlen(pwd->nt_name);
80 make_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->nt_name, user_name_len);
81 make_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
82 pw_buf[(*num_entries)].user_rid = pwd->user_rid;
83 bzero( pw_buf[(*num_entries)].nt_pwd , 16);
85 /* Now check if the NT compatible password is available. */
86 if (pwd->smb_nt_passwd != NULL)
88 memcpy( pw_buf[(*num_entries)].nt_pwd , pwd->smb_nt_passwd, 16);
91 pw_buf[(*num_entries)].acb_info = (uint16)pwd->acct_ctrl;
93 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
94 (*num_entries), pwd->nt_name,
95 pwd->user_rid, pwd->acct_ctrl));
97 if (acb_mask == 0 || IS_BITS_SET_SOME(pwd->acct_ctrl, acb_mask))
99 DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
104 DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
112 return (*num_entries) > 0;
115 /*******************************************************************
117 ********************************************************************/
118 static void samr_reply_close_hnd(SAMR_Q_CLOSE_HND *q_u,
121 SAMR_R_CLOSE_HND r_u;
123 /* set up the SAMR unknown_1 response */
124 bzero(r_u.pol.data, POL_HND_SIZE);
126 /* close the policy handle */
127 if (close_policy_hnd(&(q_u->pol)))
133 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_INVALID;
136 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
138 /* store the response in the SMB stream */
139 samr_io_r_close_hnd("", &r_u, rdata, 0);
141 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
145 /*******************************************************************
147 ********************************************************************/
148 static void api_samr_close_hnd( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
150 SAMR_Q_CLOSE_HND q_u;
151 samr_io_q_close_hnd("", &q_u, data, 0);
152 samr_reply_close_hnd(&q_u, rdata);
156 /*******************************************************************
157 samr_reply_open_domain
158 ********************************************************************/
159 static void samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
162 SAMR_R_OPEN_DOMAIN r_u;
163 BOOL pol_open = False;
167 /* find the connection policy handle. */
168 if (r_u.status == 0x0 && (find_policy_by_hnd(&(q_u->connect_pol)) == -1))
170 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
173 /* get a (unique) handle. open a policy on it. */
174 if (r_u.status == 0x0 && !(pol_open = open_policy_hnd(&(r_u.domain_pol))))
176 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
179 /* associate the domain SID with the (unique) handle. */
180 if (r_u.status == 0x0 && !set_policy_samr_sid(&(r_u.domain_pol), &(q_u->dom_sid.sid)))
182 /* oh, whoops. don't know what error message to return, here */
183 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
186 if (r_u.status != 0 && pol_open)
188 close_policy_hnd(&(r_u.domain_pol));
191 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
193 /* store the response in the SMB stream */
194 samr_io_r_open_domain("", &r_u, rdata, 0);
196 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
200 /*******************************************************************
202 ********************************************************************/
203 static void api_samr_open_domain( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
205 SAMR_Q_OPEN_DOMAIN q_u;
206 samr_io_q_open_domain("", &q_u, data, 0);
207 samr_reply_open_domain(&q_u, rdata);
211 /*******************************************************************
212 samr_reply_unknown_2c
213 ********************************************************************/
214 static void samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u,
217 SAMR_R_UNKNOWN_2C r_u;
220 /* find the policy handle. open a policy on it. */
221 if (status == 0x0 && (find_policy_by_hnd(&(q_u->user_pol)) == -1))
223 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
226 /* find the user's rid */
227 if ((status == 0x0) && (get_policy_samr_rid(&(q_u->user_pol)) == 0xffffffff))
229 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
232 make_samr_r_unknown_2c(&r_u, status);
234 DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
236 /* store the response in the SMB stream */
237 samr_io_r_unknown_2c("", &r_u, rdata, 0);
239 DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
243 /*******************************************************************
245 ********************************************************************/
246 static void api_samr_unknown_2c( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
248 SAMR_Q_UNKNOWN_2C q_u;
249 samr_io_q_unknown_2c("", &q_u, data, 0);
250 samr_reply_unknown_2c(&q_u, rdata);
254 /*******************************************************************
256 ********************************************************************/
257 static void samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
260 SAMR_R_UNKNOWN_3 r_u;
261 DOM_SID3 sid[MAX_SAM_SIDS];
267 /* find the policy handle. open a policy on it. */
268 if (status == 0x0 && (find_policy_by_hnd(&(q_u->user_pol)) == -1))
270 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
273 /* find the user's rid */
274 if (status == 0x0 && (rid = get_policy_samr_rid(&(q_u->user_pol))) == 0xffffffff)
276 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
283 usr_sid = global_sam_sid;
285 SMB_ASSERT_ARRAY(usr_sid.sub_auths, usr_sid.num_auths+1);
290 sid_append_rid(&usr_sid, rid);
292 /* maybe need another 1 or 2 (S-1-5-0x20-0x220 and S-1-5-20-0x224) */
293 /* these two are DOMAIN_ADMIN and DOMAIN_ACCT_OP group RIDs */
294 make_dom_sid3(&(sid[0]), 0x035b, 0x0002, &global_sid_S_1_1);
295 make_dom_sid3(&(sid[1]), 0x0044, 0x0002, &usr_sid);
298 make_samr_r_unknown_3(&r_u,
300 0x00000014, 0x0002, 0x0070,
303 DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
305 /* store the response in the SMB stream */
306 samr_io_r_unknown_3("", &r_u, rdata, 0);
308 DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
312 /*******************************************************************
314 ********************************************************************/
315 static void api_samr_unknown_3( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
317 SAMR_Q_UNKNOWN_3 q_u;
318 samr_io_q_unknown_3("", &q_u, data, 0);
319 samr_reply_unknown_3(&q_u, rdata);
323 /*******************************************************************
324 samr_reply_enum_dom_users
325 ********************************************************************/
326 static void samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
329 SAMR_R_ENUM_DOM_USERS r_e;
330 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
336 /* find the policy handle. open a policy on it. */
337 if (r_e.status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
339 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
342 DEBUG(5,("samr_reply_enum_dom_users: %d\n", __LINE__));
345 get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
346 MAX_SAM_ENTRIES, q_u->acb_mask);
349 make_samr_r_enum_dom_users(&r_e,
350 q_u->start_idx + num_entries, num_entries,
353 /* store the response in the SMB stream */
354 samr_io_r_enum_dom_users("", &r_e, rdata, 0);
361 if (r_e.uni_acct_name != NULL)
363 free(r_e.uni_acct_name);
366 DEBUG(5,("samr_enum_dom_users: %d\n", __LINE__));
370 /*******************************************************************
371 api_samr_enum_dom_users
372 ********************************************************************/
373 static void api_samr_enum_dom_users( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
375 SAMR_Q_ENUM_DOM_USERS q_e;
376 samr_io_q_enum_dom_users("", &q_e, data, 0);
377 samr_reply_enum_dom_users(&q_e, rdata);
381 /*******************************************************************
382 samr_reply_add_groupmem
383 ********************************************************************/
384 static void samr_reply_add_groupmem(SAMR_Q_ADD_GROUPMEM *q_u,
387 SAMR_R_ADD_GROUPMEM r_e;
390 fstring group_sid_str;
394 /* find the policy handle. open a policy on it. */
395 if (r_e.status == 0x0 && !get_policy_samr_sid(&q_u->pol, &group_sid))
397 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
401 sid_to_string(group_sid_str, &group_sid);
402 sid_split_rid(&group_sid, &group_rid);
405 if (r_e.status == 0x0)
407 DEBUG(10,("sid is %s\n", group_sid_str));
409 if (sid_equal(&group_sid, &global_sam_sid))
411 DEBUG(10,("lookup on Domain SID\n"));
414 r_e.status = add_group_member(group_rid, q_u->rid) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
419 r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_GROUP;
423 /* store the response in the SMB stream */
424 samr_io_r_add_groupmem("", &r_e, rdata, 0);
426 DEBUG(5,("samr_add_groupmem: %d\n", __LINE__));
429 /*******************************************************************
430 api_samr_add_groupmem
431 ********************************************************************/
432 static void api_samr_add_groupmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
434 SAMR_Q_ADD_GROUPMEM q_e;
435 samr_io_q_add_groupmem("", &q_e, data, 0);
436 samr_reply_add_groupmem(&q_e, rdata);
439 /*******************************************************************
440 samr_reply_del_groupmem
441 ********************************************************************/
442 static void samr_reply_del_groupmem(SAMR_Q_DEL_GROUPMEM *q_u,
445 SAMR_R_DEL_GROUPMEM r_e;
448 fstring group_sid_str;
452 /* find the policy handle. open a policy on it. */
453 if (r_e.status == 0x0 && !get_policy_samr_sid(&q_u->pol, &group_sid))
455 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
459 sid_to_string(group_sid_str, &group_sid);
460 sid_split_rid(&group_sid, &group_rid);
463 if (r_e.status == 0x0)
465 DEBUG(10,("sid is %s\n", group_sid_str));
467 if (sid_equal(&group_sid, &global_sam_sid))
469 DEBUG(10,("lookup on Domain SID\n"));
472 r_e.status = del_group_member(group_rid, q_u->rid) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
477 r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_GROUP;
481 /* store the response in the SMB stream */
482 samr_io_r_del_groupmem("", &r_e, rdata, 0);
484 DEBUG(5,("samr_del_groupmem: %d\n", __LINE__));
487 /*******************************************************************
488 api_samr_del_groupmem
489 ********************************************************************/
490 static void api_samr_del_groupmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
492 SAMR_Q_DEL_GROUPMEM q_e;
493 samr_io_q_del_groupmem("", &q_e, data, 0);
494 samr_reply_del_groupmem(&q_e, rdata);
497 /*******************************************************************
498 samr_reply_add_aliasmem
499 ********************************************************************/
500 static void samr_reply_add_aliasmem(SAMR_Q_ADD_ALIASMEM *q_u,
503 SAMR_R_ADD_ALIASMEM r_e;
506 fstring alias_sid_str;
510 /* find the policy handle. open a policy on it. */
511 if (r_e.status == 0x0 && !get_policy_samr_sid(&q_u->alias_pol, &alias_sid))
513 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
517 sid_to_string(alias_sid_str, &alias_sid);
518 sid_split_rid(&alias_sid, &alias_rid);
521 if (r_e.status == 0x0)
523 DEBUG(10,("sid is %s\n", alias_sid_str));
525 if (sid_equal(&alias_sid, &global_sam_sid))
527 DEBUG(10,("add member on Domain SID\n"));
530 r_e.status = add_alias_member(alias_rid, &q_u->sid.sid) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
533 else if (sid_equal(&alias_sid, &global_sid_S_1_5_20))
535 DEBUG(10,("add member on BUILTIN SID\n"));
538 r_e.status = add_builtin_member(alias_rid, &q_u->sid.sid) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
543 r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
547 /* store the response in the SMB stream */
548 samr_io_r_add_aliasmem("", &r_e, rdata, 0);
550 DEBUG(5,("samr_add_aliasmem: %d\n", __LINE__));
553 /*******************************************************************
554 api_samr_add_aliasmem
555 ********************************************************************/
556 static void api_samr_add_aliasmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
558 SAMR_Q_ADD_ALIASMEM q_e;
559 samr_io_q_add_aliasmem("", &q_e, data, 0);
560 samr_reply_add_aliasmem(&q_e, rdata);
563 /*******************************************************************
564 samr_reply_del_aliasmem
565 ********************************************************************/
566 static void samr_reply_del_aliasmem(SAMR_Q_DEL_ALIASMEM *q_u,
569 SAMR_R_DEL_ALIASMEM r_e;
572 fstring alias_sid_str;
576 /* find the policy handle. open a policy on it. */
577 if (r_e.status == 0x0 && !get_policy_samr_sid(&q_u->alias_pol, &alias_sid))
579 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
583 sid_to_string(alias_sid_str, &alias_sid);
584 sid_split_rid(&alias_sid, &alias_rid);
587 if (r_e.status == 0x0)
589 DEBUG(10,("sid is %s\n", alias_sid_str));
591 if (sid_equal(&alias_sid, &global_sam_sid))
593 DEBUG(10,("del member on Domain SID\n"));
596 r_e.status = del_alias_member(alias_rid, &q_u->sid.sid) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
599 else if (sid_equal(&alias_sid, &global_sid_S_1_5_20))
601 DEBUG(10,("del member on BUILTIN SID\n"));
604 r_e.status = del_builtin_member(alias_rid, &q_u->sid.sid) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
609 r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
613 /* store the response in the SMB stream */
614 samr_io_r_del_aliasmem("", &r_e, rdata, 0);
616 DEBUG(5,("samr_del_aliasmem: %d\n", __LINE__));
619 /*******************************************************************
620 api_samr_del_aliasmem
621 ********************************************************************/
622 static void api_samr_del_aliasmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
624 SAMR_Q_DEL_ALIASMEM q_e;
625 samr_io_q_del_aliasmem("", &q_e, data, 0);
626 samr_reply_del_aliasmem(&q_e, rdata);
629 /*******************************************************************
630 samr_reply_enum_domains
631 ********************************************************************/
632 static void samr_reply_enum_domains(SAMR_Q_ENUM_DOMAINS *q_u,
635 SAMR_R_ENUM_DOMAINS r_e;
637 uint32 num_entries = 0;
640 r_e.num_entries2 = 0;
646 /* find the connection policy handle. */
647 if (r_e.status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
649 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
652 DEBUG(5,("samr_reply_enum_domains:\n"));
654 if (!enumdomains(&doms, &num_entries))
656 r_e.status = 0xC0000000 | NT_STATUS_NO_MEMORY;
659 if (r_e.status == 0x0)
661 make_samr_r_enum_domains(&r_e,
662 q_u->start_idx + num_entries,
663 num_entries, doms, r_e.status);
666 /* store the response in the SMB stream */
667 samr_io_r_enum_domains("", &r_e, rdata, 0);
669 free_char_array(num_entries, doms);
676 if (r_e.uni_dom_name != NULL)
678 free(r_e.uni_dom_name);
681 DEBUG(5,("samr_enum_domains: %d\n", __LINE__));
684 /*******************************************************************
685 api_samr_enum_domains
686 ********************************************************************/
687 static void api_samr_enum_domains( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
689 SAMR_Q_ENUM_DOMAINS q_e;
691 /* grab the samr open */
692 samr_io_q_enum_domains("", &q_e, data, 0);
694 /* construct reply. */
695 samr_reply_enum_domains(&q_e, rdata);
698 /*******************************************************************
699 samr_reply_enum_dom_groups
700 ********************************************************************/
701 static void samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u,
704 SAMR_R_ENUM_DOM_GROUPS r_e;
705 DOMAIN_GRP *grps = NULL;
711 r_e.num_entries2 = 0;
713 /* find the policy handle. open a policy on it. */
714 if (r_e.status == 0x0 && !get_policy_samr_sid(&q_u->pol, &sid))
716 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
719 sid_to_string(sid_str, &sid);
721 DEBUG(5,("samr_reply_enum_dom_groups: sid %s\n", sid_str));
723 if (sid_equal(&sid, &global_sam_sid))
728 ret = enumdomgroups(&grps, &num_entries);
732 r_e.status = 0xC0000000 | NT_STATUS_NO_MEMORY;
736 if (r_e.status == 0x0)
738 make_samr_r_enum_dom_groups(&r_e,
739 q_u->start_idx + num_entries,
740 num_entries, grps, r_e.status);
743 /* store the response in the SMB stream */
744 samr_io_r_enum_dom_groups("", &r_e, rdata, 0);
756 if (r_e.uni_grp_name != NULL)
758 free(r_e.uni_grp_name);
761 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
764 /*******************************************************************
765 api_samr_enum_dom_groups
766 ********************************************************************/
767 static void api_samr_enum_dom_groups( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
769 SAMR_Q_ENUM_DOM_GROUPS q_e;
771 /* grab the samr open */
772 samr_io_q_enum_dom_groups("", &q_e, data, 0);
774 /* construct reply. */
775 samr_reply_enum_dom_groups(&q_e, rdata);
779 /*******************************************************************
780 samr_reply_enum_dom_aliases
781 ********************************************************************/
782 static void samr_reply_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_u,
785 SAMR_R_ENUM_DOM_ALIASES r_e;
786 LOCAL_GRP *alss = NULL;
792 r_e.num_entries2 = 0;
794 /* find the policy handle. open a policy on it. */
795 if (r_e.status == 0x0 && !get_policy_samr_sid(&q_u->pol, &sid))
797 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
800 sid_to_string(sid_str, &sid);
802 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
804 /* well-known aliases */
805 if (sid_equal(&sid, &global_sid_S_1_5_20))
808 /* builtin aliases */
811 ret = enumdombuiltins(&alss, &num_entries);
815 r_e.status = 0xC0000000 | NT_STATUS_NO_MEMORY;
818 else if (sid_equal(&sid, &global_sam_sid))
824 ret = enumdomaliases(&alss, &num_entries);
828 r_e.status = 0xC0000000 | NT_STATUS_NO_MEMORY;
832 if (r_e.status == 0x0)
834 make_samr_r_enum_dom_aliases(&r_e,
835 q_u->start_idx + num_entries,
836 num_entries, alss, r_e.status);
839 /* store the response in the SMB stream */
840 samr_io_r_enum_dom_aliases("", &r_e, rdata, 0);
852 if (r_e.uni_grp_name != NULL)
854 free(r_e.uni_grp_name);
857 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
861 /*******************************************************************
862 api_samr_enum_dom_aliases
863 ********************************************************************/
864 static void api_samr_enum_dom_aliases( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
866 SAMR_Q_ENUM_DOM_ALIASES q_e;
868 /* grab the samr open */
869 samr_io_q_enum_dom_aliases("", &q_e, data, 0);
871 /* construct reply. */
872 samr_reply_enum_dom_aliases(&q_e, rdata);
876 /*******************************************************************
877 samr_reply_query_dispinfo
878 ********************************************************************/
879 static void samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u,
882 SAMR_R_QUERY_DISPINFO r_e;
883 SAM_DISPINFO_CTR ctr;
884 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
885 DOMAIN_GRP *grps = NULL;
886 DOMAIN_GRP *sam_grps = NULL;
887 uint32 data_size = 0;
889 uint16 acb_mask = ACB_NORMAL;
890 int num_sam_entries = 0;
894 DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
896 /* find the policy handle. open a policy on it. */
897 if (find_policy_by_hnd(&(q_u->domain_pol)) == -1)
899 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
900 DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n"));
907 /* Get what we need from the password database */
908 switch (q_u->switch_level)
912 acb_mask = ACB_WSTRUST;
918 get_sampwd_entries(pass, q_u->start_idx,
919 &total_entries, &num_sam_entries,
920 MAX_SAM_ENTRIES, acb_mask);
926 enumdomgroups(&sam_grps, &num_sam_entries);
928 if (q_u->start_idx < num_sam_entries) {
929 grps = sam_grps + q_u->start_idx;
930 num_sam_entries -= q_u->start_idx;
940 num_entries = num_sam_entries;
942 if (num_entries > q_u->max_entries)
944 num_entries = q_u->max_entries;
947 if (num_entries > MAX_SAM_ENTRIES)
949 num_entries = MAX_SAM_ENTRIES;
950 DEBUG(5,("limiting number of entries to %d\n",
954 data_size = q_u->max_size;
956 /* Now create reply structure */
957 switch (q_u->switch_level)
961 ctr.sam.info1 = malloc(sizeof(SAM_DISPINFO_1));
962 make_sam_dispinfo_1(ctr.sam.info1,
963 &num_entries, &data_size,
964 q_u->start_idx, pass);
969 ctr.sam.info2 = malloc(sizeof(SAM_DISPINFO_2));
970 make_sam_dispinfo_2(ctr.sam.info2,
971 &num_entries, &data_size,
972 q_u->start_idx, pass);
977 ctr.sam.info3 = malloc(sizeof(SAM_DISPINFO_3));
978 make_sam_dispinfo_3(ctr.sam.info3,
979 &num_entries, &data_size,
980 q_u->start_idx, grps);
985 ctr.sam.info4 = malloc(sizeof(SAM_DISPINFO_4));
986 make_sam_dispinfo_4(ctr.sam.info4,
987 &num_entries, &data_size,
988 q_u->start_idx, pass);
993 ctr.sam.info5 = malloc(sizeof(SAM_DISPINFO_5));
994 make_sam_dispinfo_5(ctr.sam.info5,
995 &num_entries, &data_size,
996 q_u->start_idx, grps);
1001 ctr.sam.info = NULL;
1002 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
1008 if ((status == 0) && (num_entries < num_sam_entries))
1010 status = STATUS_MORE_ENTRIES;
1013 make_samr_r_query_dispinfo(&r_e, num_entries, data_size,
1014 q_u->switch_level, &ctr, status);
1016 /* store the response in the SMB stream */
1017 samr_io_r_query_dispinfo("", &r_e, rdata, 0);
1019 /* free malloc'd areas */
1020 if (sam_grps != NULL)
1025 if (ctr.sam.info != NULL)
1030 DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
1033 /*******************************************************************
1034 api_samr_query_dispinfo
1035 ********************************************************************/
1036 static void api_samr_query_dispinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
1038 SAMR_Q_QUERY_DISPINFO q_e;
1040 samr_io_q_query_dispinfo("", &q_e, data, 0);
1041 samr_reply_query_dispinfo(&q_e, rdata);
1044 /*******************************************************************
1045 samr_reply_delete_dom_group
1046 ********************************************************************/
1047 static void samr_reply_delete_dom_group(SAMR_Q_DELETE_DOM_GROUP *q_u,
1054 fstring group_sid_str;
1056 SAMR_R_DELETE_DOM_GROUP r_u;
1058 DEBUG(5,("samr_delete_dom_group: %d\n", __LINE__));
1060 /* find the policy handle. open a policy on it. */
1061 if (status == 0x0 && !get_policy_samr_sid(&q_u->group_pol, &group_sid))
1063 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1067 sid_to_string(group_sid_str, &group_sid );
1068 sid_split_rid(&group_sid, &group_rid);
1073 DEBUG(10,("sid is %s\n", group_sid_str));
1075 if (sid_equal(&group_sid, &global_sam_sid))
1077 DEBUG(10,("lookup on Domain SID\n"));
1080 status = del_group_entry(group_rid) ? 0x0 : (0xC0000000 | NT_STATUS_NO_SUCH_GROUP);
1081 unbecome_root(True);
1085 status = 0xC0000000 | NT_STATUS_NO_SUCH_GROUP;
1089 make_samr_r_delete_dom_group(&r_u, status);
1091 /* store the response in the SMB stream */
1092 samr_io_r_delete_dom_group("", &r_u, rdata, 0);
1095 /*******************************************************************
1096 api_samr_delete_dom_group
1097 ********************************************************************/
1098 static void api_samr_delete_dom_group( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
1100 SAMR_Q_DELETE_DOM_GROUP q_u;
1101 samr_io_q_delete_dom_group("", &q_u, data, 0);
1102 samr_reply_delete_dom_group(&q_u, rdata);
1106 /*******************************************************************
1107 samr_reply_query_groupmem
1108 ********************************************************************/
1109 static void samr_reply_query_groupmem(SAMR_Q_QUERY_GROUPMEM *q_u,
1114 DOMAIN_GRP_MEMBER *mem_grp = NULL;
1116 uint32 *attr = NULL;
1120 fstring group_sid_str;
1122 SAMR_R_QUERY_GROUPMEM r_u;
1124 DEBUG(5,("samr_query_groupmem: %d\n", __LINE__));
1126 /* find the policy handle. open a policy on it. */
1127 if (status == 0x0 && !get_policy_samr_sid(&q_u->group_pol, &group_sid))
1129 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1133 sid_to_string(group_sid_str, &group_sid );
1134 sid_split_rid(&group_sid, &group_rid);
1139 DEBUG(10,("sid is %s\n", group_sid_str));
1141 if (sid_equal(&group_sid, &global_sam_sid))
1143 DEBUG(10,("lookup on Domain SID\n"));
1146 status = getgrouprid(group_rid, &mem_grp, &num_rids) != NULL ? 0x0 : (0xC0000000 | NT_STATUS_NO_SUCH_GROUP);
1147 unbecome_root(True);
1151 status = 0xC0000000 | NT_STATUS_NO_SUCH_GROUP;
1155 if (status == 0x0 && num_rids > 0)
1157 rid = malloc(num_rids * sizeof(uint32));
1158 attr = malloc(num_rids * sizeof(uint32));
1159 if (mem_grp != NULL && rid != NULL && attr != NULL)
1162 for (i = 0; i < num_rids; i++)
1164 rid [i] = mem_grp[i].rid;
1165 attr[i] = mem_grp[i].attr;
1171 make_samr_r_query_groupmem(&r_u, num_rids, rid, attr, status);
1173 /* store the response in the SMB stream */
1174 samr_io_r_query_groupmem("", &r_u, rdata, 0);
1186 DEBUG(5,("samr_query_groupmem: %d\n", __LINE__));
1190 /*******************************************************************
1191 api_samr_query_groupmem
1192 ********************************************************************/
1193 static void api_samr_query_groupmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
1195 SAMR_Q_QUERY_GROUPMEM q_u;
1196 samr_io_q_query_groupmem("", &q_u, data, 0);
1197 samr_reply_query_groupmem(&q_u, rdata);
1201 /*******************************************************************
1202 samr_reply_query_groupinfo
1203 ********************************************************************/
1204 static void samr_reply_query_groupinfo(SAMR_Q_QUERY_GROUPINFO *q_u,
1207 SAMR_R_QUERY_GROUPINFO r_e;
1209 uint32 status = 0x0;
1213 /* find the policy handle. open a policy on it. */
1214 if (r_e.status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
1216 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1219 DEBUG(5,("samr_reply_query_groupinfo: %d\n", __LINE__));
1223 if (q_u->switch_level == 1)
1226 ctr.switch_value1 = 1;
1227 make_samr_group_info1(&ctr.group.info1,
1228 "fake account name",
1229 "fake account description", 2);
1231 else if (q_u->switch_level == 4)
1234 ctr.switch_value1 = 4;
1235 make_samr_group_info4(&ctr.group.info4,
1236 "fake account description");
1240 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
1244 make_samr_r_query_groupinfo(&r_e, status == 0 ? &ctr : NULL, status);
1246 /* store the response in the SMB stream */
1247 samr_io_r_query_groupinfo("", &r_e, rdata, 0);
1249 DEBUG(5,("samr_query_groupinfo: %d\n", __LINE__));
1253 /*******************************************************************
1254 api_samr_query_groupinfo
1255 ********************************************************************/
1256 static void api_samr_query_groupinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
1258 SAMR_Q_QUERY_GROUPINFO q_e;
1259 samr_io_q_query_groupinfo("", &q_e, data, 0);
1260 samr_reply_query_groupinfo(&q_e, rdata);
1264 /*******************************************************************
1265 samr_reply_query_aliasinfo
1266 ********************************************************************/
1267 static void samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
1270 SAMR_R_QUERY_ALIASINFO r_e;
1272 uint32 status = 0x0;
1276 /* find the policy handle. open a policy on it. */
1277 if (r_e.status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
1279 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1282 DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__));
1286 if (q_u->switch_level == 3)
1289 ctr.switch_value1 = 3;
1290 make_samr_alias_info3(&ctr.alias.info3, "<fake account description>");
1294 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
1298 make_samr_r_query_aliasinfo(&r_e, status == 0 ? &ctr : NULL, status);
1300 /* store the response in the SMB stream */
1301 samr_io_r_query_aliasinfo("", &r_e, rdata, 0);
1303 DEBUG(5,("samr_query_aliasinfo: %d\n", __LINE__));
1307 /*******************************************************************
1308 api_samr_query_aliasinfo
1309 ********************************************************************/
1310 static void api_samr_query_aliasinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
1312 SAMR_Q_QUERY_ALIASINFO q_e;
1313 samr_io_q_query_aliasinfo("", &q_e, data, 0);
1314 samr_reply_query_aliasinfo(&q_e, rdata);
1318 /*******************************************************************
1319 samr_reply_query_useraliases
1320 ********************************************************************/
1321 static void samr_reply_query_useraliases(SAMR_Q_QUERY_USERALIASES *q_u,
1326 LOCAL_GRP *mem_grp = NULL;
1329 struct sam_passwd *sam_pass;
1333 fstring sam_sid_str;
1334 fstring dom_sid_str;
1335 fstring usr_sid_str;
1337 SAMR_R_QUERY_USERALIASES r_u;
1340 DEBUG(5,("samr_query_useraliases: %d\n", __LINE__));
1342 /* find the policy handle. open a policy on it. */
1343 if (status == 0x0 && !get_policy_samr_sid(&q_u->pol, &dom_sid))
1345 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1349 sid_to_string(dom_sid_str, &dom_sid );
1350 sid_to_string(sam_sid_str, &global_sam_sid);
1355 usr_sid = q_u->sid[0].sid;
1356 sid_split_rid(&usr_sid, &user_rid);
1357 sid_to_string(usr_sid_str, &usr_sid);
1363 /* find the user account */
1365 sam_pass = getsam21pwrid(user_rid);
1366 unbecome_root(True);
1368 if (sam_pass == NULL)
1370 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1377 DEBUG(10,("sid is %s\n", dom_sid_str));
1379 if (sid_equal(&dom_sid, &global_sid_S_1_5_20))
1381 DEBUG(10,("lookup on S-1-5-20\n"));
1384 getuserbuiltinntnam(sam_pass->nt_name, &mem_grp, &num_rids);
1385 unbecome_root(True);
1387 else if (sid_equal(&dom_sid, &usr_sid))
1389 DEBUG(10,("lookup on Domain SID\n"));
1392 getuseraliasntnam(sam_pass->nt_name, &mem_grp, &num_rids);
1393 unbecome_root(True);
1397 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1401 if (status == 0x0 && num_rids > 0)
1403 rid = malloc(num_rids * sizeof(uint32));
1404 if (mem_grp != NULL && rid != NULL)
1407 for (i = 0; i < num_rids; i++)
1409 rid[i] = mem_grp[i].rid;
1415 make_samr_r_query_useraliases(&r_u, num_rids, rid, status);
1417 /* store the response in the SMB stream */
1418 samr_io_r_query_useraliases("", &r_u, rdata, 0);
1425 DEBUG(5,("samr_query_useraliases: %d\n", __LINE__));
1429 /*******************************************************************
1430 api_samr_query_useraliases
1431 ********************************************************************/
1432 static void api_samr_query_useraliases( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
1434 SAMR_Q_QUERY_USERALIASES q_u;
1436 samr_io_q_query_useraliases("", &q_u, data, 0);
1437 samr_reply_query_useraliases(&q_u, rdata);
1438 samr_free_q_query_useraliases(&q_u);
1441 /*******************************************************************
1442 samr_reply_delete_dom_alias
1443 ********************************************************************/
1444 static void samr_reply_delete_dom_alias(SAMR_Q_DELETE_DOM_ALIAS *q_u,
1451 fstring alias_sid_str;
1453 SAMR_R_DELETE_DOM_ALIAS r_u;
1455 DEBUG(5,("samr_delete_dom_alias: %d\n", __LINE__));
1457 /* find the policy handle. open a policy on it. */
1458 if (status == 0x0 && !get_policy_samr_sid(&q_u->alias_pol, &alias_sid))
1460 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1464 sid_to_string(alias_sid_str, &alias_sid );
1465 sid_split_rid(&alias_sid, &alias_rid);
1470 DEBUG(10,("sid is %s\n", alias_sid_str));
1472 if (sid_equal(&alias_sid, &global_sam_sid))
1474 DEBUG(10,("lookup on Domain SID\n"));
1477 status = del_alias_entry(alias_rid) ? 0x0 : (0xC0000000 | NT_STATUS_NO_SUCH_ALIAS);
1478 unbecome_root(True);
1482 status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
1486 make_samr_r_delete_dom_alias(&r_u, status);
1488 /* store the response in the SMB stream */
1489 samr_io_r_delete_dom_alias("", &r_u, rdata, 0);
1492 /*******************************************************************
1493 api_samr_delete_dom_alias
1494 ********************************************************************/
1495 static void api_samr_delete_dom_alias( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
1497 SAMR_Q_DELETE_DOM_ALIAS q_u;
1498 samr_io_q_delete_dom_alias("", &q_u, data, 0);
1499 samr_reply_delete_dom_alias(&q_u, rdata);
1503 /*******************************************************************
1504 samr_reply_query_aliasmem
1505 ********************************************************************/
1506 static void samr_reply_query_aliasmem(SAMR_Q_QUERY_ALIASMEM *q_u,
1511 LOCAL_GRP_MEMBER *mem_grp = NULL;
1512 DOM_SID2 *sid = NULL;
1516 fstring alias_sid_str;
1518 SAMR_R_QUERY_ALIASMEM r_u;
1520 DEBUG(5,("samr_query_aliasmem: %d\n", __LINE__));
1522 /* find the policy handle. open a policy on it. */
1523 if (status == 0x0 && !get_policy_samr_sid(&q_u->alias_pol, &alias_sid))
1525 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1529 sid_to_string(alias_sid_str, &alias_sid );
1530 sid_split_rid(&alias_sid, &alias_rid);
1535 DEBUG(10,("sid is %s\n", alias_sid_str));
1537 if (sid_equal(&alias_sid, &global_sid_S_1_5_20))
1539 DEBUG(10,("lookup on S-1-5-20\n"));
1542 status = getbuiltinrid(alias_rid, &mem_grp, &num_sids) != NULL ? 0x0 : 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
1543 unbecome_root(True);
1545 else if (sid_equal(&alias_sid, &global_sam_sid))
1547 DEBUG(10,("lookup on Domain SID\n"));
1550 status = getaliasrid(alias_rid, &mem_grp, &num_sids) != NULL ? 0x0 : 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
1551 unbecome_root(True);
1555 status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
1559 if (status == 0x0 && num_sids > 0)
1561 sid = malloc(num_sids * sizeof(DOM_SID));
1562 if (mem_grp != NULL && sid != NULL)
1565 for (i = 0; i < num_sids; i++)
1567 make_dom_sid2(&sid[i], &mem_grp[i].sid);
1573 make_samr_r_query_aliasmem(&r_u, num_sids, sid, status);
1575 /* store the response in the SMB stream */
1576 samr_io_r_query_aliasmem("", &r_u, rdata, 0);
1583 DEBUG(5,("samr_query_aliasmem: %d\n", __LINE__));
1587 /*******************************************************************
1588 api_samr_query_aliasmem
1589 ********************************************************************/
1590 static void api_samr_query_aliasmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
1592 SAMR_Q_QUERY_ALIASMEM q_u;
1593 samr_io_q_query_aliasmem("", &q_u, data, 0);
1594 samr_reply_query_aliasmem(&q_u, rdata);
1597 /*******************************************************************
1598 samr_reply_lookup_names
1599 ********************************************************************/
1600 static void samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
1603 uint32 rid [MAX_SAM_ENTRIES];
1604 uint8 type[MAX_SAM_ENTRIES];
1607 int num_rids = q_u->num_names1;
1610 SAMR_R_LOOKUP_NAMES r_u;
1612 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1614 if (status == 0x0 && !get_policy_samr_sid(&q_u->pol, &pol_sid))
1616 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
1619 if (num_rids > MAX_SAM_ENTRIES)
1621 num_rids = MAX_SAM_ENTRIES;
1622 DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
1625 SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
1627 for (i = 0; i < num_rids && status == 0; i++)
1631 unistr2_to_ascii(name, &q_u->uni_name[i], sizeof(name)-1);
1633 status = lookup_name(name, &sid, &(type[i]));
1636 sid_split_rid(&sid, &rid[i]);
1640 type[i] = SID_NAME_UNKNOWN;
1641 rid [i] = 0xffffffff;
1643 if (!sid_equal(&pol_sid, &sid))
1645 rid [i] = 0xffffffff;
1646 type[i] = SID_NAME_UNKNOWN;
1650 make_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
1652 /* store the response in the SMB stream */
1653 samr_io_r_lookup_names("", &r_u, rdata, 0);
1655 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
1659 /*******************************************************************
1660 api_samr_lookup_names
1661 ********************************************************************/
1662 static void api_samr_lookup_names( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
1664 SAMR_Q_LOOKUP_NAMES q_u;
1665 samr_io_q_lookup_names("", &q_u, data, 0);
1666 samr_reply_lookup_names(&q_u, rdata);
1669 /*******************************************************************
1670 samr_reply_chgpasswd_user
1671 ********************************************************************/
1672 static void samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
1675 SAMR_R_CHGPASSWD_USER r_u;
1676 uint32 status = 0x0;
1680 unistr2_to_ascii(user_name, &q_u->uni_user_name, sizeof(user_name)-1);
1681 unistr2_to_ascii(wks, &q_u->uni_dest_host, sizeof(wks)-1);
1683 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1685 if (!pass_oem_change(user_name,
1686 q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1687 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1689 status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
1692 make_samr_r_chgpasswd_user(&r_u, status);
1694 /* store the response in the SMB stream */
1695 samr_io_r_chgpasswd_user("", &r_u, rdata, 0);
1697 DEBUG(5,("samr_chgpasswd_user: %d\n", __LINE__));
1700 /*******************************************************************
1701 api_samr_chgpasswd_user
1702 ********************************************************************/
1703 static void api_samr_chgpasswd_user( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
1705 SAMR_Q_CHGPASSWD_USER q_u;
1706 samr_io_q_chgpasswd_user("", &q_u, data, 0);
1707 samr_reply_chgpasswd_user(&q_u, rdata);
1711 /*******************************************************************
1712 samr_reply_unknown_38
1713 ********************************************************************/
1714 static void samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u,
1717 SAMR_R_UNKNOWN_38 r_u;
1719 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1721 make_samr_r_unknown_38(&r_u);
1723 /* store the response in the SMB stream */
1724 samr_io_r_unknown_38("", &r_u, rdata, 0);
1726 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
1729 /*******************************************************************
1731 ********************************************************************/
1732 static void api_samr_unknown_38( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
1734 SAMR_Q_UNKNOWN_38 q_u;
1735 samr_io_q_unknown_38("", &q_u, data, 0);
1736 samr_reply_unknown_38(&q_u, rdata);
1740 /*******************************************************************
1741 samr_reply_lookup_rids
1742 ********************************************************************/
1743 static void samr_reply_lookup_rids(SAMR_Q_LOOKUP_RIDS *q_u,
1746 fstring group_names[MAX_SAM_ENTRIES];
1747 uint8 group_attrs[MAX_SAM_ENTRIES];
1749 int num_rids = q_u->num_rids1;
1752 SAMR_R_LOOKUP_RIDS r_u;
1755 DEBUG(5,("samr_lookup_rids: %d\n", __LINE__));
1757 /* find the policy handle. open a policy on it. */
1758 if (status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
1760 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1763 if (status == 0x0 && !get_policy_samr_sid(&q_u->pol, &pol_sid))
1765 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
1771 if (num_rids > MAX_SAM_ENTRIES)
1773 num_rids = MAX_SAM_ENTRIES;
1774 DEBUG(5,("samr_lookup_rids: truncating entries to %d\n", num_rids));
1777 for (i = 0; i < num_rids && status == 0; i++)
1780 sid_copy(&sid, &pol_sid);
1781 sid_append_rid(&sid, q_u->rid[i]);
1782 lookup_sid(&sid, group_names[i], &group_attrs[i]);
1786 make_samr_r_lookup_rids(&r_u, num_rids, group_names, group_attrs, status);
1788 /* store the response in the SMB stream */
1789 samr_io_r_lookup_rids("", &r_u, rdata, 0);
1791 DEBUG(5,("samr_lookup_rids: %d\n", __LINE__));
1795 /*******************************************************************
1796 api_samr_lookup_rids
1797 ********************************************************************/
1798 static void api_samr_lookup_rids( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
1800 SAMR_Q_LOOKUP_RIDS q_u;
1802 samr_io_q_lookup_rids("", &q_u, data, 0);
1803 samr_reply_lookup_rids(&q_u, rdata);
1804 samr_free_q_lookup_rids(&q_u);
1808 /*******************************************************************
1809 samr_reply_open_user
1810 ********************************************************************/
1811 static void samr_reply_open_user(SAMR_Q_OPEN_USER *q_u,
1815 SAMR_R_OPEN_USER r_u;
1816 struct sam_passwd *sam_pass;
1817 BOOL pol_open = False;
1819 /* set up the SAMR open_user response */
1820 bzero(r_u.user_pol.data, POL_HND_SIZE);
1824 /* find the policy handle. open a policy on it. */
1825 if (r_u.status == 0x0 && (find_policy_by_hnd(&(q_u->domain_pol)) == -1))
1827 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1830 /* get a (unique) handle. open a policy on it. */
1831 if (r_u.status == 0x0 && !(pol_open = open_policy_hnd(&(r_u.user_pol))))
1833 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1837 sam_pass = getsam21pwrid(q_u->user_rid);
1838 unbecome_root(True);
1840 /* check that the RID exists in our domain. */
1841 if (r_u.status == 0x0 && sam_pass == NULL)
1843 r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1846 /* associate the RID with the (unique) handle. */
1847 if (r_u.status == 0x0 && !set_policy_samr_rid(&(r_u.user_pol), q_u->user_rid))
1849 /* oh, whoops. don't know what error message to return, here */
1850 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1853 if (r_u.status != 0 && pol_open)
1855 close_policy_hnd(&(r_u.user_pol));
1858 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1860 /* store the response in the SMB stream */
1861 samr_io_r_open_user("", &r_u, rdata, 0);
1863 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1867 /*******************************************************************
1869 ********************************************************************/
1870 static void api_samr_open_user( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
1872 SAMR_Q_OPEN_USER q_u;
1873 samr_io_q_open_user("", &q_u, data, 0);
1874 samr_reply_open_user(&q_u, rdata, 0x0);
1878 /*************************************************************************
1880 *************************************************************************/
1881 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1883 struct sam_passwd *sam_pass;
1886 sam_pass = getsam21pwrid(user_rid);
1887 unbecome_root(True);
1889 if (sam_pass == NULL)
1891 DEBUG(4,("User 0x%x not found\n", user_rid));
1895 DEBUG(3,("User:[%s]\n", sam_pass->nt_name));
1897 make_sam_user_info10(id10, sam_pass->acct_ctrl);
1902 /*************************************************************************
1904 *************************************************************************/
1905 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1907 struct sam_passwd *sam_pass;
1912 sam_pass = getsam21pwrid(user_rid);
1913 unbecome_root(True);
1915 if (sam_pass == NULL)
1917 DEBUG(4,("User 0x%x not found\n", user_rid));
1921 DEBUG(3,("User:[%s]\n", sam_pass->nt_name));
1923 /* create a LOGON_HRS structure */
1924 hrs.len = sam_pass->hours_len;
1925 SMB_ASSERT_ARRAY(hrs.hours, hrs.len);
1926 for (i = 0; i < hrs.len; i++)
1928 hrs.hours[i] = sam_pass->hours[i];
1931 make_sam_user_info21(id21,
1933 &sam_pass->logon_time,
1934 &sam_pass->logoff_time,
1935 &sam_pass->kickoff_time,
1936 &sam_pass->pass_last_set_time,
1937 &sam_pass->pass_can_change_time,
1938 &sam_pass->pass_must_change_time,
1940 sam_pass->nt_name, /* user_name */
1941 sam_pass->full_name, /* full_name */
1942 sam_pass->home_dir, /* home_dir */
1943 sam_pass->dir_drive, /* dir_drive */
1944 sam_pass->logon_script, /* logon_script */
1945 sam_pass->profile_path, /* profile_path */
1946 sam_pass->acct_desc, /* description */
1947 sam_pass->workstations, /* workstations user can log in from */
1948 sam_pass->unknown_str, /* don't know, yet */
1949 sam_pass->munged_dial, /* dialin info. contains dialin path and tel no */
1951 sam_pass->user_rid, /* RID user_id */
1952 sam_pass->group_rid, /* RID group_id */
1953 sam_pass->acct_ctrl,
1955 sam_pass->unknown_3, /* unknown_3 */
1956 sam_pass->logon_divs, /* divisions per week */
1957 &hrs, /* logon hours */
1958 sam_pass->unknown_5,
1959 sam_pass->unknown_6);
1964 /*******************************************************************
1965 samr_reply_query_userinfo
1966 ********************************************************************/
1967 static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
1970 SAMR_R_QUERY_USERINFO r_u;
1972 SAM_USER_INFO_11 id11;
1974 SAM_USER_INFO_10 id10;
1975 SAM_USER_INFO_21 id21;
1978 uint32 status = 0x0;
1981 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1983 /* search for the handle */
1984 if (status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
1986 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1989 /* find the user's rid */
1990 if (status == 0x0 && (rid = get_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1992 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
1995 DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
1997 /* ok! user info levels (there are lots: see MSDEV help), off we go... */
2000 switch (q_u->switch_value)
2004 info = (void*)&id10;
2005 status = get_user_info_10(&id10, rid) ? 0 : (0xC0000000 | NT_STATUS_NO_SUCH_USER);
2009 /* whoops - got this wrong. i think. or don't understand what's happening. */
2013 info = (void*)&id11;
2015 expire.low = 0xffffffff;
2016 expire.high = 0x7fffffff;
2018 make_sam_user_info11(&id11, &expire, "BROOKFIELDS$", 0x03ef, 0x201, 0x0080);
2025 info = (void*)&id21;
2026 status = get_user_info_21(&id21, rid) ? 0 : (0xC0000000 | NT_STATUS_NO_SUCH_USER);
2032 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
2039 make_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
2041 /* store the response in the SMB stream */
2042 samr_io_r_query_userinfo("", &r_u, rdata, 0);
2044 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
2048 /*******************************************************************
2050 ********************************************************************/
2051 static BOOL set_user_info_24(SAM_USER_INFO_24 *id24, uint32 rid)
2053 struct sam_passwd *pwd = getsam21pwrid(rid);
2054 struct sam_passwd new_pwd;
2055 static uchar nt_hash[16];
2056 static uchar lm_hash[16];
2065 pwdb_init_sam(&new_pwd);
2066 copy_sam_passwd(&new_pwd, pwd);
2068 if (!decode_pw_buffer(id24->pass, (char *)new_pw.buffer, 256, &len))
2073 new_pw.uni_max_len = len / 2;
2074 new_pw.uni_str_len = len / 2;
2076 nt_lm_owf_genW(&new_pw, nt_hash, lm_hash);
2078 new_pwd.smb_passwd = lm_hash;
2079 new_pwd.smb_nt_passwd = nt_hash;
2081 return mod_sam21pwd_entry(&new_pwd, True);
2084 /*******************************************************************
2086 ********************************************************************/
2087 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
2089 struct sam_passwd *pwd = getsam21pwrid(rid);
2090 struct sam_passwd new_pwd;
2091 static uchar nt_hash[16];
2092 static uchar lm_hash[16];
2098 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2106 pwdb_init_sam(&new_pwd);
2107 copy_sam_passwd(&new_pwd, pwd);
2108 copy_id23_to_sam_passwd(&new_pwd, id23);
2110 if (!decode_pw_buffer(id23->pass, (char*)new_pw.buffer, 256, &len))
2115 new_pw.uni_max_len = len / 2;
2116 new_pw.uni_str_len = len / 2;
2118 nt_lm_owf_genW(&new_pw, nt_hash, lm_hash);
2120 new_pwd.smb_passwd = lm_hash;
2121 new_pwd.smb_nt_passwd = nt_hash;
2123 return mod_sam21pwd_entry(&new_pwd, True);
2126 /*******************************************************************
2128 ********************************************************************/
2129 static BOOL set_user_info_16(SAM_USER_INFO_16 *id16, uint32 rid)
2131 struct sam_passwd *pwd = getsam21pwrid(rid);
2132 struct sam_passwd new_pwd;
2136 DEBUG(5, ("set_user_info_16: NULL id16\n"));
2144 copy_sam_passwd(&new_pwd, pwd);
2146 new_pwd.acct_ctrl = id16->acb_info;
2148 return mod_sam21pwd_entry(&new_pwd, True);
2151 /*******************************************************************
2152 api_samr_query_userinfo
2153 ********************************************************************/
2154 static void api_samr_query_userinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
2156 SAMR_Q_QUERY_USERINFO q_u;
2157 samr_io_q_query_userinfo("", &q_u, data, 0);
2158 samr_reply_query_userinfo(&q_u, rdata);
2162 /*******************************************************************
2163 samr_reply_set_userinfo2
2164 ********************************************************************/
2165 static void samr_reply_set_userinfo2(SAMR_Q_SET_USERINFO2 *q_u,
2166 prs_struct *rdata, uchar user_sess_key[16])
2168 SAMR_R_SET_USERINFO2 r_u;
2170 uint32 status = 0x0;
2173 DEBUG(5,("samr_reply_set_userinfo2: %d\n", __LINE__));
2175 /* search for the handle */
2176 if (status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
2178 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
2181 /* find the user's rid */
2182 if (status == 0x0 && (rid = get_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
2184 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
2187 DEBUG(5,("samr_reply_set_userinfo2: rid:0x%x\n", rid));
2189 /* ok! user info levels (there are lots: see MSDEV help), off we go... */
2190 if (status == 0x0 && q_u->info.id == NULL)
2192 DEBUG(5,("samr_reply_set_userinfo2: NULL info level\n"));
2193 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
2198 switch (q_u->switch_value)
2202 SAM_USER_INFO_16 *id16 = q_u->info.id16;
2203 status = set_user_info_16(id16, rid) ? 0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
2208 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
2215 make_samr_r_set_userinfo2(&r_u, status);
2217 /* store the response in the SMB stream */
2218 samr_io_r_set_userinfo2("", &r_u, rdata, 0);
2220 DEBUG(5,("samr_reply_set_userinfo2: %d\n", __LINE__));
2224 /*******************************************************************
2225 api_samr_set_userinfo2
2226 ********************************************************************/
2227 static void api_samr_set_userinfo2( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
2229 SAMR_Q_SET_USERINFO2 q_u;
2232 samr_io_q_set_userinfo2("", &q_u, data, 0);
2233 samr_reply_set_userinfo2(&q_u, rdata, p->user_sess_key);
2235 if (q_u.info.id != NULL)
2242 /*******************************************************************
2243 samr_reply_set_userinfo
2244 ********************************************************************/
2245 static void samr_reply_set_userinfo(SAMR_Q_SET_USERINFO *q_u,
2246 prs_struct *rdata, uchar user_sess_key[16])
2248 SAMR_R_SET_USERINFO r_u;
2250 uint32 status = 0x0;
2253 DEBUG(5,("samr_reply_set_userinfo: %d\n", __LINE__));
2255 /* search for the handle */
2256 if (status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
2258 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
2261 /* find the user's rid */
2262 if (status == 0x0 && (rid = get_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
2264 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
2267 DEBUG(5,("samr_reply_set_userinfo: rid:0x%x\n", rid));
2269 /* ok! user info levels (there are lots: see MSDEV help), off we go... */
2270 if (status == 0x0 && q_u->info.id == NULL)
2272 DEBUG(5,("samr_reply_set_userinfo: NULL info level\n"));
2273 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
2278 switch (q_u->switch_value)
2282 SAM_USER_INFO_24 *id24 = q_u->info.id24;
2283 SamOEMhash(id24->pass, user_sess_key, True);
2284 status = set_user_info_24(id24, rid) ? 0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
2290 SAM_USER_INFO_23 *id23 = q_u->info.id23;
2291 SamOEMhash(id23->pass, user_sess_key, 1);
2293 DEBUG(100,("pass buff:\n"));
2294 dump_data(100, id23->pass, sizeof(id23->pass));
2298 status = set_user_info_23(id23, rid) ? 0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
2304 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
2311 make_samr_r_set_userinfo(&r_u, status);
2313 /* store the response in the SMB stream */
2314 samr_io_r_set_userinfo("", &r_u, rdata, 0);
2316 DEBUG(5,("samr_reply_set_userinfo: %d\n", __LINE__));
2320 /*******************************************************************
2321 api_samr_set_userinfo
2322 ********************************************************************/
2323 static void api_samr_set_userinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
2325 SAMR_Q_SET_USERINFO q_u;
2328 #ifdef DEBUG_PASSWORD
2329 DEBUG(100,("set user info: sess_key: "));
2330 dump_data(100, p->user_sess_key, 16);
2332 samr_io_q_set_userinfo("", &q_u, data, 0);
2333 samr_reply_set_userinfo(&q_u, rdata, p->user_sess_key);
2335 if (q_u.info.id != NULL)
2342 /*******************************************************************
2343 samr_reply_query_usergroups
2344 ********************************************************************/
2345 static void samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
2348 SAMR_R_QUERY_USERGROUPS r_u;
2349 uint32 status = 0x0;
2351 struct sam_passwd *sam_pass;
2352 DOM_GID *gids = NULL;
2356 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
2358 /* find the policy handle. open a policy on it. */
2359 if (status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
2361 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
2364 /* find the user's rid */
2365 if (status == 0x0 && (rid = get_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
2367 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
2373 sam_pass = getsam21pwrid(rid);
2374 unbecome_root(True);
2376 if (sam_pass == NULL)
2378 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
2384 DOMAIN_GRP *mem_grp = NULL;
2387 getusergroupsntnam(sam_pass->nt_name, &mem_grp, &num_groups);
2388 unbecome_root(True);
2391 num_groups = make_dom_gids(mem_grp, num_groups, &gids);
2393 if (mem_grp != NULL)
2399 /* construct the response. lkclXXXX: gids are not copied! */
2400 make_samr_r_query_usergroups(&r_u, num_groups, gids, status);
2402 /* store the response in the SMB stream */
2403 samr_io_r_query_usergroups("", &r_u, rdata, 0);
2410 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
2414 /*******************************************************************
2415 api_samr_query_usergroups
2416 ********************************************************************/
2417 static void api_samr_query_usergroups( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
2419 SAMR_Q_QUERY_USERGROUPS q_u;
2420 samr_io_q_query_usergroups("", &q_u, data, 0);
2421 samr_reply_query_usergroups(&q_u, rdata);
2425 /*******************************************************************
2426 opens a samr alias by rid, returns a policy handle.
2427 ********************************************************************/
2428 static uint32 open_samr_alias(DOM_SID *sid, POLICY_HND *alias_pol,
2431 BOOL pol_open = False;
2432 uint32 status = 0x0;
2434 /* get a (unique) handle. open a policy on it. */
2435 if (status == 0x0 && !(pol_open = open_policy_hnd(alias_pol)))
2437 status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2440 DEBUG(0,("TODO: verify that the alias rid exists\n"));
2442 /* associate a RID with the (unique) handle. */
2443 if (status == 0x0 && !set_policy_samr_rid(alias_pol, alias_rid))
2445 /* oh, whoops. don't know what error message to return, here */
2446 status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2449 sid_append_rid(sid, alias_rid);
2451 /* associate an alias SID with the (unique) handle. */
2452 if (status == 0x0 && !set_policy_samr_sid(alias_pol, sid))
2454 /* oh, whoops. don't know what error message to return, here */
2455 status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2458 if (status != 0 && pol_open)
2460 close_policy_hnd(alias_pol);
2466 /*******************************************************************
2467 samr_reply_create_dom_alias
2468 ********************************************************************/
2469 static void samr_reply_create_dom_alias(SAMR_Q_CREATE_DOM_ALIAS *q_u,
2472 SAMR_R_CREATE_DOM_ALIAS r_u;
2475 POLICY_HND alias_pol;
2476 uint32 status = 0x0;
2478 bzero(&alias_pol, sizeof(alias_pol));
2480 DEBUG(5,("samr_create_dom_alias: %d\n", __LINE__));
2482 /* find the policy handle. open a policy on it. */
2483 if (status == 0x0 && (find_policy_by_hnd(&(q_u->dom_pol)) == -1))
2485 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
2488 /* find the domain sid */
2489 if (status == 0x0 && !get_policy_samr_sid(&q_u->dom_pol, &dom_sid))
2491 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
2494 if (!sid_equal(&dom_sid, &global_sam_sid))
2496 status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
2501 unistr2_to_ascii(grp.name, &q_u->uni_acct_desc, sizeof(grp.name)-1);
2502 fstrcpy(grp.comment, "");
2503 grp.rid = 0xffffffff;
2506 status = add_alias_entry(&grp) ? 0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
2507 unbecome_root(True);
2512 status = open_samr_alias(&dom_sid, &alias_pol, grp.rid);
2515 /* construct the response. */
2516 make_samr_r_create_dom_alias(&r_u, &alias_pol, grp.rid, status);
2518 /* store the response in the SMB stream */
2519 samr_io_r_create_dom_alias("", &r_u, rdata, 0);
2521 DEBUG(5,("samr_create_dom_alias: %d\n", __LINE__));
2525 /*******************************************************************
2526 api_samr_create_dom_alias
2527 ********************************************************************/
2528 static void api_samr_create_dom_alias( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
2530 SAMR_Q_CREATE_DOM_ALIAS q_u;
2531 samr_io_q_create_dom_alias("", &q_u, data, 0);
2532 samr_reply_create_dom_alias(&q_u, rdata);
2536 /*******************************************************************
2537 opens a samr group by rid, returns a policy handle.
2538 ********************************************************************/
2539 static uint32 open_samr_group(DOM_SID *sid, POLICY_HND *group_pol,
2542 BOOL pol_open = False;
2543 uint32 status = 0x0;
2545 /* get a (unique) handle. open a policy on it. */
2546 if (status == 0x0 && !(pol_open = open_policy_hnd(group_pol)))
2548 status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2551 DEBUG(0,("TODO: verify that the group rid exists\n"));
2553 /* associate a RID with the (unique) handle. */
2554 if (status == 0x0 && !set_policy_samr_rid(group_pol, group_rid))
2556 /* oh, whoops. don't know what error message to return, here */
2557 status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2560 sid_append_rid(sid, group_rid);
2562 /* associate an group SID with the (unique) handle. */
2563 if (status == 0x0 && !set_policy_samr_sid(group_pol, sid))
2565 /* oh, whoops. don't know what error message to return, here */
2566 status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2569 if (status != 0 && pol_open)
2571 close_policy_hnd(group_pol);
2577 /*******************************************************************
2578 samr_reply_create_dom_group
2579 ********************************************************************/
2580 static void samr_reply_create_dom_group(SAMR_Q_CREATE_DOM_GROUP *q_u,
2583 SAMR_R_CREATE_DOM_GROUP r_u;
2586 POLICY_HND group_pol;
2587 uint32 status = 0x0;
2589 bzero(&group_pol, sizeof(group_pol));
2591 DEBUG(5,("samr_create_dom_group: %d\n", __LINE__));
2593 /* find the policy handle. open a policy on it. */
2594 if (status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
2596 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
2599 /* find the domain sid */
2600 if (status == 0x0 && !get_policy_samr_sid(&q_u->pol, &dom_sid))
2602 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
2605 if (!sid_equal(&dom_sid, &global_sam_sid))
2607 status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
2612 unistr2_to_ascii(grp.name, &q_u->uni_acct_desc, sizeof(grp.name)-1);
2613 fstrcpy(grp.comment, "");
2614 grp.rid = 0xffffffff;
2618 status = add_group_entry(&grp) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
2619 unbecome_root(True);
2624 status = open_samr_group(&dom_sid, &group_pol, grp.rid);
2627 /* construct the response. */
2628 make_samr_r_create_dom_group(&r_u, &group_pol, grp.rid, status);
2630 /* store the response in the SMB stream */
2631 samr_io_r_create_dom_group("", &r_u, rdata, 0);
2633 DEBUG(5,("samr_create_dom_group: %d\n", __LINE__));
2637 /*******************************************************************
2638 api_samr_create_dom_group
2639 ********************************************************************/
2640 static void api_samr_create_dom_group( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
2642 SAMR_Q_CREATE_DOM_GROUP q_u;
2643 samr_io_q_create_dom_group("", &q_u, data, 0);
2644 samr_reply_create_dom_group(&q_u, rdata);
2648 /*******************************************************************
2649 samr_reply_query_dom_info
2650 ********************************************************************/
2651 static void samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
2654 SAMR_R_QUERY_DOMAIN_INFO r_u;
2656 uint16 switch_value = 0x0;
2657 uint32 status = 0x0;
2664 DEBUG(5,("samr_reply_query_dom_info: %d\n", __LINE__));
2666 /* find the policy handle. open a policy on it. */
2667 if (r_u.status == 0x0 && (find_policy_by_hnd(&(q_u->domain_pol)) == -1))
2669 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
2670 DEBUG(5,("samr_reply_query_dom_info: invalid handle\n"));
2675 switch (q_u->switch_value)
2680 make_unk_info7(&ctr.info.inf7);
2687 make_unk_info6(&ctr.info.inf6);
2694 make_unk_info3(&ctr.info.inf3);
2701 make_unk_info2(&ctr.info.inf2, global_sam_name, global_myname);
2708 make_unk_info1(&ctr.info.inf1);
2714 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
2720 make_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
2722 /* store the response in the SMB stream */
2723 samr_io_r_query_dom_info("", &r_u, rdata, 0);
2725 DEBUG(5,("samr_query_dom_info: %d\n", __LINE__));
2729 /*******************************************************************
2730 api_samr_query_dom_info
2731 ********************************************************************/
2732 static void api_samr_query_dom_info( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
2734 SAMR_Q_QUERY_DOMAIN_INFO q_e;
2735 samr_io_q_query_dom_info("", &q_e, data, 0);
2736 samr_reply_query_dom_info(&q_e, rdata);
2741 /*******************************************************************
2742 samr_reply_create_user
2743 ********************************************************************/
2744 static void samr_reply_create_user(SAMR_Q_CREATE_USER *q_u,
2747 struct sam_passwd *sam_pass;
2750 SAMR_R_CREATE_USER r_u;
2752 uint32 status = 0x0;
2753 uint32 user_rid = 0x0;
2754 BOOL pol_open = False;
2755 uint32 unk_0 = 0x30;
2757 /* find the machine account: tell the caller if it exists.
2758 lkclXXXX i have *no* idea if this is a problem or not
2759 or even if you are supposed to construct a different
2760 reply if the account already exists...
2763 /* find the policy handle. open a policy on it. */
2764 if (status == 0x0 && (find_policy_by_hnd(&(q_u->domain_pol)) == -1))
2766 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
2769 /* get a (unique) handle. open a policy on it. */
2770 if (status == 0x0 && !(pol_open = open_policy_hnd(&pol)))
2772 status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2775 unistr2_to_ascii(user_name, &q_u->uni_name, sizeof(user_name)-1);
2777 sam_pass = getsam21pwntnam(user_name);
2779 if (sam_pass != NULL)
2781 /* account exists: say so */
2782 status = 0xC0000000 | NT_STATUS_USER_EXISTS;
2789 if (!local_password_change(user_name, True,
2790 q_u->acb_info | ACB_DISABLED | ACB_PWNOTREQ, 0xffff,
2792 err_str, sizeof(err_str),
2793 msg_str, sizeof(msg_str)))
2795 DEBUG(0,("%s\n", err_str));
2796 status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
2800 sam_pass = getsam21pwntnam(user_name);
2801 if (sam_pass == NULL)
2803 /* account doesn't exist: say so */
2804 status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
2808 user_rid = sam_pass->user_rid;
2814 /* associate the RID with the (unique) handle. */
2815 if (status == 0x0 && !set_policy_samr_rid(&pol, user_rid))
2817 /* oh, whoops. don't know what error message to return, here */
2818 status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2821 if (status != 0 && pol_open)
2823 close_policy_hnd(&pol);
2826 DEBUG(5,("samr_create_user: %d\n", __LINE__));
2828 make_samr_r_create_user(&r_u, &pol, unk_0, user_rid, status);
2830 /* store the response in the SMB stream */
2831 samr_io_r_create_user("", &r_u, rdata, 0);
2833 DEBUG(5,("samr_create_user: %d\n", __LINE__));
2837 /*******************************************************************
2838 api_samr_create_user
2839 ********************************************************************/
2840 static void api_samr_create_user( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
2842 SAMR_Q_CREATE_USER q_u;
2844 /* grab the samr unknown 32 */
2845 samr_io_q_create_user("", &q_u, data, 0);
2847 /* construct reply. */
2848 samr_reply_create_user(&q_u, rdata);
2852 /*******************************************************************
2853 samr_reply_connect_anon
2854 ********************************************************************/
2855 static void samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u,
2858 SAMR_R_CONNECT_ANON r_u;
2859 BOOL pol_open = False;
2861 /* set up the SAMR connect_anon response */
2864 /* get a (unique) handle. open a policy on it. */
2865 if (r_u.status == 0x0 && !(pol_open = open_policy_hnd(&(r_u.connect_pol))))
2867 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2870 /* associate the domain SID with the (unique) handle. */
2871 if (r_u.status == 0x0 && !set_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
2873 /* oh, whoops. don't know what error message to return, here */
2874 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2877 if (r_u.status != 0 && pol_open)
2879 close_policy_hnd(&(r_u.connect_pol));
2882 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
2884 /* store the response in the SMB stream */
2885 samr_io_r_connect_anon("", &r_u, rdata, 0);
2887 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
2891 /*******************************************************************
2892 api_samr_connect_anon
2893 ********************************************************************/
2894 static void api_samr_connect_anon( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
2896 SAMR_Q_CONNECT_ANON q_u;
2897 samr_io_q_connect_anon("", &q_u, data, 0);
2898 samr_reply_connect_anon(&q_u, rdata);
2901 /*******************************************************************
2903 ********************************************************************/
2904 static void samr_reply_connect(SAMR_Q_CONNECT *q_u,
2908 BOOL pol_open = False;
2910 /* set up the SAMR connect response */
2913 /* get a (unique) handle. open a policy on it. */
2914 if (r_u.status == 0x0 && !(pol_open = open_policy_hnd(&(r_u.connect_pol))))
2916 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2919 /* associate the domain SID with the (unique) handle. */
2920 if (r_u.status == 0x0 && !set_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
2922 /* oh, whoops. don't know what error message to return, here */
2923 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2926 if (r_u.status != 0 && pol_open)
2928 close_policy_hnd(&(r_u.connect_pol));
2931 DEBUG(5,("samr_connect: %d\n", __LINE__));
2933 /* store the response in the SMB stream */
2934 samr_io_r_connect("", &r_u, rdata, 0);
2936 DEBUG(5,("samr_connect: %d\n", __LINE__));
2940 /*******************************************************************
2942 ********************************************************************/
2943 static void api_samr_connect( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
2946 samr_io_q_connect("", &q_u, data, 0);
2947 samr_reply_connect(&q_u, rdata);
2950 /*******************************************************************
2951 samr_reply_open_alias
2952 ********************************************************************/
2953 static void samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
2956 SAMR_R_OPEN_ALIAS r_u;
2958 BOOL pol_open = False;
2960 /* set up the SAMR open_alias response */
2963 if (r_u.status == 0x0 && !get_policy_samr_sid(&q_u->dom_pol, &sid))
2965 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
2968 /* get a (unique) handle. open a policy on it. */
2969 if (r_u.status == 0x0 && !(pol_open = open_policy_hnd(&(r_u.pol))))
2971 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2974 DEBUG(0,("TODO: verify that the alias rid exists\n"));
2976 /* associate a RID with the (unique) handle. */
2977 if (r_u.status == 0x0 && !set_policy_samr_rid(&(r_u.pol), q_u->rid_alias))
2979 /* oh, whoops. don't know what error message to return, here */
2980 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2983 sid_append_rid(&sid, q_u->rid_alias);
2985 /* associate an alias SID with the (unique) handle. */
2986 if (r_u.status == 0x0 && !set_policy_samr_sid(&(r_u.pol), &sid))
2988 /* oh, whoops. don't know what error message to return, here */
2989 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
2992 if (r_u.status != 0 && pol_open)
2994 close_policy_hnd(&(r_u.pol));
2997 DEBUG(5,("samr_open_alias: %d\n", __LINE__));
2999 /* store the response in the SMB stream */
3000 samr_io_r_open_alias("", &r_u, rdata, 0);
3002 DEBUG(5,("samr_open_alias: %d\n", __LINE__));
3006 /*******************************************************************
3008 ********************************************************************/
3009 static void api_samr_open_alias( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
3012 SAMR_Q_OPEN_ALIAS q_u;
3013 samr_io_q_open_alias("", &q_u, data, 0);
3014 samr_reply_open_alias(&q_u, rdata);
3017 /*******************************************************************
3018 samr_reply_open_group
3019 ********************************************************************/
3020 static void samr_reply_open_group(SAMR_Q_OPEN_GROUP *q_u,
3023 SAMR_R_OPEN_GROUP r_u;
3026 DEBUG(5,("samr_open_group: %d\n", __LINE__));
3030 /* find the domain sid associated with the policy handle */
3031 if (r_u.status == 0x0 && !get_policy_samr_sid(&q_u->domain_pol, &sid))
3033 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
3036 if (r_u.status == 0x0 && !sid_equal(&sid, &global_sam_sid))
3038 r_u.status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
3041 if (r_u.status == 0x0)
3043 r_u.status = open_samr_group(&sid, &r_u.pol, q_u->rid_group);
3046 /* store the response in the SMB stream */
3047 samr_io_r_open_group("", &r_u, rdata, 0);
3049 DEBUG(5,("samr_open_group: %d\n", __LINE__));
3053 /*******************************************************************
3055 ********************************************************************/
3056 static void api_samr_open_group( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
3059 SAMR_Q_OPEN_GROUP q_u;
3060 samr_io_q_open_group("", &q_u, data, 0);
3061 samr_reply_open_group(&q_u, rdata);
3064 /*******************************************************************
3065 samr_reply_lookup_domain
3066 ********************************************************************/
3067 static void samr_reply_lookup_domain(SAMR_Q_LOOKUP_DOMAIN *q_u,
3070 SAMR_R_LOOKUP_DOMAIN r_u;
3073 DEBUG(5,("samr_lookup_domain: %d\n", __LINE__));
3078 /* find the connection policy handle */
3079 if (find_policy_by_hnd(&(q_u->connect_pol)) == -1)
3081 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
3084 if (r_u.status == 0x0)
3086 unistr2_to_ascii(domain, &(q_u->uni_domain), sizeof(domain));
3087 DEBUG(5, ("Lookup Domain: %s\n", domain));
3089 /* check it's one of ours */
3090 if (strequal(domain, global_sam_name))
3092 make_dom_sid2(&(r_u.dom_sid), &global_sam_sid);
3095 else if (strequal(domain, "BUILTIN"))
3097 make_dom_sid2(&(r_u.dom_sid), &global_sid_S_1_5_20);
3102 r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_DOMAIN;
3106 /* store the response in the SMB stream */
3107 samr_io_r_lookup_domain("", &r_u, rdata, 0);
3109 DEBUG(5,("samr_lookup_domain: %d\n", __LINE__));
3112 /*******************************************************************
3113 api_samr_lookup_domain
3114 ********************************************************************/
3115 static void api_samr_lookup_domain( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
3117 SAMR_Q_LOOKUP_DOMAIN q_u;
3118 samr_io_q_lookup_domain("", &q_u, data, 0);
3119 samr_reply_lookup_domain(&q_u, rdata);
3122 /*******************************************************************
3123 array of \PIPE\samr operations
3124 ********************************************************************/
3125 static struct api_struct api_samr_cmds [] =
3127 { "SAMR_CLOSE_HND" , SAMR_CLOSE_HND , api_samr_close_hnd },
3128 { "SAMR_CONNECT" , SAMR_CONNECT , api_samr_connect },
3129 { "SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON , api_samr_connect_anon },
3130 { "SAMR_ENUM_DOMAINS" , SAMR_ENUM_DOMAINS , api_samr_enum_domains },
3131 { "SAMR_ENUM_DOM_USERS" , SAMR_ENUM_DOM_USERS , api_samr_enum_dom_users },
3132 { "SAMR_ENUM_DOM_GROUPS" , SAMR_ENUM_DOM_GROUPS , api_samr_enum_dom_groups },
3133 { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
3134 { "SAMR_QUERY_USERALIASES", SAMR_QUERY_USERALIASES, api_samr_query_useraliases},
3135 { "SAMR_QUERY_ALIASMEM" , SAMR_QUERY_ALIASMEM , api_samr_query_aliasmem },
3136 { "SAMR_QUERY_GROUPMEM" , SAMR_QUERY_GROUPMEM , api_samr_query_groupmem },
3137 { "SAMR_ADD_ALIASMEM" , SAMR_ADD_ALIASMEM , api_samr_add_aliasmem },
3138 { "SAMR_DEL_ALIASMEM" , SAMR_DEL_ALIASMEM , api_samr_del_aliasmem },
3139 { "SAMR_ADD_GROUPMEM" , SAMR_ADD_GROUPMEM , api_samr_add_groupmem },
3140 { "SAMR_DEL_GROUPMEM" , SAMR_DEL_GROUPMEM , api_samr_del_groupmem },
3141 { "SAMR_DELETE_DOM_GROUP" , SAMR_DELETE_DOM_GROUP , api_samr_delete_dom_group },
3142 { "SAMR_DELETE_DOM_ALIAS" , SAMR_DELETE_DOM_ALIAS , api_samr_delete_dom_alias },
3143 { "SAMR_CREATE_DOM_GROUP" , SAMR_CREATE_DOM_GROUP , api_samr_create_dom_group },
3144 { "SAMR_CREATE_DOM_ALIAS" , SAMR_CREATE_DOM_ALIAS , api_samr_create_dom_alias },
3145 { "SAMR_LOOKUP_NAMES" , SAMR_LOOKUP_NAMES , api_samr_lookup_names },
3146 { "SAMR_OPEN_USER" , SAMR_OPEN_USER , api_samr_open_user },
3147 { "SAMR_QUERY_USERINFO" , SAMR_QUERY_USERINFO , api_samr_query_userinfo },
3148 { "SAMR_SET_USERINFO" , SAMR_SET_USERINFO , api_samr_set_userinfo },
3149 { "SAMR_SET_USERINFO2" , SAMR_SET_USERINFO2 , api_samr_set_userinfo2 },
3150 { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
3151 { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
3152 { "SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo },
3153 { "SAMR_QUERY_DISPINFO3" , SAMR_QUERY_DISPINFO3 , api_samr_query_dispinfo },
3154 { "SAMR_QUERY_DISPINFO4" , SAMR_QUERY_DISPINFO4 , api_samr_query_dispinfo },
3155 { "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo },
3156 { "SAMR_QUERY_GROUPINFO" , SAMR_QUERY_GROUPINFO , api_samr_query_groupinfo },
3157 { "SAMR_CREATE_USER" , SAMR_CREATE_USER , api_samr_create_user },
3158 { "SAMR_LOOKUP_RIDS" , SAMR_LOOKUP_RIDS , api_samr_lookup_rids },
3159 { "SAMR_GET_DOM_PWINFO" , SAMR_GET_DOM_PWINFO , api_samr_unknown_38 },
3160 { "SAMR_CHGPASSWD_USER" , SAMR_CHGPASSWD_USER , api_samr_chgpasswd_user },
3161 { "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias },
3162 { "SAMR_OPEN_GROUP" , SAMR_OPEN_GROUP , api_samr_open_group },
3163 { "SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain },
3164 { "SAMR_LOOKUP_DOMAIN" , SAMR_LOOKUP_DOMAIN , api_samr_lookup_domain },
3165 { "SAMR_QUERY_SEC_OBJECT" , SAMR_QUERY_SEC_OBJECT , api_samr_unknown_3 },
3166 { "SAMR_GET_USRDOM_PWINFO", SAMR_GET_USRDOM_PWINFO, api_samr_unknown_2c },
3170 /*******************************************************************
3171 receives a samr pipe and responds.
3172 ********************************************************************/
3173 BOOL api_samr_rpc(rpcsrv_struct *p, prs_struct *data)
3175 return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds, data);