2 * Unix SMB/Netbios implementation.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-2000,
6 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
7 * Copyright (C) Sander Striker 2000
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include "rpc_parse.h"
30 extern int DEBUGLEVEL
;
33 /****************************************************************************
35 ****************************************************************************/
36 static BOOL
set_policy_samr_sid(struct policy_cache
*cache
, POLICY_HND
* hnd
,
40 DOM_SID
*dev
= sid_dup(sid
);
42 DEBUG(3, ("Setting policy sid=%s\n", sid_to_string(sidstr
, sid
)));
46 if (set_policy_state(cache
, hnd
, NULL
, (void *)dev
))
48 DEBUG(3, ("Service setting policy sid=%s\n", sidstr
));
54 DEBUG(3, ("Error setting policy sid\n"));
58 /****************************************************************************
60 ****************************************************************************/
61 static BOOL
get_policy_samr_sid(struct policy_cache
*cache
,
62 const POLICY_HND
* hnd
, DOM_SID
* sid
)
64 DOM_SID
*dev
= (DOM_SID
*) get_policy_state_info(cache
, hnd
);
70 DEBUG(3, ("Getting policy sid=%s\n",
71 sid_to_string(tmp
, sid
)));
75 DEBUG(3, ("Error getting policy sid\n"));
79 /*******************************************************************
80 This next function should be replaced with something that
81 dynamically returns the correct user info..... JRA.
82 ********************************************************************/
84 static BOOL
get_sampwd_entries(SAM_USER_INFO_21
* pw_buf
,
86 int *total_entries
, int *num_entries
,
87 int max_num_entries
, uint16 acb_mask
)
90 struct sam_passwd
*pwd
= NULL
;
98 vp
= startsmbpwent(False
);
102 ("get_sampwd_entries: Unable to open SMB password database.\n"));
106 while (((pwd
= getsam21pwent(vp
)) != NULL
)
107 && (*num_entries
) < max_num_entries
)
113 /* skip the requested number of entries.
114 not very efficient, but hey...
117 || IS_BITS_SET_SOME(pwd
->acct_ctrl
, acb_mask
))
124 user_name_len
= strlen(pwd
->nt_name
);
125 make_unistr2(&(pw_buf
[(*num_entries
)].uni_user_name
),
126 pwd
->nt_name
, user_name_len
);
127 make_uni_hdr(&(pw_buf
[(*num_entries
)].hdr_user_name
),
129 pw_buf
[(*num_entries
)].user_rid
= pwd
->user_rid
;
130 memset(pw_buf
[(*num_entries
)].nt_pwd
, 0, 16);
132 /* Now check if the NT compatible password is available. */
133 if (pwd
->smb_nt_passwd
!= NULL
)
135 memcpy(pw_buf
[(*num_entries
)].nt_pwd
,
136 pwd
->smb_nt_passwd
, 16);
139 pw_buf
[(*num_entries
)].acb_info
= (uint16
) pwd
->acct_ctrl
;
141 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
142 (*num_entries
), pwd
->nt_name
,
143 pwd
->user_rid
, pwd
->acct_ctrl
));
146 || IS_BITS_SET_SOME(pwd
->acct_ctrl
, acb_mask
))
148 DEBUG(5, (" acb_mask %x accepts\n", acb_mask
));
153 DEBUG(5, (" acb_mask %x rejects\n", acb_mask
));
161 return (*total_entries
) >= 0;
164 /*******************************************************************
165 opens a samr group by rid, returns a policy handle.
166 ********************************************************************/
167 static uint32
samr_open_by_sid(const POLICY_HND
* parent_pol
,
168 const DOM_SID
* dom_sid
,
170 uint32 access_mask
, uint32 rid
)
174 /* get a (unique) handle. open a policy on it. */
175 if (!open_policy_hnd_link(get_global_hnd_cache(),
176 parent_pol
, pol
, access_mask
))
178 return NT_STATUS_ACCESS_DENIED
;
181 DEBUG(0, ("TODO: verify that the rid exists\n"));
183 /* associate a SID with the (unique) handle. */
184 sid_copy(&sid
, dom_sid
);
185 sid_append_rid(&sid
, rid
);
187 /* associate an group SID with the (unique) handle. */
188 if (!set_policy_samr_sid(get_global_hnd_cache(), pol
, &sid
))
190 /* close the policy in case we can't associate a group SID */
191 close_policy_hnd(get_global_hnd_cache(), pol
);
192 return NT_STATUS_ACCESS_DENIED
;
195 return NT_STATUS_NOPROBLEMO
;
198 /*******************************************************************
200 ********************************************************************/
201 uint32
_samr_close(POLICY_HND
* hnd
)
203 /* close the policy handle */
204 if (close_policy_hnd(get_global_hnd_cache(), hnd
))
206 return NT_STATUS_NOPROBLEMO
;
208 return NT_STATUS_OBJECT_NAME_INVALID
;
211 /*******************************************************************
212 samr_reply_unknown_2d
213 ********************************************************************/
214 uint32
_samr_unknown_2d(const POLICY_HND
* domain_pol
, const DOM_SID
* sid
)
218 /* associate the domain SID with the (unique) handle. */
219 if (!get_policy_samr_sid(get_global_hnd_cache(),
220 domain_pol
, &dom_sid
))
222 return NT_STATUS_ACCESS_DENIED
;
225 DEBUG(0, ("_samr_unknown_2d: not implemented, returning OK\n"));
226 DEBUG(5, ("_samr_unknown_2d: %d\n", __LINE__
));
228 return NT_STATUS_NOPROBLEMO
;
231 /*******************************************************************
232 samr_reply_open_domain
233 ********************************************************************/
234 uint32
_samr_open_domain(const POLICY_HND
* connect_pol
,
236 const DOM_SID
* sid
, POLICY_HND
* domain_pol
)
238 /* find the connection policy handle. */
239 if (find_policy_by_hnd(get_global_hnd_cache(), connect_pol
) == -1)
241 return NT_STATUS_INVALID_HANDLE
;
244 /* get a (unique) handle. open a policy on it. */
245 if (!open_policy_hnd_link(get_global_hnd_cache(),
246 connect_pol
, domain_pol
, ace_perms
))
248 return NT_STATUS_ACCESS_DENIED
;
251 policy_hnd_set_name(get_global_hnd_cache(), domain_pol
, "sam_domain");
253 /* associate the domain SID with the (unique) handle. */
254 if (!set_policy_samr_sid(get_global_hnd_cache(), domain_pol
, sid
))
256 close_policy_hnd(get_global_hnd_cache(), domain_pol
);
257 return NT_STATUS_ACCESS_DENIED
;
260 DEBUG(5, ("_samr_open_domain: %d\n", __LINE__
));
262 return NT_STATUS_NOPROBLEMO
;
265 /*******************************************************************
266 samr_reply_get_usrdom_pwinfo
267 ********************************************************************/
268 uint32
_samr_get_usrdom_pwinfo(const POLICY_HND
* user_pol
,
270 uint16
* unknown_1
, uint32
* unknown_2
)
275 /* find the policy handle. open a policy on it. */
276 if (!get_policy_samr_sid(get_global_hnd_cache(), user_pol
, &sid
))
278 return NT_STATUS_INVALID_HANDLE
;
281 sid_split_rid(&sid
, &rid
);
285 *unknown_2
= 0x00000000;
287 DEBUG(5, ("samr_get_usrdom_pwinfo: %d\n", __LINE__
));
289 return NT_STATUS_NOPROBLEMO
;
292 /*******************************************************************
293 samr_reply_query_sec_obj
294 ********************************************************************/
295 uint32
_samr_query_sec_obj(const POLICY_HND
* user_pol
, SEC_DESC_BUF
* buf
)
299 /* find the policy handle. open a policy on it. */
300 if (!get_policy_samr_sid(get_global_hnd_cache(), user_pol
, &usr_sid
))
302 return NT_STATUS_INVALID_HANDLE
;
305 SMB_ASSERT_ARRAY(usr_sid
.sub_auths
, usr_sid
.num_auths
+ 1);
308 /* maybe need another 1 or 2 (S-1-5-0x20-0x220 and S-1-5-20-0x224) */
309 /* these two are DOMAIN_ADMIN and DOMAIN_ACCT_OP group RIDs */
310 make_dom_sid3(&sid_stuff
->sid
[0], 0x035b, 0x0002, &global_sid_S_1_1
);
311 make_dom_sid3(&sid_stuff
->sid
[1], 0x0044, 0x0002, &usr_sid
);
313 make_sam_sid_stuff(sid_stuff
,
314 0x0001, 0x8004, 0x00000014, 0x0002, 0x0070, 2);
317 DEBUG(5, ("samr_query_sec_obj: %d\n", __LINE__
));
319 return samr_make_usr_obj_sd(buf
, &usr_sid
);
322 /*******************************************************************
323 makes a SAM_ENTRY / UNISTR2* structure.
324 ********************************************************************/
325 static void make_samr_dom_users(SAM_ENTRY
** sam
, UNISTR2
** uni_acct_name
,
326 uint32 num_sam_entries
,
327 SAM_USER_INFO_21 pass
[MAX_SAM_ENTRIES
])
332 *uni_acct_name
= NULL
;
334 if (num_sam_entries
== 0)
339 (*sam
) = g_new(SAM_ENTRY
, num_sam_entries
);
341 (*uni_acct_name
) = g_new(UNISTR2
, num_sam_entries
);
343 if ((*sam
) == NULL
|| (*uni_acct_name
) == NULL
)
345 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
349 for (i
= 0; i
< num_sam_entries
; i
++)
351 make_sam_entry(&((*sam
)[i
]),
352 pass
[i
].uni_user_name
.uni_str_len
,
355 copy_unistr2(&((*uni_acct_name
)[i
]),
356 &(pass
[i
].uni_user_name
));
360 /*******************************************************************
361 samr_reply_enum_dom_users
362 ********************************************************************/
363 uint32
_samr_enum_dom_users(const POLICY_HND
* pol
, uint32
* start_idx
,
364 uint16 acb_mask
, uint16 unk_1
, uint32 size
,
366 UNISTR2
** uni_acct_name
, uint32
* num_sam_users
)
368 SAM_USER_INFO_21 pass
[MAX_SAM_ENTRIES
];
372 /* find the policy handle. open a policy on it. */
373 if (find_policy_by_hnd(get_global_hnd_cache(), pol
) == -1)
375 return NT_STATUS_INVALID_HANDLE
;
378 DEBUG(5, ("samr_reply_enum_dom_users: %d\n", __LINE__
));
381 ret
= get_sampwd_entries(pass
, (*start_idx
), &total_entries
,
382 num_sam_users
, MAX_SAM_ENTRIES
, acb_mask
);
386 return NT_STATUS_ACCESS_DENIED
;
389 (*start_idx
) += (*num_sam_users
);
390 make_samr_dom_users(sam
, uni_acct_name
, (*num_sam_users
), pass
);
392 DEBUG(5, ("samr_enum_dom_users: %d\n", __LINE__
));
394 return NT_STATUS_NOPROBLEMO
;
397 /*******************************************************************
398 samr_reply_add_groupmem
399 ********************************************************************/
400 uint32
_samr_add_groupmem(const POLICY_HND
* pol
, uint32 rid
, uint32 unknown
)
404 fstring group_sid_str
;
406 /* find the policy handle. open a policy on it. */
407 if (!get_policy_samr_sid(get_global_hnd_cache(), pol
, &group_sid
))
409 return NT_STATUS_INVALID_HANDLE
;
412 sid_to_string(group_sid_str
, &group_sid
);
413 sid_split_rid(&group_sid
, &group_rid
);
415 DEBUG(10, ("sid is %s\n", group_sid_str
));
417 if (!sid_equal(&group_sid
, &global_sam_sid
))
419 return NT_STATUS_NO_SUCH_GROUP
;
422 DEBUG(10, ("lookup on Domain SID\n"));
424 if (!add_group_member(group_rid
, rid
))
426 return NT_STATUS_ACCESS_DENIED
;
429 return NT_STATUS_NOPROBLEMO
;
432 /*******************************************************************
433 samr_reply_del_groupmem
434 ********************************************************************/
435 uint32
_samr_del_groupmem(const POLICY_HND
* pol
, uint32 rid
)
439 fstring group_sid_str
;
441 /* find the policy handle. open a policy on it. */
442 if (!get_policy_samr_sid(get_global_hnd_cache(), pol
, &group_sid
))
444 return NT_STATUS_INVALID_HANDLE
;
447 sid_to_string(group_sid_str
, &group_sid
);
448 sid_split_rid(&group_sid
, &group_rid
);
450 DEBUG(10, ("sid is %s\n", group_sid_str
));
452 if (!sid_equal(&group_sid
, &global_sam_sid
))
454 return NT_STATUS_NO_SUCH_GROUP
;
456 DEBUG(10, ("lookup on Domain SID\n"));
458 if (!del_group_member(group_rid
, rid
))
460 return NT_STATUS_ACCESS_DENIED
;
463 return NT_STATUS_NOPROBLEMO
;
466 /*******************************************************************
467 samr_reply_add_aliasmem
468 ********************************************************************/
469 uint32
_samr_add_aliasmem(const POLICY_HND
* alias_pol
, const DOM_SID
* sid
)
473 fstring alias_sid_str
;
475 /* find the policy handle. open a policy on it. */
476 if (!get_policy_samr_sid(get_global_hnd_cache(),
477 alias_pol
, &alias_sid
))
479 return NT_STATUS_INVALID_HANDLE
;
481 sid_to_string(alias_sid_str
, &alias_sid
);
482 sid_split_rid(&alias_sid
, &alias_rid
);
484 DEBUG(10, ("sid is %s\n", alias_sid_str
));
486 if (sid_equal(&alias_sid
, &global_sam_sid
))
488 DEBUG(10, ("add member on Domain SID\n"));
490 if (!add_alias_member(alias_rid
, sid
))
492 return NT_STATUS_ACCESS_DENIED
;
495 else if (sid_equal(&alias_sid
, global_sid_builtin
))
497 DEBUG(10, ("add member on BUILTIN SID\n"));
499 if (!add_builtin_member(alias_rid
, sid
))
501 return NT_STATUS_ACCESS_DENIED
;
506 return NT_STATUS_NO_SUCH_ALIAS
;
509 return NT_STATUS_NOPROBLEMO
;
512 /*******************************************************************
513 samr_reply_del_aliasmem
514 ********************************************************************/
515 uint32
_samr_del_aliasmem(const POLICY_HND
* alias_pol
, const DOM_SID
* sid
)
519 fstring alias_sid_str
;
521 /* find the policy handle. open a policy on it. */
522 if (!get_policy_samr_sid(get_global_hnd_cache(),
523 alias_pol
, &alias_sid
))
525 return NT_STATUS_INVALID_HANDLE
;
527 sid_to_string(alias_sid_str
, &alias_sid
);
528 sid_split_rid(&alias_sid
, &alias_rid
);
530 DEBUG(10, ("sid is %s\n", alias_sid_str
));
532 if (sid_equal(&alias_sid
, &global_sam_sid
))
534 DEBUG(10, ("del member on Domain SID\n"));
536 if (!del_alias_member(alias_rid
, sid
))
538 return NT_STATUS_ACCESS_DENIED
;
541 else if (sid_equal(&alias_sid
, global_sid_builtin
))
543 DEBUG(10, ("del member on BUILTIN SID\n"));
545 if (!del_builtin_member(alias_rid
, sid
))
547 return NT_STATUS_ACCESS_DENIED
;
552 return NT_STATUS_NO_SUCH_ALIAS
;
555 return NT_STATUS_NOPROBLEMO
;
558 /******************************************************************
559 makes a SAMR_R_ENUM_DOMAINS structure.
560 ********************************************************************/
561 static void make_enum_domains(SAM_ENTRY
** sam
, UNISTR2
** uni_dom_name
,
562 uint32 num_sam_entries
, char **doms
)
566 DEBUG(5, ("make_enum_domains\n"));
569 (*uni_dom_name
) = NULL
;
571 if (num_sam_entries
== 0)
576 (*sam
) = g_new(SAM_ENTRY
, num_sam_entries
);
578 (*uni_dom_name
) = g_new(UNISTR2
, num_sam_entries
);
580 if ((*sam
) == NULL
|| (*uni_dom_name
) == NULL
)
582 DEBUG(0, ("NULL pointers in make_enum_domains\n"));
586 for (i
= 0; i
< num_sam_entries
; i
++)
588 int len
= doms
[i
] != NULL
? strlen(doms
[i
]) : 0;
590 make_sam_entry(&((*sam
)[i
]), len
, 0);
591 make_unistr2(&((*uni_dom_name
)[i
]), doms
[i
], len
);
596 /**************************************************************************
597 enumerates all domains for which the SAM server is responsible
598 ***************************************************************************/
599 static BOOL
enumdomains(char ***doms
, uint32
* num_entries
)
601 add_chars_to_array(num_entries
, doms
, global_sam_name
);
602 add_chars_to_array(num_entries
, doms
, "Builtin");
607 /*******************************************************************
608 samr_reply_enum_domains
609 ********************************************************************/
610 uint32
_samr_enum_domains(const POLICY_HND
* pol
, uint32
* start_idx
,
613 UNISTR2
** uni_acct_name
, uint32
* num_sam_users
)
616 uint32 num_entries
= 0;
618 /* find the connection policy handle. */
619 if (find_policy_by_hnd(get_global_hnd_cache(), pol
) == -1)
621 return NT_STATUS_INVALID_HANDLE
;
624 DEBUG(5, ("samr_reply_enum_domains:\n"));
626 if (!enumdomains(&doms
, &num_entries
))
628 return NT_STATUS_NO_MEMORY
;
631 make_enum_domains(sam
, uni_acct_name
, num_entries
, doms
);
633 (*start_idx
) += num_entries
;
634 (*num_sam_users
) = num_entries
;
636 free_char_array(num_entries
, doms
);
638 return NT_STATUS_NOPROBLEMO
;
641 /*******************************************************************
642 makes a SAMR_R_ENUM_DOM_GROUPS structure.
643 ********************************************************************/
644 static void make_samr_dom_groups(SAM_ENTRY
** sam
, UNISTR2
** uni_grp_name
,
645 uint32 num_sam_entries
, DOMAIN_GRP
* grps
)
649 DEBUG(5, ("make_samr_dom_groups\n"));
652 (*uni_grp_name
) = NULL
;
654 if (num_sam_entries
== 0)
659 (*sam
) = g_new(SAM_ENTRY
, num_sam_entries
);
661 (*uni_grp_name
) = g_new(UNISTR2
, num_sam_entries
);
663 if ((*sam
) == NULL
|| (*uni_grp_name
) == NULL
)
665 DEBUG(0, ("NULL pointers in SAMR_R_ENUM_DOM_GROUPS\n"));
669 for (i
= 0; i
< num_sam_entries
; i
++)
671 int len
= strlen(grps
[i
].name
);
673 make_sam_entry(&((*sam
)[i
]), len
, grps
[i
].rid
);
674 make_unistr2(&((*uni_grp_name
)[i
]), grps
[i
].name
, len
);
678 /*******************************************************************
679 samr_reply_enum_dom_groups
680 ********************************************************************/
681 uint32
_samr_enum_dom_groups(const POLICY_HND
* pol
,
682 uint32
* start_idx
, uint32 size
,
684 UNISTR2
** uni_acct_name
,
685 uint32
* num_sam_groups
)
687 DOMAIN_GRP
*grps
= NULL
;
693 /* find the policy handle. open a policy on it. */
694 if (!get_policy_samr_sid(get_global_hnd_cache(), pol
, &sid
))
696 return NT_STATUS_INVALID_HANDLE
;
699 sid_to_string(sid_str
, &sid
);
701 DEBUG(5, ("samr_reply_enum_dom_groups: sid %s\n", sid_str
));
703 if (!sid_equal(&sid
, &global_sam_sid
))
705 return NT_STATUS_ACCESS_DENIED
;
709 ret
= enumdomgroups(&grps
, &num_entries
);
713 return NT_STATUS_ACCESS_DENIED
;
716 (*start_idx
) += num_entries
;
717 (*num_sam_groups
) = num_entries
;
719 make_samr_dom_groups(sam
, uni_acct_name
, num_entries
, grps
);
723 return NT_STATUS_NOPROBLEMO
;
726 /*******************************************************************
727 makes a SAMR_R_ENUM_DOM_ALIASES structure.
728 ********************************************************************/
729 static void make_samr_dom_aliases(SAM_ENTRY
** sam
, UNISTR2
** uni_grp_name
,
730 uint32 num_sam_entries
, LOCAL_GRP
* alss
)
734 DEBUG(5, ("make_samr_r_enum_dom_aliases\n"));
737 (*uni_grp_name
) = NULL
;
739 if (num_sam_entries
== 0)
744 (*sam
) = g_new(SAM_ENTRY
, num_sam_entries
);
746 (*uni_grp_name
) = g_new(UNISTR2
, num_sam_entries
);
748 if ((*sam
) == NULL
|| (*uni_grp_name
) == NULL
)
750 DEBUG(0, ("NULL pointers in SAMR_R_ENUM_DOM_ALIASES\n"));
754 for (i
= 0; i
< num_sam_entries
; i
++)
756 int len
= strlen(alss
[i
].name
);
758 make_sam_entry(&((*sam
)[i
]), len
, alss
[i
].rid
);
759 make_unistr2(&((*uni_grp_name
)[i
]), alss
[i
].name
, len
);
763 /*******************************************************************
764 samr_reply_enum_dom_aliases
765 ********************************************************************/
766 uint32
_samr_enum_dom_aliases(const POLICY_HND
* pol
,
767 uint32
* start_idx
, uint32 size
,
769 UNISTR2
** uni_acct_name
,
770 uint32
* num_sam_aliases
)
772 LOCAL_GRP
*alss
= NULL
;
777 /* find the policy handle. open a policy on it. */
778 if (!get_policy_samr_sid(get_global_hnd_cache(), pol
, &sid
))
780 return NT_STATUS_INVALID_HANDLE
;
783 sid_to_string(sid_str
, &sid
);
785 DEBUG(5, ("samr_reply_enum_dom_aliases: sid %s\n", sid_str
));
787 /* well-known aliases */
788 if (sid_equal(&sid
, global_sid_builtin
))
791 /* builtin aliases */
794 ret
= enumdombuiltins(&alss
, &num_entries
);
798 return NT_STATUS_ACCESS_DENIED
;
801 else if (sid_equal(&sid
, &global_sam_sid
))
807 ret
= enumdomaliases(&alss
, &num_entries
);
811 return NT_STATUS_ACCESS_DENIED
;
815 (*start_idx
) += num_entries
;
816 (*num_sam_aliases
) = num_entries
;
818 make_samr_dom_aliases(sam
, uni_acct_name
, num_entries
, alss
);
822 return NT_STATUS_NOPROBLEMO
;
825 /*******************************************************************
826 samr_reply_query_dispinfo
827 ********************************************************************/
828 uint32
_samr_query_dispinfo(const POLICY_HND
* domain_pol
, uint16 level
,
833 uint32
* num_entries
, SAM_DISPINFO_CTR
* ctr
)
835 SAM_USER_INFO_21 pass
[MAX_SAM_ENTRIES
];
836 DOMAIN_GRP
*grps
= NULL
;
837 DOMAIN_GRP
*sam_grps
= NULL
;
838 uint16 acb_mask
= ACB_NORMAL
;
839 int num_sam_entries
= 0;
840 int total_entries
= 0;
842 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__
));
847 /* find the policy handle. open a policy on it. */
848 if (find_policy_by_hnd(get_global_hnd_cache(), domain_pol
) == -1)
850 DEBUG(5, ("samr_reply_query_dispinfo: invalid handle\n"));
851 return NT_STATUS_INVALID_HANDLE
;
854 /* Get what we need from the password database */
859 acb_mask
= ACB_WSTRUST
;
868 ret
= get_sampwd_entries(pass
, start_idx
,
871 MAX_SAM_ENTRIES
, acb_mask
);
875 DEBUG(5, ("get_sampwd_entries: failed\n"));
876 return NT_STATUS_ACCESS_DENIED
;
886 ret
= enumdomgroups(&sam_grps
, &num_sam_entries
);
890 return NT_STATUS_ACCESS_DENIED
;
893 if (start_idx
< num_sam_entries
)
895 grps
= sam_grps
+ start_idx
;
896 num_sam_entries
-= start_idx
;
907 (*num_entries
) = num_sam_entries
;
909 if ((*num_entries
) > max_entries
)
911 (*num_entries
) = max_entries
;
914 if ((*num_entries
) > MAX_SAM_ENTRIES
)
916 (*num_entries
) = MAX_SAM_ENTRIES
;
917 DEBUG(5, ("limiting number of entries to %d\n",
921 (*data_size
) = max_size
;
923 /* Now create reply structure */
928 ctr
->sam
.info1
= malloc(sizeof(SAM_DISPINFO_1
));
929 make_sam_dispinfo_1(ctr
->sam
.info1
,
930 num_entries
, data_size
,
936 ctr
->sam
.info2
= malloc(sizeof(SAM_DISPINFO_2
));
937 make_sam_dispinfo_2(ctr
->sam
.info2
,
938 num_entries
, data_size
,
944 ctr
->sam
.info3
= malloc(sizeof(SAM_DISPINFO_3
));
945 make_sam_dispinfo_3(ctr
->sam
.info3
,
946 num_entries
, data_size
,
952 ctr
->sam
.info4
= malloc(sizeof(SAM_DISPINFO_4
));
953 make_sam_dispinfo_4(ctr
->sam
.info4
,
954 num_entries
, data_size
,
960 ctr
->sam
.info5
= malloc(sizeof(SAM_DISPINFO_5
));
961 make_sam_dispinfo_5(ctr
->sam
.info5
,
962 num_entries
, data_size
,
968 ctr
->sam
.info
= NULL
;
970 return NT_STATUS_INVALID_INFO_CLASS
;
974 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__
));
978 if ((*num_entries
) < num_sam_entries
)
980 return STATUS_MORE_ENTRIES
;
983 return NT_STATUS_NOPROBLEMO
;
987 /*******************************************************************
989 ********************************************************************/
990 uint32
_samr_delete_dom_user(POLICY_HND
*user_pol
)
992 uint32 user_rid
= 0x0;
995 /* find the policy handle. open a policy on it. */
996 if (!get_policy_samr_sid(get_global_hnd_cache(), user_pol
, &user_sid
))
998 return NT_STATUS_INVALID_HANDLE
;
1000 sid_split_rid(&user_sid
, &user_rid
);
1002 DEBUG(0, ("_samr_delete_dom_user: user_rid:0x%x\n", user_rid
));
1004 if (!del_smbpwd_entry(user_rid
))
1006 return NT_STATUS_ACCESS_DENIED
;
1009 return NT_STATUS_NOPROBLEMO
;
1012 /*******************************************************************
1013 samr_reply_delete_dom_group
1014 ********************************************************************/
1015 uint32
_samr_delete_dom_group(POLICY_HND
* group_pol
)
1019 fstring group_sid_str
;
1021 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__
));
1023 /* find the policy handle. open a policy on it. */
1024 if (!get_policy_samr_sid(get_global_hnd_cache(),
1025 group_pol
, &group_sid
))
1027 return NT_STATUS_INVALID_HANDLE
;
1029 sid_to_string(group_sid_str
, &group_sid
);
1030 sid_split_rid(&group_sid
, &group_rid
);
1032 DEBUG(10, ("sid is %s\n", group_sid_str
));
1034 if (!sid_equal(&group_sid
, &global_sam_sid
))
1036 return NT_STATUS_NO_SUCH_GROUP
;
1039 DEBUG(10, ("lookup on Domain SID\n"));
1041 if (!del_group_entry(group_rid
))
1043 return NT_STATUS_ACCESS_DENIED
;
1046 return _samr_close(group_pol
);
1050 /*******************************************************************
1051 samr_reply_query_groupmem
1052 ********************************************************************/
1053 uint32
_samr_query_groupmem(const POLICY_HND
* group_pol
,
1054 uint32
* num_mem
, uint32
** rid
, uint32
** attr
)
1056 DOMAIN_GRP_MEMBER
*mem_grp
= NULL
;
1057 DOMAIN_GRP
*grp
= NULL
;
1061 fstring group_sid_str
;
1063 DEBUG(5, ("samr_query_groupmem: %d\n", __LINE__
));
1069 /* find the policy handle. open a policy on it. */
1070 if (!get_policy_samr_sid(get_global_hnd_cache(),
1071 group_pol
, &group_sid
))
1073 return NT_STATUS_INVALID_HANDLE
;
1075 sid_to_string(group_sid_str
, &group_sid
);
1076 sid_split_rid(&group_sid
, &group_rid
);
1078 DEBUG(10, ("sid is %s\n", group_sid_str
));
1080 if (!sid_equal(&group_sid
, &global_sam_sid
))
1082 return NT_STATUS_NO_SUCH_GROUP
;
1085 DEBUG(10, ("lookup on Domain SID\n"));
1088 grp
= getgrouprid(group_rid
, &mem_grp
, &num_rids
);
1089 unbecome_root(True
);
1093 return NT_STATUS_NO_SUCH_GROUP
;
1098 (*rid
) = g_new(uint32
, num_rids
);
1099 (*attr
) = g_new(uint32
, num_rids
);
1100 if (mem_grp
!= NULL
&& (*rid
) != NULL
&& (*attr
) != NULL
)
1103 for (i
= 0; i
< num_rids
; i
++)
1105 (*rid
)[i
] = mem_grp
[i
].rid
;
1106 (*attr
)[i
] = mem_grp
[i
].attr
;
1113 (*num_mem
) = num_rids
;
1115 return NT_STATUS_NOPROBLEMO
;
1118 /*******************************************************************
1120 ********************************************************************/
1121 uint32
_samr_set_groupinfo(const POLICY_HND
* pol
,
1122 uint16 switch_level
, const GROUP_INFO_CTR
* ctr
)
1124 return NT_STATUS_ACCESS_DENIED
;
1127 /*******************************************************************
1128 samr_reply_query_groupinfo
1129 ********************************************************************/
1130 uint32
_samr_query_groupinfo(const POLICY_HND
* pol
,
1131 uint16 switch_level
, GROUP_INFO_CTR
* ctr
)
1133 /* find the policy handle. open a policy on it. */
1134 if ((find_policy_by_hnd(get_global_hnd_cache(), pol
) == -1))
1136 return NT_STATUS_INVALID_HANDLE
;
1139 switch (switch_level
)
1143 ctr
->switch_value1
= 1;
1144 make_samr_group_info1(&ctr
->group
.info1
,
1145 "fake account name",
1146 "fake account description", 2);
1151 ctr
->switch_value1
= 4;
1152 make_samr_group_info4(&ctr
->group
.info4
,
1153 "fake account description");
1158 return NT_STATUS_INVALID_INFO_CLASS
;
1162 return NT_STATUS_NOPROBLEMO
;
1166 /*******************************************************************
1167 samr_reply_query_aliasinfo
1168 ********************************************************************/
1169 uint32
_samr_query_aliasinfo(const POLICY_HND
* alias_pol
,
1170 uint16 switch_level
, ALIAS_INFO_CTR
* ctr
)
1172 /* find the policy handle. open a policy on it. */
1173 if ((find_policy_by_hnd(get_global_hnd_cache(), alias_pol
) == -1))
1175 return NT_STATUS_INVALID_HANDLE
;
1178 switch (switch_level
)
1182 ctr
->switch_value1
= 3;
1183 make_samr_alias_info3(&ctr
->alias
.info3
,
1184 "<fake account description>");
1189 return NT_STATUS_INVALID_INFO_CLASS
;
1193 return NT_STATUS_NOPROBLEMO
;
1197 /*******************************************************************
1198 samr_reply_query_useraliases
1199 ********************************************************************/
1200 uint32
_samr_query_useraliases(const POLICY_HND
* pol
,
1201 const uint32
* ptr_sid
, const DOM_SID2
* sid
,
1202 uint32
* num_aliases
, uint32
** rid
)
1204 LOCAL_GRP
*mem_grp
= NULL
;
1206 struct sam_passwd
*sam_pass
;
1210 fstring sam_sid_str
;
1211 fstring dom_sid_str
;
1212 fstring usr_sid_str
;
1214 DEBUG(5, ("samr_query_useraliases: %d\n", __LINE__
));
1219 /* find the policy handle. open a policy on it. */
1220 if (!get_policy_samr_sid(get_global_hnd_cache(), pol
, &dom_sid
))
1222 return NT_STATUS_INVALID_HANDLE
;
1224 sid_to_string(dom_sid_str
, &dom_sid
);
1225 sid_to_string(sam_sid_str
, &global_sam_sid
);
1227 usr_sid
= sid
[0].sid
;
1228 sid_split_rid(&usr_sid
, &user_rid
);
1229 sid_to_string(usr_sid_str
, &usr_sid
);
1231 /* find the user account */
1233 sam_pass
= getsam21pwrid(user_rid
);
1234 unbecome_root(True
);
1236 if (sam_pass
== NULL
)
1238 return NT_STATUS_NO_SUCH_USER
;
1241 DEBUG(10, ("sid is %s\n", dom_sid_str
));
1243 if (sid_equal(&dom_sid
, global_sid_builtin
))
1246 DEBUG(10, ("lookup on S-1-5-20\n"));
1249 ret
= getuserbuiltinntnam(sam_pass
->nt_name
, &mem_grp
,
1251 unbecome_root(True
);
1255 return NT_STATUS_ACCESS_DENIED
;
1258 else if (sid_equal(&dom_sid
, &usr_sid
))
1261 DEBUG(10, ("lookup on Domain SID\n"));
1264 ret
= getuseraliasntnam(sam_pass
->nt_name
, &mem_grp
,
1266 unbecome_root(True
);
1270 return NT_STATUS_ACCESS_DENIED
;
1275 return NT_STATUS_NO_SUCH_USER
; /* no user (in domain) */
1280 (*rid
) = g_new(uint32
, num_rids
);
1281 if (mem_grp
!= NULL
&& (*rid
) != NULL
)
1284 for (i
= 0; i
< num_rids
; i
++)
1286 (*rid
)[i
] = mem_grp
[i
].rid
;
1291 (*num_aliases
) = num_rids
;
1294 return NT_STATUS_NOPROBLEMO
;
1297 /*******************************************************************
1298 samr_reply_delete_dom_alias
1299 ********************************************************************/
1300 uint32
_samr_delete_dom_alias(POLICY_HND
* alias_pol
)
1304 fstring alias_sid_str
;
1306 DEBUG(5, ("samr_delete_dom_alias: %d\n", __LINE__
));
1308 /* find the policy handle. open a policy on it. */
1309 if (!get_policy_samr_sid(get_global_hnd_cache(),
1310 alias_pol
, &alias_sid
))
1312 return NT_STATUS_INVALID_HANDLE
;
1315 sid_to_string(alias_sid_str
, &alias_sid
);
1316 sid_split_rid(&alias_sid
, &alias_rid
);
1318 DEBUG(10, ("sid is %s\n", alias_sid_str
));
1320 if (!sid_equal(&alias_sid
, &global_sam_sid
))
1322 return NT_STATUS_NO_SUCH_ALIAS
;
1325 DEBUG(10, ("lookup on Domain SID\n"));
1327 if (!del_alias_entry(alias_rid
))
1329 return NT_STATUS_NO_SUCH_ALIAS
;
1332 return _samr_close(alias_pol
);
1336 /*******************************************************************
1337 samr_reply_query_aliasmem
1338 ********************************************************************/
1339 uint32
_samr_query_aliasmem(const POLICY_HND
* alias_pol
,
1340 uint32
* num_mem
, DOM_SID2
** sid
)
1342 LOCAL_GRP_MEMBER
*mem_grp
= NULL
;
1343 LOCAL_GRP
*grp
= NULL
;
1347 fstring alias_sid_str
;
1349 DEBUG(5, ("samr_query_aliasmem: %d\n", __LINE__
));
1354 /* find the policy handle. open a policy on it. */
1355 if (!get_policy_samr_sid(get_global_hnd_cache(),
1356 alias_pol
, &alias_sid
))
1358 return NT_STATUS_INVALID_HANDLE
;
1360 sid_to_string(alias_sid_str
, &alias_sid
);
1361 sid_split_rid(&alias_sid
, &alias_rid
);
1363 DEBUG(10, ("sid is %s\n", alias_sid_str
));
1365 if (sid_equal(&alias_sid
, global_sid_builtin
))
1367 DEBUG(10, ("lookup on S-1-5-20\n"));
1370 grp
= getbuiltinrid(alias_rid
, &mem_grp
, &num_sids
);
1371 unbecome_root(True
);
1373 else if (sid_equal(&alias_sid
, &global_sam_sid
))
1375 DEBUG(10, ("lookup on Domain SID\n"));
1378 grp
= getaliasrid(alias_rid
, &mem_grp
, &num_sids
);
1379 unbecome_root(True
);
1383 return NT_STATUS_NO_SUCH_ALIAS
;
1388 return NT_STATUS_NO_SUCH_ALIAS
;
1393 (*sid
) = g_new(DOM_SID2
, num_sids
);
1394 if (mem_grp
!= NULL
&& sid
!= NULL
)
1397 for (i
= 0; i
< num_sids
; i
++)
1399 make_dom_sid2(&(*sid
)[i
], &mem_grp
[i
].sid
);
1404 (*num_mem
) = num_sids
;
1406 if (mem_grp
!= NULL
)
1411 return NT_STATUS_NOPROBLEMO
;
1414 /*******************************************************************
1415 samr_reply_lookup_names
1416 ********************************************************************/
1417 uint32
_samr_lookup_names(const POLICY_HND
* pol
,
1421 const UNISTR2
* uni_name
,
1423 uint32 rid
[MAX_SAM_ENTRIES
],
1424 uint32
* num_types1
, uint32 type
[MAX_SAM_ENTRIES
])
1427 int num_rids
= num_names1
;
1430 BOOL found_one
= False
;
1432 DEBUG(5, ("samr_lookup_names: %d\n", __LINE__
));
1434 if (!get_policy_samr_sid(get_global_hnd_cache(), pol
, &pol_sid
))
1436 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
1439 sid_to_string(tmp
, &pol_sid
);
1440 DEBUG(5, ("pol_sid: %s\n", tmp
));
1442 if (num_rids
> MAX_SAM_ENTRIES
)
1444 num_rids
= MAX_SAM_ENTRIES
;
1446 ("samr_lookup_names: truncating entries to %d\n",
1450 for (i
= 0; i
< num_rids
; i
++)
1455 unistr2_to_ascii(name
, &uni_name
[i
], sizeof(name
) - 1);
1458 status1
= lookup_name(name
, &sid
, &(type
[i
]));
1462 sid_split_rid(&sid
, &rid
[i
]);
1463 sid_to_string(tmp
, &sid
);
1465 if ((status1
!= 0x0) || !sid_equal(&pol_sid
, &sid
))
1467 rid
[i
] = 0xffffffff;
1468 type
[i
] = SID_NAME_UNKNOWN
;
1471 DEBUG(10, ("name: %s sid: %s rid: %x type: %d\n",
1472 name
, tmp
, rid
[i
], type
[i
]));
1477 return NT_STATUS_NONE_MAPPED
;
1480 (*num_rids1
) = num_rids
;
1481 (*num_types1
) = num_rids
;
1483 return NT_STATUS_NOPROBLEMO
;
1486 /*******************************************************************
1487 samr_reply_chgpasswd_user
1488 ********************************************************************/
1489 uint32
_samr_chgpasswd_user(const UNISTR2
* uni_dest_host
,
1490 const UNISTR2
* uni_user_name
,
1491 const char nt_newpass
[516],
1492 const uchar nt_oldhash
[16],
1493 const char lm_newpass
[516],
1494 const uchar lm_oldhash
[16])
1499 unistr2_to_ascii(user_name
, uni_user_name
, sizeof(user_name
) - 1);
1500 unistr2_to_ascii(wks
, uni_dest_host
, sizeof(wks
) - 1);
1502 DEBUG(5, ("samr_chgpasswd_user: user: %s wks: %s\n", user_name
, wks
));
1504 if (!pass_oem_change(user_name
,
1505 lm_newpass
, lm_oldhash
, nt_newpass
, nt_oldhash
))
1507 return NT_STATUS_WRONG_PASSWORD
;
1510 return NT_STATUS_NOPROBLEMO
;
1514 /*******************************************************************
1515 samr_reply_get_dom_pwinfo
1516 ********************************************************************/
1517 uint32
_samr_get_dom_pwinfo(const UNISTR2
* uni_srv_name
,
1518 uint16
* unk_0
, uint16
* unk_1
, uint16
* unk_2
)
1520 /* absolutely no idea what to do, here */
1525 return NT_STATUS_NOPROBLEMO
;
1528 /*******************************************************************
1529 makes a SAMR_R_LOOKUP_RIDS structure.
1530 ********************************************************************/
1531 static BOOL
make_samr_lookup_rids(uint32 num_names
, char *const *name
,
1532 UNIHDR
** hdr_name
, UNISTR2
** uni_name
)
1543 (*hdr_name
) = g_new(UNIHDR
, num_names
);
1544 if ((*hdr_name
) == NULL
)
1549 (*uni_name
) = g_new(UNISTR2
, num_names
);
1550 if ((*uni_name
) == NULL
)
1558 for (i
= 0; i
< num_names
; i
++)
1560 int len
= name
[i
] != NULL
? strlen(name
[i
]) : 0;
1561 DEBUG(10, ("name[%d]:%s\n", i
, name
[i
]));
1562 make_uni_hdr(&((*hdr_name
)[i
]), len
);
1563 make_unistr2(&((*uni_name
)[i
]), name
[i
], len
);
1569 /*******************************************************************
1570 samr_reply_lookup_rids
1571 ********************************************************************/
1572 uint32
_samr_lookup_rids(const POLICY_HND
* pol
,
1573 uint32 num_rids
, uint32 flags
,
1574 const uint32
* rids
,
1576 UNIHDR
** hdr_name
, UNISTR2
** uni_name
,
1579 char **grp_names
= NULL
;
1581 BOOL found_one
= False
;
1584 DEBUG(5, ("samr_lookup_rids: %d\n", __LINE__
));
1586 /* find the policy handle. open a policy on it. */
1587 if (find_policy_by_hnd(get_global_hnd_cache(), pol
) == -1)
1589 return NT_STATUS_INVALID_HANDLE
;
1592 if (!get_policy_samr_sid(get_global_hnd_cache(), pol
, &pol_sid
))
1594 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
1597 (*types
) = g_new(uint32
, num_rids
);
1599 if ((*types
) == NULL
)
1601 return NT_STATUS_NO_MEMORY
;
1604 grp_names
= g_new(char *, num_rids
);
1605 if (grp_names
== NULL
)
1609 return NT_STATUS_NO_MEMORY
;
1613 for (i
= 0; i
< num_rids
; i
++)
1619 sid_copy(&sid
, &pol_sid
);
1620 sid_append_rid(&sid
, rids
[i
]);
1622 status1
= lookup_sid(&sid
, tmpname
, &(*types
)[i
]);
1627 grp_names
[i
] = strdup(tmpname
);
1631 (*types
)[i
] = SID_NAME_UNKNOWN
;
1632 grp_names
[i
] = NULL
;
1638 return NT_STATUS_NONE_MAPPED
;
1641 (*num_names
) = num_rids
;
1642 make_samr_lookup_rids(num_rids
, grp_names
, hdr_name
, uni_name
);
1644 free_char_array(num_rids
, grp_names
);
1645 return NT_STATUS_NOPROBLEMO
;
1648 /*******************************************************************
1649 samr_reply_open_user
1650 ********************************************************************/
1651 uint32
_samr_open_user(const POLICY_HND
* domain_pol
,
1652 uint32 access_mask
, uint32 user_rid
,
1653 POLICY_HND
* user_pol
)
1655 struct sam_passwd
*sam_pass
;
1658 /* set up the SAMR open_user response */
1659 ZERO_STRUCTP(user_pol
);
1661 /* find the policy handle. open a policy on it. */
1662 if (!get_policy_samr_sid(get_global_hnd_cache(), domain_pol
, &sid
))
1664 return NT_STATUS_INVALID_HANDLE
;
1667 /* this should not be hard-coded like this */
1668 if (!sid_equal(&sid
, &global_sam_sid
))
1670 return NT_STATUS_ACCESS_DENIED
;
1674 sam_pass
= getsam21pwrid(user_rid
);
1675 unbecome_root(True
);
1677 /* check that the RID exists in our domain. */
1678 if (sam_pass
== NULL
)
1680 close_policy_hnd(get_global_hnd_cache(), user_pol
);
1681 return NT_STATUS_NO_SUCH_USER
;
1684 return samr_open_by_sid(domain_pol
, &sid
, user_pol
,
1685 access_mask
, user_rid
);
1689 /*************************************************************************
1691 *************************************************************************/
1692 static BOOL
get_user_info_10(SAM_USER_INFO_10
* id10
, uint32 user_rid
)
1694 struct sam_passwd
*sam_pass
;
1697 sam_pass
= getsam21pwrid(user_rid
);
1698 unbecome_root(True
);
1700 if (sam_pass
== NULL
)
1702 DEBUG(4, ("User 0x%x not found\n", user_rid
));
1706 DEBUG(3, ("User:[%s]\n", sam_pass
->nt_name
));
1708 make_sam_user_info10(id10
, sam_pass
->acct_ctrl
);
1713 /*************************************************************************
1715 *************************************************************************/
1716 static BOOL
get_user_info_12(SAM_USER_INFO_12
* id12
, uint32 user_rid
)
1718 struct sam_passwd
*sam_pass
;
1721 sam_pass
= getsam21pwrid(user_rid
);
1722 unbecome_root(True
);
1724 if (sam_pass
== NULL
)
1726 DEBUG(4, ("User 0x%x not found\n", user_rid
));
1730 DEBUG(3, ("User:[%s] %x\n", sam_pass
->nt_name
, sam_pass
->acct_ctrl
));
1732 if (IS_BITS_SET_ALL(sam_pass
->acct_ctrl
, ACB_DISABLED
))
1737 make_sam_user_info12(id12
, sam_pass
->smb_passwd
,
1738 sam_pass
->smb_nt_passwd
);
1743 /*************************************************************************
1745 *************************************************************************/
1746 static BOOL
get_user_info_21(SAM_USER_INFO_21
* id21
, uint32 user_rid
)
1748 struct sam_passwd
*sam_pass
;
1753 sam_pass
= getsam21pwrid(user_rid
);
1754 unbecome_root(True
);
1756 if (sam_pass
== NULL
)
1758 DEBUG(4, ("User 0x%x not found\n", user_rid
));
1762 DEBUG(3, ("User:[%s]\n", sam_pass
->nt_name
));
1764 /* create a LOGON_HRS structure */
1765 hrs
.len
= sam_pass
->hours_len
;
1766 SMB_ASSERT_ARRAY(hrs
.hours
, hrs
.len
);
1767 for (i
= 0; i
< hrs
.len
; i
++)
1769 hrs
.hours
[i
] = sam_pass
->hours
[i
];
1772 make_sam_user_info21A(id21
, &sam_pass
->logon_time
,
1773 &sam_pass
->logoff_time
,
1774 &sam_pass
->kickoff_time
,
1775 &sam_pass
->pass_last_set_time
,
1776 &sam_pass
->pass_can_change_time
,
1777 &sam_pass
->pass_must_change_time
,
1778 sam_pass
->nt_name
, /* user_name */
1779 sam_pass
->full_name
, /* full_name */
1780 sam_pass
->home_dir
, /* home_dir */
1781 sam_pass
->dir_drive
, /* dir_drive */
1782 sam_pass
->logon_script
, /* logon_script */
1783 sam_pass
->profile_path
, /* profile_path */
1784 sam_pass
->acct_desc
, /* description */
1785 sam_pass
->workstations
, /* workstations user can log in from */
1786 sam_pass
->unknown_str
, /* don't know, yet */
1787 sam_pass
->munged_dial
, /* dialin info. contains dialin path and tel no */
1788 sam_pass
->user_rid
, /* RID user_id */
1789 sam_pass
->group_rid
, /* RID group_id */
1790 sam_pass
->acct_ctrl
, sam_pass
->unknown_3
, /* unknown_3 */
1791 sam_pass
->logon_divs
, /* divisions per week */
1792 &hrs
, /* logon hours */
1793 sam_pass
->unknown_5
, sam_pass
->unknown_6
);
1798 /*******************************************************************
1799 samr_reply_query_userinfo
1800 ********************************************************************/
1801 uint32
_samr_query_userinfo(const POLICY_HND
* pol
, uint16 switch_value
,
1802 SAM_USERINFO_CTR
* ctr
)
1807 /* find the policy handle. open a policy on it. */
1808 if (!get_policy_samr_sid(get_global_hnd_cache(), pol
, &group_sid
))
1810 return NT_STATUS_INVALID_HANDLE
;
1812 sid_split_rid(&group_sid
, &rid
);
1814 DEBUG(5, ("samr_reply_query_userinfo: rid:0x%x\n", rid
));
1816 /* ok! user info levels (lots: see MSDEV help), off we go... */
1817 ctr
->switch_value
= switch_value
;
1818 switch (switch_value
)
1822 ctr
->info
.id10
= g_new(SAM_USER_INFO_10
, 1);
1823 if (ctr
->info
.id10
== NULL
)
1825 return NT_STATUS_NO_MEMORY
;
1827 if (!get_user_info_10(ctr
->info
.id10
, rid
))
1829 return NT_STATUS_NO_SUCH_USER
;
1834 /* whoops - got this wrong. i think. or don't understand what's happening. */
1838 info
= (void *)&id11
;
1840 expire
.low
= 0xffffffff;
1841 expire
.high
= 0x7fffffff;
1843 ctr
->info
.id
= (SAM_USER_INFO_11
*) Realloc(NULL
,
1848 make_sam_user_info11(ctr
->info
.id11
, &expire
,
1849 "BROOKFIELDS$", /* name */
1850 0x03ef, /* user rid */
1851 0x201, /* group rid */
1852 0x0080); /* acb info */
1859 ctr
->info
.id12
= g_new(SAM_USER_INFO_12
, 1);
1860 if (ctr
->info
.id12
== NULL
)
1862 return NT_STATUS_NO_MEMORY
;
1864 if (!get_user_info_12(ctr
->info
.id12
, rid
))
1866 return NT_STATUS_NO_SUCH_USER
;
1872 ctr
->info
.id21
= g_new(SAM_USER_INFO_21
, 1);
1873 if (ctr
->info
.id21
== NULL
)
1875 return NT_STATUS_NO_MEMORY
;
1877 if (!get_user_info_21(ctr
->info
.id21
, rid
))
1879 return NT_STATUS_NO_SUCH_USER
;
1886 return NT_STATUS_INVALID_INFO_CLASS
;
1890 return NT_STATUS_NOPROBLEMO
;
1893 /*******************************************************************
1895 ********************************************************************/
1896 static BOOL
set_user_info_12(const SAM_USER_INFO_12
* id12
, uint32 rid
)
1898 struct sam_passwd
*pwd
= getsam21pwrid(rid
);
1899 struct sam_passwd new_pwd
;
1900 static uchar nt_hash
[16];
1901 static uchar lm_hash
[16];
1909 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
1913 pwdb_init_sam(&new_pwd
);
1914 copy_sam_passwd(&new_pwd
, pwd
);
1916 memcpy(nt_hash
, id12
->nt_pwd
, sizeof(nt_hash
));
1917 memcpy(lm_hash
, id12
->lm_pwd
, sizeof(lm_hash
));
1919 new_pwd
.smb_passwd
= lm_hash
;
1920 new_pwd
.smb_nt_passwd
= nt_hash
;
1922 return mod_sam21pwd_entry(&new_pwd
, True
);
1925 /*******************************************************************
1927 ********************************************************************/
1928 static BOOL
set_user_info_24(const SAM_USER_INFO_24
* id24
, uint32 rid
)
1930 struct sam_passwd
*pwd
= getsam21pwrid(rid
);
1931 struct sam_passwd new_pwd
;
1932 static uchar nt_hash
[16];
1933 static uchar lm_hash
[16];
1944 pwdb_init_sam(&new_pwd
);
1945 copy_sam_passwd(&new_pwd
, pwd
);
1947 if (!decode_pw_buffer(id24
->pass
, buf
, 256, &len
))
1952 dump_data_pw("decoded password buffer:\n", buf
, 516);
1954 new_pw
.uni_max_len
= len
/ 2;
1955 new_pw
.uni_str_len
= len
/ 2;
1957 for (i
= 0; i
< new_pw
.uni_str_len
; i
++)
1959 new_pw
.buffer
[i
] = SVAL(buf
, i
* 2);
1962 dump_data_pw("unicode password:\n", (char*)new_pw
.buffer
, len
);
1964 nt_lm_owf_genW(&new_pw
, nt_hash
, lm_hash
);
1966 dump_data_pw("nt#:\n", nt_hash
, 16);
1967 dump_data_pw("lm#:\n", lm_hash
, 16);
1969 new_pwd
.smb_passwd
= lm_hash
;
1970 new_pwd
.smb_nt_passwd
= nt_hash
;
1972 return mod_sam21pwd_entry(&new_pwd
, True
);
1975 /*******************************************************************
1977 ********************************************************************/
1978 static BOOL
set_user_info_21(const SAM_USER_INFO_21
* id21
, uint32 rid
)
1980 struct sam_passwd
*pwd
= getsam21pwrid(rid
);
1981 struct sam_passwd new_pwd
;
1982 static uchar nt_hash
[16];
1983 static uchar lm_hash
[16];
1987 DEBUG(5, ("set_user_info_21: NULL id21\n"));
1995 pwdb_init_sam(&new_pwd
);
1996 copy_sam_passwd(&new_pwd
, pwd
);
1997 copy_id21_to_sam_passwd(&new_pwd
, id21
);
1999 if (pwd
->smb_nt_passwd
!= NULL
)
2001 memcpy(nt_hash
, pwd
->smb_nt_passwd
, 16);
2002 new_pwd
.smb_nt_passwd
= nt_hash
;
2006 new_pwd
.smb_nt_passwd
= NULL
;
2008 if (pwd
->smb_nt_passwd
!= NULL
)
2010 memcpy(lm_hash
, pwd
->smb_passwd
, 16);
2011 new_pwd
.smb_passwd
= lm_hash
;
2015 new_pwd
.smb_passwd
= NULL
;
2018 return mod_sam21pwd_entry(&new_pwd
, True
);
2021 /*******************************************************************
2023 ********************************************************************/
2024 static BOOL
set_user_info_23(const SAM_USER_INFO_23
* id23
, uint32 rid
)
2026 struct sam_passwd
*pwd
= getsam21pwrid(rid
);
2027 struct sam_passwd new_pwd
;
2028 static uchar nt_hash
[16];
2029 static uchar lm_hash
[16];
2037 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2045 pwdb_init_sam(&new_pwd
);
2046 copy_sam_passwd(&new_pwd
, pwd
);
2047 copy_id23_to_sam_passwd(&new_pwd
, id23
);
2049 if (!decode_pw_buffer(id23
->pass
, buf
, 256, &len
))
2054 new_pw
.uni_max_len
= len
/ 2;
2055 new_pw
.uni_str_len
= len
/ 2;
2057 for (i
= 0; i
< new_pw
.uni_str_len
; i
++)
2059 new_pw
.buffer
[i
] = SVAL(buf
, i
* 2);
2062 nt_lm_owf_genW(&new_pw
, nt_hash
, lm_hash
);
2064 new_pwd
.smb_passwd
= lm_hash
;
2065 new_pwd
.smb_nt_passwd
= nt_hash
;
2067 return mod_sam21pwd_entry(&new_pwd
, True
);
2070 /*******************************************************************
2071 samr_reply_set_userinfo
2072 ********************************************************************/
2073 uint32
_samr_set_userinfo(const POLICY_HND
* pol
, uint16 switch_value
,
2074 SAM_USERINFO_CTR
* ctr
)
2076 uchar user_sess_key
[16];
2080 DEBUG(5, ("samr_reply_set_userinfo: %d\n", __LINE__
));
2082 /* search for the handle */
2083 if (find_policy_by_hnd(get_global_hnd_cache(), pol
) == -1)
2085 return NT_STATUS_INVALID_HANDLE
;
2088 if (!pol_get_usr_sesskey(get_global_hnd_cache(), pol
, user_sess_key
))
2090 return NT_STATUS_INVALID_HANDLE
;
2093 /* find the policy handle. open a policy on it. */
2094 if (!get_policy_samr_sid(get_global_hnd_cache(), pol
, &sid
))
2096 return NT_STATUS_INVALID_HANDLE
;
2099 sid_split_rid(&sid
, &rid
);
2101 DEBUG(5, ("samr_reply_set_userinfo: rid:0x%x\n", rid
));
2105 DEBUG(5, ("samr_reply_set_userinfo: NULL info level\n"));
2106 return NT_STATUS_INVALID_INFO_CLASS
;
2109 /* ok! user info levels (lots: see MSDEV help), off we go... */
2110 switch (switch_value
)
2114 SAM_USER_INFO_12
*id12
= ctr
->info
.id12
;
2115 if (!set_user_info_12(id12
, rid
))
2117 return NT_STATUS_ACCESS_DENIED
;
2124 SAM_USER_INFO_24
*id24
= ctr
->info
.id24
;
2125 SamOEMhash(id24
->pass
, user_sess_key
, True
);
2126 if (!set_user_info_24(id24
, rid
))
2128 return NT_STATUS_ACCESS_DENIED
;
2135 SAM_USER_INFO_23
*id23
= ctr
->info
.id23
;
2136 SamOEMhash(id23
->pass
, user_sess_key
, 1);
2137 dump_data_pw("pass buff:\n", id23
->pass
,
2138 sizeof(id23
->pass
));
2141 if (!set_user_info_23(id23
, rid
))
2143 return NT_STATUS_ACCESS_DENIED
;
2150 return NT_STATUS_INVALID_INFO_CLASS
;
2154 return NT_STATUS_NOPROBLEMO
;
2157 /*******************************************************************
2159 ********************************************************************/
2160 static BOOL
set_user_info_10(const SAM_USER_INFO_10
* id10
, uint32 rid
)
2162 struct sam_passwd
*pwd
= getsam21pwrid(rid
);
2163 struct sam_passwd new_pwd
;
2167 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2175 copy_sam_passwd(&new_pwd
, pwd
);
2177 new_pwd
.acct_ctrl
= id10
->acb_info
;
2179 return mod_sam21pwd_entry(&new_pwd
, True
);
2182 /*******************************************************************
2183 samr_reply_set_userinfo2
2184 ********************************************************************/
2185 uint32
_samr_set_userinfo2(const POLICY_HND
* pol
, uint16 switch_value
,
2186 SAM_USERINFO_CTR
* ctr
)
2191 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__
));
2193 /* find the policy handle. open a policy on it. */
2194 if (!get_policy_samr_sid(get_global_hnd_cache(), pol
, &sid
))
2196 return NT_STATUS_INVALID_HANDLE
;
2199 sid_split_rid(&sid
, &rid
);
2201 DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid
));
2205 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
2206 return NT_STATUS_INVALID_INFO_CLASS
;
2209 ctr
->switch_value
= switch_value
;
2211 /* ok! user info levels (lots: see MSDEV help), off we go... */
2212 switch (switch_value
)
2216 SAM_USER_INFO_21
*id21
= ctr
->info
.id21
;
2217 if (!set_user_info_21(id21
, rid
))
2219 return NT_STATUS_ACCESS_DENIED
;
2225 SAM_USER_INFO_10
*id10
= ctr
->info
.id10
;
2226 if (!set_user_info_10(id10
, rid
))
2228 return NT_STATUS_ACCESS_DENIED
;
2234 return NT_STATUS_INVALID_INFO_CLASS
;
2238 return NT_STATUS_NOPROBLEMO
;
2243 /*******************************************************************
2244 samr_reply_query_usergroups
2245 ********************************************************************/
2246 uint32
_samr_query_usergroups(const POLICY_HND
* pol
,
2247 uint32
* num_groups
, DOM_GID
** gids
)
2249 DOMAIN_GRP
*mem_grp
= NULL
;
2250 struct sam_passwd
*sam_pass
;
2255 DEBUG(5, ("samr_query_usergroups: %d\n", __LINE__
));
2257 /* find the policy handle. open a policy on it. */
2258 if (!get_policy_samr_sid(get_global_hnd_cache(), pol
, &sid
))
2260 return NT_STATUS_INVALID_HANDLE
;
2263 sid_split_rid(&sid
, &rid
);
2266 sam_pass
= getsam21pwrid(rid
);
2267 unbecome_root(True
);
2269 if (sam_pass
== NULL
)
2271 return NT_STATUS_NO_SUCH_USER
;
2275 ret
= getusergroupsntnam(sam_pass
->nt_name
, &mem_grp
, num_groups
);
2276 unbecome_root(True
);
2280 return NT_STATUS_ACCESS_DENIED
;
2284 (*num_groups
) = make_dom_gids(mem_grp
, *num_groups
, gids
);
2286 if (mem_grp
!= NULL
)
2291 return NT_STATUS_NOPROBLEMO
;
2294 /*******************************************************************
2295 _samr_create_dom_alias
2296 ********************************************************************/
2297 uint32
_samr_create_dom_alias(const POLICY_HND
* domain_pol
,
2298 const UNISTR2
* uni_acct_name
,
2300 POLICY_HND
* alias_pol
, uint32
* rid
)
2306 ZERO_STRUCTP(alias_pol
);
2308 /* find the policy handle. open a policy on it. */
2309 if (find_policy_by_hnd(get_global_hnd_cache(), domain_pol
) == -1)
2311 return NT_STATUS_INVALID_HANDLE
;
2314 /* find the domain sid */
2315 if (!get_policy_samr_sid(get_global_hnd_cache(),
2316 domain_pol
, &dom_sid
))
2318 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
2321 if (!sid_equal(&dom_sid
, &global_sam_sid
))
2323 return NT_STATUS_ACCESS_DENIED
;
2326 unistr2_to_ascii(grp
.name
, uni_acct_name
, sizeof(grp
.name
) - 1);
2327 fstrcpy(grp
.comment
, "");
2328 *rid
= grp
.rid
= 0xffffffff;
2331 status
= samr_open_by_sid(domain_pol
, &dom_sid
, alias_pol
,
2332 access_mask
, grp
.rid
);
2339 if (!add_alias_entry(&grp
))
2341 return NT_STATUS_ACCESS_DENIED
;
2344 return NT_STATUS_NOPROBLEMO
;
2347 /*******************************************************************
2348 _samr_create_dom_group
2349 ********************************************************************/
2350 uint32
_samr_create_dom_group(const POLICY_HND
* domain_pol
,
2351 const UNISTR2
* uni_acct_name
,
2353 POLICY_HND
* group_pol
, uint32
* rid
)
2359 ZERO_STRUCTP(group_pol
);
2361 /* find the policy handle. open a policy on it. */
2362 if (find_policy_by_hnd(get_global_hnd_cache(), domain_pol
) == -1)
2364 return NT_STATUS_INVALID_HANDLE
;
2367 /* find the domain sid */
2368 if (!get_policy_samr_sid(get_global_hnd_cache(),
2369 domain_pol
, &dom_sid
))
2371 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
2374 if (!sid_equal(&dom_sid
, &global_sam_sid
))
2376 return NT_STATUS_ACCESS_DENIED
;
2379 unistr2_to_ascii(grp
.name
, uni_acct_name
, sizeof(grp
.name
) - 1);
2380 fstrcpy(grp
.comment
, "");
2381 *rid
= grp
.rid
= 0xffffffff;
2385 status
= samr_open_by_sid(domain_pol
, &dom_sid
, group_pol
,
2386 access_mask
, grp
.rid
);
2392 if (!add_group_entry(&grp
))
2394 return NT_STATUS_ACCESS_DENIED
;
2397 return NT_STATUS_NOPROBLEMO
;
2400 /*******************************************************************
2401 _samr_query_dom_info
2402 ********************************************************************/
2403 uint32
_samr_query_dom_info(const POLICY_HND
* domain_pol
,
2404 uint16 switch_value
, SAM_UNK_CTR
* ctr
)
2406 /* find the policy handle. open a policy on it. */
2407 if (find_policy_by_hnd(get_global_hnd_cache(), domain_pol
) == -1)
2409 DEBUG(5, ("samr_reply_query_dom_info: invalid handle\n"));
2410 return NT_STATUS_INVALID_HANDLE
;
2413 switch (switch_value
)
2417 make_unk_info12(&(ctr
->info
.inf12
));
2422 make_unk_info7(&(ctr
->info
.inf7
));
2427 make_unk_info6(&(ctr
->info
.inf6
));
2432 make_unk_info3(&(ctr
->info
.inf3
));
2437 extern fstring global_sam_name
;
2438 extern pstring global_myname
;
2439 make_unk_info2(&(ctr
->info
.inf2
), global_sam_name
,
2445 make_unk_info1(&(ctr
->info
.inf1
));
2450 return NT_STATUS_INVALID_INFO_CLASS
;
2454 return NT_STATUS_NOPROBLEMO
;
2457 /*******************************************************************
2459 ********************************************************************/
2460 uint32
_samr_create_user(const POLICY_HND
* domain_pol
,
2461 const UNISTR2
* uni_username
,
2462 uint16 acb_info
, uint32 access_mask
,
2463 POLICY_HND
* user_pol
,
2464 uint32
* unknown_0
, uint32
* user_rid
)
2468 struct sam_passwd
*sam_pass
;
2473 (*unknown_0
) = 0x30;
2476 /* find the machine account: tell the caller if it exists.
2477 lkclXXXX i have *no* idea if this is a problem or not
2478 or even if you are supposed to construct a different
2479 reply if the account already exists...
2482 /* find the domain sid associated with the policy handle */
2483 if (!get_policy_samr_sid(get_global_hnd_cache(), domain_pol
, &sid
))
2485 return NT_STATUS_INVALID_HANDLE
;
2487 if (!sid_equal(&sid
, &global_sam_sid
))
2489 return NT_STATUS_ACCESS_DENIED
;
2492 unistr2_to_ascii(user_name
, uni_username
, sizeof(user_name
) - 1);
2494 sam_pass
= getsam21pwntnam(user_name
);
2496 if (sam_pass
!= NULL
)
2498 /* account exists: say so */
2499 return NT_STATUS_USER_EXISTS
;
2502 if (!local_password_change(user_name
, True
,
2503 acb_info
| ACB_DISABLED
| ACB_PWNOTREQ
,
2504 0xffff, NULL
, err_str
, sizeof(err_str
),
2505 msg_str
, sizeof(msg_str
)))
2507 DEBUG(0, ("%s\n", err_str
));
2508 return NT_STATUS_ACCESS_DENIED
;
2511 sam_pass
= getsam21pwntnam(user_name
);
2512 if (sam_pass
== NULL
)
2514 /* account doesn't exist: say so */
2515 return NT_STATUS_ACCESS_DENIED
;
2518 *unknown_0
= 0x000703ff;
2519 *user_rid
= sam_pass
->user_rid
;
2521 return samr_open_by_sid(domain_pol
, &sid
, user_pol
,
2522 access_mask
, *user_rid
);
2525 /*******************************************************************
2527 ********************************************************************/
2528 uint32
_samr_connect_anon(const UNISTR2
* srv_name
, uint32 access_mask
,
2529 POLICY_HND
* connect_pol
)
2531 /* get a (unique) handle. open a policy on it. */
2532 if (!open_policy_hnd(get_global_hnd_cache(),
2533 get_sec_ctx(), connect_pol
, access_mask
))
2535 return NT_STATUS_ACCESS_DENIED
;
2538 policy_hnd_set_name(get_global_hnd_cache(),
2539 connect_pol
, "sam_connect_anon");
2541 return NT_STATUS_NOPROBLEMO
;
2544 /*******************************************************************
2546 ********************************************************************/
2547 uint32
_samr_connect(const UNISTR2
* srv_name
, uint32 access_mask
,
2548 POLICY_HND
* connect_pol
)
2550 /* get a (unique) handle. open a policy on it. */
2551 if (!open_policy_hnd(get_global_hnd_cache(),
2552 get_sec_ctx(), connect_pol
, access_mask
))
2554 return NT_STATUS_ACCESS_DENIED
;
2557 policy_hnd_set_name(get_global_hnd_cache(),
2558 connect_pol
, "sam_connect");
2560 return NT_STATUS_NOPROBLEMO
;
2563 /*******************************************************************
2565 ********************************************************************/
2566 uint32
_samr_open_alias(const POLICY_HND
* domain_pol
,
2567 uint32 access_mask
, uint32 alias_rid
,
2568 POLICY_HND
* alias_pol
)
2572 /* find the domain sid associated with the policy handle */
2573 if (!get_policy_samr_sid(get_global_hnd_cache(), domain_pol
, &sid
))
2575 return NT_STATUS_INVALID_HANDLE
;
2578 /* this should not be hard-coded like this */
2579 if (!sid_equal(&sid
, &global_sam_sid
) &&
2580 !sid_equal(&sid
, global_sid_builtin
))
2582 return NT_STATUS_ACCESS_DENIED
;
2585 return samr_open_by_sid(domain_pol
, &sid
, alias_pol
, access_mask
,
2589 /*******************************************************************
2591 ********************************************************************/
2592 uint32
_samr_open_group(const POLICY_HND
* domain_pol
, uint32 access_mask
,
2593 uint32 group_rid
, POLICY_HND
* group_pol
)
2597 /* find the domain sid associated with the policy handle */
2598 if (!get_policy_samr_sid(get_global_hnd_cache(), domain_pol
, &sid
))
2600 return NT_STATUS_INVALID_HANDLE
;
2603 /* this should not be hard-coded like this */
2604 if (!sid_equal(&sid
, &global_sam_sid
))
2606 return NT_STATUS_ACCESS_DENIED
;
2609 return samr_open_by_sid(domain_pol
, &sid
, group_pol
, access_mask
,
2613 /*******************************************************************
2615 ********************************************************************/
2616 uint32
_samr_lookup_domain(const POLICY_HND
* connect_pol
,
2617 const UNISTR2
* uni_domain
, DOM_SID
* dom_sid
)
2621 /* find the connection policy handle */
2622 if (find_policy_by_hnd(get_global_hnd_cache(), connect_pol
) == -1)
2624 return NT_STATUS_INVALID_HANDLE
;
2627 unistr2_to_ascii(domain
, uni_domain
, sizeof(domain
));
2628 DEBUG(5, ("Lookup Domain: %s\n", domain
));
2630 /* check it's one of ours */
2631 if (strequal(domain
, global_sam_name
))
2633 sid_copy(dom_sid
, &global_sam_sid
);
2636 else if (strequal(domain
, "BUILTIN"))
2638 sid_copy(dom_sid
, global_sid_builtin
);
2639 return NT_STATUS_NOPROBLEMO
;
2642 return NT_STATUS_NO_SUCH_DOMAIN
;
2645 BOOL
pwdbsam_initialise(void)
2647 return initialise_password_db() &&
2648 initialise_sam_password_db() &&
2649 initialise_passgrp_db() &&
2650 initialise_group_db() &&
2651 initialise_alias_db() && initialise_builtin_db();