2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2002,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
11 * Copyright (C) Gerald (Jerry) Carter 2003,
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 * This is the implementation of the SAMR code.
35 #define DBGC_CLASS DBGC_RPC_SRV
37 extern DOM_SID global_sid_Builtin;
39 extern rid_name domain_group_rids[];
40 extern rid_name domain_alias_rids[];
41 extern rid_name builtin_alias_rids[];
44 typedef struct _disp_info {
46 uint32 num_user_account;
47 SAM_ACCOUNT *disp_user_info;
49 uint32 num_group_account;
50 DOMAIN_GRP *disp_group_info;
54 /* for use by the \PIPE\samr policy */
56 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
65 struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
66 struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
67 struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
68 struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
69 struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
71 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
73 /*******************************************************************
74 Checks if access to an object should be granted, and returns that
75 level of access for further checks.
76 ********************************************************************/
78 NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_token, uint32 des_access,
79 uint32 *acc_granted, const char *debug)
81 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
83 if (!se_access_check(psd, nt_user_token, des_access, acc_granted, &status)) {
84 *acc_granted = des_access;
85 if (geteuid() == sec_initial_uid()) {
86 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n",
88 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
89 status = NT_STATUS_OK;
92 DEBUG(2,("%s: ACCESS DENIED (requested: %#010x)\n",
99 /*******************************************************************
100 Checks if access to a function can be granted
101 ********************************************************************/
103 NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
105 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
106 debug, acc_granted, acc_required));
107 if ((acc_granted & acc_required) != acc_required) {
108 if (geteuid() == sec_initial_uid()) {
109 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
110 debug, acc_granted, acc_required));
111 DEBUGADD(4,("but overwritten by euid == 0\n"));
114 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
115 debug, acc_granted, acc_required));
116 return NT_STATUS_ACCESS_DENIED;
122 /*******************************************************************
123 Create a samr_info struct.
124 ********************************************************************/
126 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
128 struct samr_info *info;
133 sid_to_string(sid_str, psid);
135 fstrcpy(sid_str,"(NULL)");
138 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
140 if ((info = TALLOC_P(mem_ctx, struct samr_info)) == NULL)
144 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
146 sid_copy( &info->sid, psid);
148 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
150 info->mem_ctx = mem_ctx;
154 /*******************************************************************
155 Function to free the per handle data.
156 ********************************************************************/
158 static void free_samr_users(struct samr_info *info)
162 if (info->disp_info.user_dbloaded){
163 for (i=0; i<info->disp_info.num_user_account; i++) {
164 SAM_ACCOUNT *sam = &info->disp_info.disp_user_info[i];
165 /* Not really a free, actually a 'clear' */
169 info->disp_info.user_dbloaded=False;
170 info->disp_info.num_user_account=0;
173 /*******************************************************************
174 Function to free the per handle data.
175 ********************************************************************/
177 static void free_samr_db(struct samr_info *info)
179 /* Groups are talloced */
181 free_samr_users(info);
183 info->disp_info.group_dbloaded=False;
184 info->disp_info.num_group_account=0;
187 static void free_samr_info(void *ptr)
189 struct samr_info *info=(struct samr_info *) ptr;
192 talloc_destroy(info->mem_ctx);
195 /*******************************************************************
196 Ensure password info is never given out. Paranioa... JRA.
197 ********************************************************************/
199 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
205 /* These now zero out the old password */
207 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
208 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
212 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL all_machines)
214 SAM_ACCOUNT *pwd = NULL;
215 SAM_ACCOUNT *pwd_array = NULL;
216 NTSTATUS nt_status = NT_STATUS_OK;
217 TALLOC_CTX *mem_ctx = info->mem_ctx;
219 DEBUG(10,("load_sampwd_entries\n"));
221 /* if the snapshoot is already loaded, return */
222 if ((info->disp_info.user_dbloaded==True)
223 && (info->acb_mask == acb_mask)
224 && (info->all_machines == all_machines)) {
225 DEBUG(10,("load_sampwd_entries: already in memory\n"));
229 free_samr_users(info);
231 if (!pdb_setsampwent(False)) {
232 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
233 return NT_STATUS_ACCESS_DENIED;
236 for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd)))
237 && pdb_getsampwent(pwd) == True; pwd=NULL) {
240 if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST)
241 || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
242 DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
247 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
249 DEBUG(5,(" acb_mask %x reject\n", acb_mask));
254 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
255 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
257 DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
258 pwd_array=TALLOC_REALLOC_ARRAY(mem_ctx, info->disp_info.disp_user_info, SAM_ACCOUNT,
259 info->disp_info.num_user_account+MAX_SAM_ENTRIES);
262 return NT_STATUS_NO_MEMORY;
264 info->disp_info.disp_user_info=pwd_array;
267 /* Copy the SAM_ACCOUNT into the array */
268 info->disp_info.disp_user_info[info->disp_info.num_user_account]=*pwd;
270 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
272 info->disp_info.num_user_account++;
277 /* the snapshoot is in memory, we're ready to enumerate fast */
279 info->acb_mask = acb_mask;
280 info->all_machines = all_machines;
281 info->disp_info.user_dbloaded=True;
283 DEBUG(10,("load_sampwd_entries: done\n"));
288 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
291 DOMAIN_GRP *grp_array = NULL;
292 uint32 group_entries = 0;
294 TALLOC_CTX *mem_ctx = info->mem_ctx;
297 DEBUG(10,("load_group_domain_entries\n"));
299 /* if the snapshoot is already loaded, return */
300 if (info->disp_info.group_dbloaded==True) {
301 DEBUG(10,("load_group_domain_entries: already in memory\n"));
305 if (sid_equal(sid, &global_sid_Builtin)) {
306 /* No domain groups for now in the BUILTIN domain */
307 info->disp_info.num_group_account=0;
308 info->disp_info.disp_group_info=NULL;
309 info->disp_info.group_dbloaded=True;
314 ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
318 DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
319 return NT_STATUS_NO_MEMORY;
323 info->disp_info.num_group_account=group_entries;
325 grp_array=TALLOC_ARRAY(mem_ctx, DOMAIN_GRP, info->disp_info.num_group_account);
326 if (group_entries!=0 && grp_array==NULL) {
327 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
329 return NT_STATUS_NO_MEMORY;
332 info->disp_info.disp_group_info=grp_array;
334 for (i=0; i<group_entries; i++) {
335 fstrcpy(grp_array[i].name, map[i].nt_name);
336 fstrcpy(grp_array[i].comment, map[i].comment);
337 sid_split_rid(&map[i].sid, &grp_array[i].rid);
338 grp_array[i].attr=SID_NAME_DOM_GRP;
343 /* the snapshoot is in memory, we're ready to enumerate fast */
345 info->disp_info.group_dbloaded=True;
347 DEBUG(10,("load_group_domain_entries: done\n"));
353 /*******************************************************************
355 ********************************************************************/
357 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
359 r_u->status = NT_STATUS_OK;
361 /* close the policy handle */
362 if (!close_policy_hnd(p, &q_u->pol))
363 return NT_STATUS_OBJECT_NAME_INVALID;
365 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
370 /*******************************************************************
371 samr_reply_open_domain
372 ********************************************************************/
374 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
376 struct samr_info *info;
377 SEC_DESC *psd = NULL;
379 uint32 des_access = q_u->flags;
383 r_u->status = NT_STATUS_OK;
385 /* find the connection policy handle. */
386 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
387 return NT_STATUS_INVALID_HANDLE;
389 if (!NT_STATUS_IS_OK(status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN,"_samr_open_domain"))) {
393 /*check if access can be granted as requested by client. */
394 samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
395 se_map_generic(&des_access,&dom_generic_mapping);
397 if (!NT_STATUS_IS_OK(status =
398 access_check_samr_object(psd, p->pipe_user.nt_user_token,
399 des_access, &acc_granted, "_samr_open_domain"))) {
403 /* associate the domain SID with the (unique) handle. */
404 if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
405 return NT_STATUS_NO_MEMORY;
406 info->acc_granted = acc_granted;
408 /* get a (unique) handle. open a policy on it. */
409 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
410 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
412 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
417 /*******************************************************************
418 _samr_get_usrdom_pwinfo
419 ********************************************************************/
421 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
423 struct samr_info *info = NULL;
425 r_u->status = NT_STATUS_OK;
427 /* find the policy handle. open a policy on it. */
428 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
429 return NT_STATUS_INVALID_HANDLE;
431 if (!sid_check_is_in_our_domain(&info->sid))
432 return NT_STATUS_OBJECT_TYPE_MISMATCH;
434 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
436 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
439 * NT sometimes return NT_STATUS_ACCESS_DENIED
440 * I don't know yet why.
446 /*******************************************************************
448 ********************************************************************/
450 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
452 extern DOM_SID global_sid_World;
461 sid_copy(&adm_sid, &global_sid_Builtin);
462 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
464 sid_copy(&act_sid, &global_sid_Builtin);
465 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
467 /*basic access for every one*/
468 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
469 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
471 /*full access for builtin aliases Administrators and Account Operators*/
472 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS);
473 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
474 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
476 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
477 return NT_STATUS_NO_MEMORY;
479 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
480 return NT_STATUS_NO_MEMORY;
485 /*******************************************************************
487 ********************************************************************/
489 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
491 extern DOM_SID global_sid_World;
500 sid_copy(&adm_sid, &global_sid_Builtin);
501 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
503 sid_copy(&act_sid, &global_sid_Builtin);
504 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
506 /*basic access for every one*/
507 init_sec_access(&mask, GENERIC_RIGHTS_USER_EXECUTE | GENERIC_RIGHTS_USER_READ);
508 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
510 /*full access for builtin aliases Administrators and Account Operators*/
511 init_sec_access(&mask, GENERIC_RIGHTS_USER_ALL_ACCESS);
512 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
513 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
515 /*extended access for the user*/
516 init_sec_access(&mask,READ_CONTROL_ACCESS | SA_RIGHT_USER_CHANGE_PASSWORD | SA_RIGHT_USER_SET_LOC_COM);
517 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
519 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
520 return NT_STATUS_NO_MEMORY;
522 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
523 return NT_STATUS_NO_MEMORY;
528 /*******************************************************************
530 ********************************************************************/
532 static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
534 extern DOM_SID global_sid_World;
543 sid_copy(&adm_sid, &global_sid_Builtin);
544 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
546 sid_copy(&act_sid, &global_sid_Builtin);
547 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
549 /*basic access for every one*/
550 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
551 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
553 /*full access for builtin aliases Administrators and Account Operators*/
554 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_ALL_ACCESS);
555 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
556 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
558 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
559 return NT_STATUS_NO_MEMORY;
561 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
562 return NT_STATUS_NO_MEMORY;
567 /*******************************************************************
569 ********************************************************************/
571 static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
573 extern DOM_SID global_sid_World;
582 sid_copy(&adm_sid, &global_sid_Builtin);
583 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
585 sid_copy(&act_sid, &global_sid_Builtin);
586 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
588 /*basic access for every one*/
589 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
590 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
592 /*full access for builtin aliases Administrators and Account Operators*/
593 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_ALL_ACCESS);
594 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
595 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
597 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
598 return NT_STATUS_NO_MEMORY;
600 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
601 return NT_STATUS_NO_MEMORY;
606 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
608 struct samr_info *info = NULL;
610 /* find the policy handle. open a policy on it. */
611 if (!find_policy_by_hnd(p, pol, (void **)&info))
618 *acc_granted = info->acc_granted;
622 /*******************************************************************
624 ********************************************************************/
626 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
628 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
629 return NT_STATUS_NOT_IMPLEMENTED;
633 /*******************************************************************
635 ********************************************************************/
637 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
641 SEC_DESC * psd = NULL;
645 r_u->status = NT_STATUS_OK;
648 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
649 return NT_STATUS_INVALID_HANDLE;
653 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
655 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
657 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
658 if (pol_sid.sid_rev_num == 0)
660 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
661 r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
663 else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */
666 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
667 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
669 else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */
671 /* TODO: Builtin probably needs a different SD with restricted write access*/
672 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
673 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
675 else if (sid_check_is_in_our_domain(&pol_sid) ||
676 sid_check_is_in_builtin(&pol_sid))
678 /* TODO: different SDs have to be generated for aliases groups and users.
679 Currently all three get a default user SD */
680 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
681 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
683 else return NT_STATUS_OBJECT_TYPE_MISMATCH;
685 if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
686 return NT_STATUS_NO_MEMORY;
688 if (NT_STATUS_IS_OK(r_u->status))
694 /*******************************************************************
695 makes a SAM_ENTRY / UNISTR2* structure from a user list.
696 ********************************************************************/
698 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
699 uint32 num_entries, uint32 start_idx, SAM_ACCOUNT *disp_user_info,
705 SAM_ACCOUNT *pwd = NULL;
706 UNISTR2 uni_temp_name;
707 const char *temp_name;
708 const DOM_SID *user_sid;
710 fstring user_sid_string;
711 fstring domain_sid_string;
716 if (num_entries == 0)
719 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_entries);
721 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_entries);
723 if (sam == NULL || uni_name == NULL) {
724 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
725 return NT_STATUS_NO_MEMORY;
728 for (i = 0; i < num_entries; i++) {
729 pwd = &disp_user_info[i+start_idx];
730 temp_name = pdb_get_username(pwd);
733 * usrmgr expects a non-NULL terminated string with
734 * trust relationships
736 if (pdb_get_acct_ctrl(pwd) & ACB_DOMTRUST) {
737 init_unistr2(&uni_temp_name, temp_name, UNI_FLAGS_NONE);
739 init_unistr2(&uni_temp_name, temp_name, UNI_STR_TERMINATE);
742 user_sid = pdb_get_user_sid(pwd);
744 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
745 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
746 "the domain sid %s. Failing operation.\n",
748 sid_to_string(user_sid_string, user_sid),
749 sid_to_string(domain_sid_string, domain_sid)));
750 return NT_STATUS_UNSUCCESSFUL;
753 init_sam_entry(&sam[i], &uni_temp_name, user_rid);
754 copy_unistr2(&uni_name[i], &uni_temp_name);
758 *uni_name_pp = uni_name;
762 /*******************************************************************
763 samr_reply_enum_dom_users
764 ********************************************************************/
766 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
767 SAMR_R_ENUM_DOM_USERS *r_u)
769 struct samr_info *info = NULL;
770 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
772 uint32 enum_context=q_u->start_idx;
773 uint32 max_size=q_u->max_size;
775 enum remote_arch_types ra_type = get_remote_arch();
776 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
777 uint32 max_entries = max_sam_entries;
780 r_u->status = NT_STATUS_OK;
782 /* find the policy handle. open a policy on it. */
783 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
784 return NT_STATUS_INVALID_HANDLE;
786 domain_sid = info->sid;
788 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
789 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
790 "_samr_enum_dom_users"))) {
794 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
797 r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
800 if (!NT_STATUS_IS_OK(r_u->status))
803 num_account = info->disp_info.num_user_account;
805 if (enum_context > num_account) {
806 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
810 /* verify we won't overflow */
811 if (max_entries > num_account-enum_context) {
812 max_entries = num_account-enum_context;
813 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
816 /* calculate the size and limit on the number of entries we will return */
817 temp_size=max_entries*struct_size;
819 if (temp_size>max_size) {
820 max_entries=MIN((max_size/struct_size),max_entries);;
821 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
825 * Note from JRA. total_entries is not being used here. Currently if there is a
826 * large user base then it looks like NT will enumerate until get_sampwd_entries
827 * returns False due to num_entries being zero. This will cause an access denied
828 * return. I don't think this is right and needs further investigation. Note that
829 * this is also the same in the TNG code (I don't think that has been tested with
830 * a very large user list as MAX_SAM_ENTRIES is set to 600).
832 * I also think that one of the 'num_entries' return parameters is probably
833 * the "max entries" parameter - but in the TNG code they're all currently set to the same
834 * value (again I think this is wrong).
837 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
838 max_entries, enum_context,
839 info->disp_info.disp_user_info,
842 if (!NT_STATUS_IS_OK(r_u->status))
845 if (enum_context+max_entries < num_account)
846 r_u->status = STATUS_MORE_ENTRIES;
848 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
850 init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
852 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
857 /*******************************************************************
858 makes a SAM_ENTRY / UNISTR2* structure from a group list.
859 ********************************************************************/
861 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
862 uint32 num_sam_entries, DOMAIN_GRP *grp)
871 if (num_sam_entries == 0)
874 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
875 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
877 if (sam == NULL || uni_name == NULL) {
878 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
882 for (i = 0; i < num_sam_entries; i++) {
884 * JRA. I think this should include the null. TNG does not.
886 init_unistr2(&uni_name[i], grp[i].name, UNI_STR_TERMINATE);
887 init_sam_entry(&sam[i], &uni_name[i], grp[i].rid);
891 *uni_name_pp = uni_name;
894 /*******************************************************************
895 Get the group entries - similar to get_sampwd_entries().
896 ******************************************************************/
898 static NTSTATUS get_group_domain_entries( TALLOC_CTX *ctx,
899 DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
900 uint32 *p_num_entries, uint32 max_entries )
904 uint32 group_entries = 0;
905 uint32 num_entries = 0;
909 /* access checks for the users were performed higher up. become/unbecome_root()
910 needed for some passdb backends to enumerate groups */
913 pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries,
917 num_entries=group_entries-start_idx;
919 /* limit the number of entries */
920 if (num_entries>max_entries) {
921 DEBUG(5,("Limiting to %d entries\n", max_entries));
922 num_entries=max_entries;
925 *d_grp=TALLOC_ZERO_ARRAY(ctx, DOMAIN_GRP, num_entries);
926 if (num_entries!=0 && *d_grp==NULL){
928 return NT_STATUS_NO_MEMORY;
931 for (i=0; i<num_entries; i++) {
932 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
933 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
934 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
935 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
940 *p_num_entries = num_entries;
942 DEBUG(10,("get_group_domain_entries: returning %d entries\n",
948 /*******************************************************************
949 Wrapper for enumerating local groups
950 ******************************************************************/
952 static NTSTATUS get_alias_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp,
953 const DOM_SID *sid, uint32 start_idx,
954 uint32 *p_num_entries, uint32 max_entries )
956 struct acct_info *info;
961 res = pdb_enum_aliases(sid, start_idx, max_entries,
962 p_num_entries, &info);
966 return NT_STATUS_ACCESS_DENIED;
968 if (*p_num_entries == 0)
971 *d_grp = TALLOC_ARRAY(ctx, DOMAIN_GRP, *p_num_entries);
973 if (*d_grp == NULL) {
975 return NT_STATUS_NO_MEMORY;
978 for (i=0; i<*p_num_entries; i++) {
979 fstrcpy((*d_grp)[i].name, info[i].acct_name);
980 fstrcpy((*d_grp)[i].comment, info[i].acct_desc);
981 (*d_grp)[i].rid = info[i].rid;
982 (*d_grp)[i].attr = SID_NAME_ALIAS;
989 /*******************************************************************
990 samr_reply_enum_dom_groups
991 ********************************************************************/
993 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
995 DOMAIN_GRP *grp=NULL;
1000 r_u->status = NT_STATUS_OK;
1002 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1003 return NT_STATUS_INVALID_HANDLE;
1005 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
1009 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1011 /* the domain group array is being allocated in the function below */
1012 if (!NT_STATUS_IS_OK(r_u->status = get_group_domain_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES))) {
1016 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1018 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
1020 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1026 /*******************************************************************
1027 samr_reply_enum_dom_aliases
1028 ********************************************************************/
1030 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1032 DOMAIN_GRP *grp=NULL;
1033 uint32 num_entries = 0;
1039 r_u->status = NT_STATUS_OK;
1041 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1042 return NT_STATUS_INVALID_HANDLE;
1044 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1048 sid_to_string(sid_str, &sid);
1049 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1051 status = get_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1052 &num_entries, MAX_SAM_ENTRIES);
1053 if (!NT_STATUS_IS_OK(status)) return status;
1055 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1059 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1061 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1066 /*******************************************************************
1067 samr_reply_query_dispinfo
1068 ********************************************************************/
1070 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1071 SAMR_R_QUERY_DISPINFO *r_u)
1073 struct samr_info *info = NULL;
1074 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1076 uint32 max_entries=q_u->max_entries;
1077 uint32 enum_context=q_u->start_idx;
1078 uint32 max_size=q_u->max_size;
1080 SAM_DISPINFO_CTR *ctr;
1081 uint32 temp_size=0, total_data_size=0;
1083 uint32 num_account = 0;
1084 enum remote_arch_types ra_type = get_remote_arch();
1085 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1088 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1089 r_u->status = NT_STATUS_OK;
1091 /* find the policy handle. open a policy on it. */
1092 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1093 return NT_STATUS_INVALID_HANDLE;
1095 domain_sid = info->sid;
1098 * calculate how many entries we will return.
1100 * - the number of entries the client asked
1101 * - our limit on that
1102 * - the starting point (enumeration context)
1103 * - the buffer size the client will accept
1107 * We are a lot more like W2K. Instead of reading the SAM
1108 * each time to find the records we need to send back,
1109 * we read it once and link that copy to the sam handle.
1110 * For large user list (over the MAX_SAM_ENTRIES)
1111 * it's a definitive win.
1112 * second point to notice: between enumerations
1113 * our sam is now the same as it's a snapshoot.
1114 * third point: got rid of the static SAM_USER_21 struct
1115 * no more intermediate.
1116 * con: it uses much more memory, as a full copy is stored
1119 * If you want to change it, think twice and think
1120 * of the second point , that's really important.
1125 /* Get what we need from the password database */
1126 switch (q_u->switch_level) {
1128 /* When playing with usrmgr, this is necessary
1129 if you want immediate refresh after editing
1130 a user. I would like to do this after the
1131 setuserinfo2, but we do not have access to
1132 the domain handle in that call, only to the
1133 user handle. Where else does this hurt?
1137 /* We cannot do this here - it kills performace. JRA. */
1138 free_samr_users(info);
1143 /* Level 2 is for all machines, otherwise only 'normal' users */
1144 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1146 if (!NT_STATUS_IS_OK(r_u->status)) {
1147 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1150 num_account = info->disp_info.num_user_account;
1154 r_u->status = load_group_domain_entries(info, &info->sid);
1155 if (!NT_STATUS_IS_OK(r_u->status))
1157 num_account = info->disp_info.num_group_account;
1160 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1161 return NT_STATUS_INVALID_INFO_CLASS;
1164 /* first limit the number of entries we will return */
1165 if(max_entries > max_sam_entries) {
1166 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1167 max_entries = max_sam_entries;
1170 if (enum_context > num_account) {
1171 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1172 return NT_STATUS_NO_MORE_ENTRIES;
1175 /* verify we won't overflow */
1176 if (max_entries > num_account-enum_context) {
1177 max_entries = num_account-enum_context;
1178 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1181 /* calculate the size and limit on the number of entries we will return */
1182 temp_size=max_entries*struct_size;
1184 if (temp_size>max_size) {
1185 max_entries=MIN((max_size/struct_size),max_entries);;
1186 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1189 if (!(ctr = TALLOC_ZERO_P(p->mem_ctx,SAM_DISPINFO_CTR)))
1190 return NT_STATUS_NO_MEMORY;
1194 /* Now create reply structure */
1195 switch (q_u->switch_level) {
1198 if (!(ctr->sam.info1 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_1,max_entries)))
1199 return NT_STATUS_NO_MEMORY;
1201 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1202 info->disp_info.disp_user_info, &domain_sid);
1203 if (!NT_STATUS_IS_OK(disp_ret))
1208 if (!(ctr->sam.info2 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_2,max_entries)))
1209 return NT_STATUS_NO_MEMORY;
1211 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1212 info->disp_info.disp_user_info, &domain_sid);
1213 if (!NT_STATUS_IS_OK(disp_ret))
1218 if (!(ctr->sam.info3 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_3,max_entries)))
1219 return NT_STATUS_NO_MEMORY;
1221 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1222 if (!NT_STATUS_IS_OK(disp_ret))
1227 if (!(ctr->sam.info4 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_4,max_entries)))
1228 return NT_STATUS_NO_MEMORY;
1230 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1231 if (!NT_STATUS_IS_OK(disp_ret))
1236 if (!(ctr->sam.info5 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_5,max_entries)))
1237 return NT_STATUS_NO_MEMORY;
1239 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1240 if (!NT_STATUS_IS_OK(disp_ret))
1245 ctr->sam.info = NULL;
1246 return NT_STATUS_INVALID_INFO_CLASS;
1249 /* calculate the total size */
1250 total_data_size=num_account*struct_size;
1252 if (enum_context+max_entries < num_account)
1253 r_u->status = STATUS_MORE_ENTRIES;
1255 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1257 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1263 /*******************************************************************
1264 samr_reply_query_aliasinfo
1265 ********************************************************************/
1267 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1270 struct acct_info info;
1274 r_u->status = NT_STATUS_OK;
1276 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1278 /* find the policy handle. open a policy on it. */
1279 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1280 return NT_STATUS_INVALID_HANDLE;
1281 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1286 ret = pdb_get_aliasinfo(&sid, &info);
1290 return NT_STATUS_NO_SUCH_ALIAS;
1292 switch (q_u->switch_level) {
1295 r_u->ctr.switch_value1 = 1;
1296 init_samr_alias_info1(&r_u->ctr.alias.info1,
1297 info.acct_name, 1, info.acct_desc);
1301 r_u->ctr.switch_value1 = 3;
1302 init_samr_alias_info3(&r_u->ctr.alias.info3, info.acct_desc);
1305 return NT_STATUS_INVALID_INFO_CLASS;
1308 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1314 /*******************************************************************
1315 samr_reply_lookup_ids
1316 ********************************************************************/
1318 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1320 uint32 rid[MAX_SAM_ENTRIES];
1321 int num_rids = q_u->num_sids1;
1323 r_u->status = NT_STATUS_OK;
1325 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1327 if (num_rids > MAX_SAM_ENTRIES) {
1328 num_rids = MAX_SAM_ENTRIES;
1329 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1334 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1336 for (i = 0; i < num_rids && status == 0; i++)
1338 struct sam_passwd *sam_pass;
1342 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1343 q_u->uni_user_name[i].uni_str_len));
1345 /* find the user account */
1347 sam_pass = get_smb21pwd_entry(user_name, 0);
1350 if (sam_pass == NULL)
1352 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1357 rid[i] = sam_pass->user_rid;
1363 rid[0] = BUILTIN_ALIAS_RID_USERS;
1365 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1367 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1373 /*******************************************************************
1375 ********************************************************************/
1377 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1379 uint32 rid[MAX_SAM_ENTRIES];
1381 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1382 enum SID_NAME_USE local_type;
1384 int num_rids = q_u->num_names2;
1389 r_u->status = NT_STATUS_OK;
1391 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1396 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1397 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1401 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, 0, "_samr_lookup_names"))) { /* Don't know the acc_bits yet */
1405 if (num_rids > MAX_SAM_ENTRIES) {
1406 num_rids = MAX_SAM_ENTRIES;
1407 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1410 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1412 for (i = 0; i < num_rids; i++) {
1417 r_u->status = NT_STATUS_NONE_MAPPED;
1419 rid [i] = 0xffffffff;
1420 type[i] = SID_NAME_UNKNOWN;
1422 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1425 * we are only looking for a name
1426 * the SID we get back can be outside
1427 * the scope of the pol_sid
1429 * in clear: it prevents to reply to domain\group: yes
1430 * when only builtin\group exists.
1432 * a cleaner code is to add the sid of the domain we're looking in
1433 * to the local_lookup_name function.
1436 if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
1437 sid_split_rid(&sid, &local_rid);
1439 if (sid_equal(&sid, &pol_sid)) {
1442 /* Windows does not return WKN_GRP here, even
1443 * on lookups in builtin */
1444 type[i] = (local_type == SID_NAME_WKN_GRP) ?
1445 SID_NAME_ALIAS : local_type;
1447 r_u->status = NT_STATUS_OK;
1452 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1454 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1459 /*******************************************************************
1460 _samr_chgpasswd_user
1461 ********************************************************************/
1463 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1468 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1470 r_u->status = NT_STATUS_OK;
1472 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1473 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1475 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1478 * Pass the user through the NT -> unix user mapping
1482 (void)map_username(user_name);
1485 * UNIX username case mangling not required, pass_oem_change
1486 * is case insensitive.
1489 r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1490 q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1492 init_samr_r_chgpasswd_user(r_u, r_u->status);
1494 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1499 /*******************************************************************
1500 makes a SAMR_R_LOOKUP_RIDS structure.
1501 ********************************************************************/
1503 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1504 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1507 UNIHDR *hdr_name=NULL;
1508 UNISTR2 *uni_name=NULL;
1510 *pp_uni_name = NULL;
1511 *pp_hdr_name = NULL;
1513 if (num_names != 0) {
1514 hdr_name = TALLOC_ZERO_ARRAY(ctx, UNIHDR, num_names);
1515 if (hdr_name == NULL)
1518 uni_name = TALLOC_ZERO_ARRAY(ctx,UNISTR2, num_names);
1519 if (uni_name == NULL)
1523 for (i = 0; i < num_names; i++) {
1524 DEBUG(10, ("names[%d]:%s\n", i, names[i] ? names[i] : ""));
1525 init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
1526 init_uni_hdr(&hdr_name[i], &uni_name[i]);
1529 *pp_uni_name = uni_name;
1530 *pp_hdr_name = hdr_name;
1535 /*******************************************************************
1537 ********************************************************************/
1539 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1541 fstring group_names[MAX_SAM_ENTRIES];
1542 uint32 *group_attrs = NULL;
1543 UNIHDR *hdr_name = NULL;
1544 UNISTR2 *uni_name = NULL;
1546 int num_rids = q_u->num_rids1;
1550 r_u->status = NT_STATUS_OK;
1552 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1554 /* find the policy handle. open a policy on it. */
1555 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1556 return NT_STATUS_INVALID_HANDLE;
1558 if (num_rids > MAX_SAM_ENTRIES) {
1559 num_rids = MAX_SAM_ENTRIES;
1560 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1564 if ((group_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids )) == NULL)
1565 return NT_STATUS_NO_MEMORY;
1568 r_u->status = NT_STATUS_NONE_MAPPED;
1570 become_root(); /* lookup_sid can require root privs */
1572 for (i = 0; i < num_rids; i++) {
1576 enum SID_NAME_USE type;
1578 group_attrs[i] = SID_NAME_UNKNOWN;
1579 *group_names[i] = '\0';
1581 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1582 sid_copy(&sid, &pol_sid);
1583 sid_append_rid(&sid, q_u->rid[i]);
1585 if (lookup_sid(&sid, domname, tmpname, &type)) {
1586 r_u->status = NT_STATUS_OK;
1587 group_attrs[i] = (uint32)type;
1588 fstrcpy(group_names[i],tmpname);
1589 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1596 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1597 return NT_STATUS_NO_MEMORY;
1599 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1601 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1606 /*******************************************************************
1607 _samr_open_user. Safe - gives out no passwd info.
1608 ********************************************************************/
1610 NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1612 SAM_ACCOUNT *sampass=NULL;
1614 POLICY_HND domain_pol = q_u->domain_pol;
1615 POLICY_HND *user_pol = &r_u->user_pol;
1616 struct samr_info *info = NULL;
1617 SEC_DESC *psd = NULL;
1619 uint32 des_access = q_u->access_mask;
1624 r_u->status = NT_STATUS_OK;
1626 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1627 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1628 return NT_STATUS_INVALID_HANDLE;
1630 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1634 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1635 if (!NT_STATUS_IS_OK(nt_status)) {
1639 /* append the user's RID to it */
1640 if (!sid_append_rid(&sid, q_u->user_rid))
1641 return NT_STATUS_NO_SUCH_USER;
1643 /* check if access can be granted as requested by client. */
1644 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1645 se_map_generic(&des_access, &usr_generic_mapping);
1646 if (!NT_STATUS_IS_OK(nt_status =
1647 access_check_samr_object(psd, p->pipe_user.nt_user_token,
1648 des_access, &acc_granted, "_samr_open_user"))) {
1653 ret=pdb_getsampwsid(sampass, &sid);
1656 /* check that the SID exists in our domain. */
1658 return NT_STATUS_NO_SUCH_USER;
1661 pdb_free_sam(&sampass);
1663 /* associate the user's SID and access bits with the new handle. */
1664 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1665 return NT_STATUS_NO_MEMORY;
1666 info->acc_granted = acc_granted;
1668 /* get a (unique) handle. open a policy on it. */
1669 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1670 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1675 /*************************************************************************
1676 get_user_info_10. Safe. Only gives out acb bits.
1677 *************************************************************************/
1679 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1681 SAM_ACCOUNT *smbpass=NULL;
1685 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1687 if (!NT_STATUS_IS_OK(nt_status)) {
1692 ret = pdb_getsampwsid(smbpass, user_sid);
1696 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1697 return NT_STATUS_NO_SUCH_USER;
1700 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1703 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1705 pdb_free_sam(&smbpass);
1707 return NT_STATUS_OK;
1710 /*************************************************************************
1711 get_user_info_12. OK - this is the killer as it gives out password info.
1712 Ensure that this is only allowed on an encrypted connection with a root
1714 *************************************************************************/
1716 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1718 SAM_ACCOUNT *smbpass=NULL;
1722 if (!p->ntlmssp_auth_validated)
1723 return NT_STATUS_ACCESS_DENIED;
1725 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1726 return NT_STATUS_ACCESS_DENIED;
1729 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1732 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1734 if (!NT_STATUS_IS_OK(nt_status)) {
1738 ret = pdb_getsampwsid(smbpass, user_sid);
1741 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1742 pdb_free_sam(&smbpass);
1743 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1746 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1748 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1749 pdb_free_sam(&smbpass);
1750 return NT_STATUS_ACCOUNT_DISABLED;
1754 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1756 pdb_free_sam(&smbpass);
1758 return NT_STATUS_OK;
1761 /*************************************************************************
1763 *************************************************************************/
1765 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1767 SAM_ACCOUNT *sampass=NULL;
1770 pdb_init_sam_talloc(mem_ctx, &sampass);
1773 ret = pdb_getsampwsid(sampass, user_sid);
1777 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1778 return NT_STATUS_NO_SUCH_USER;
1781 samr_clear_sam_passwd(sampass);
1783 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1786 init_sam_user_info20A(id20, sampass);
1788 pdb_free_sam(&sampass);
1790 return NT_STATUS_OK;
1793 /*************************************************************************
1795 *************************************************************************/
1797 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1798 DOM_SID *user_sid, DOM_SID *domain_sid)
1800 SAM_ACCOUNT *sampass=NULL;
1804 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1805 if (!NT_STATUS_IS_OK(nt_status)) {
1810 ret = pdb_getsampwsid(sampass, user_sid);
1814 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1815 return NT_STATUS_NO_SUCH_USER;
1818 samr_clear_sam_passwd(sampass);
1820 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1823 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1825 pdb_free_sam(&sampass);
1827 return NT_STATUS_OK;
1830 /*******************************************************************
1831 _samr_query_userinfo
1832 ********************************************************************/
1834 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1836 SAM_USERINFO_CTR *ctr;
1837 struct samr_info *info = NULL;
1841 r_u->status=NT_STATUS_OK;
1843 /* search for the handle */
1844 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1845 return NT_STATUS_INVALID_HANDLE;
1847 domain_sid = info->sid;
1849 sid_split_rid(&domain_sid, &rid);
1851 if (!sid_check_is_in_our_domain(&info->sid))
1852 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1854 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1856 ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_USERINFO_CTR);
1858 return NT_STATUS_NO_MEMORY;
1862 /* ok! user info levels (lots: see MSDEV help), off we go... */
1863 ctr->switch_value = q_u->switch_value;
1865 switch (q_u->switch_value) {
1867 ctr->info.id10 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_10);
1868 if (ctr->info.id10 == NULL)
1869 return NT_STATUS_NO_MEMORY;
1871 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1876 /* whoops - got this wrong. i think. or don't understand what's happening. */
1880 info = (void *)&id11;
1882 expire.low = 0xffffffff;
1883 expire.high = 0x7fffffff;
1885 ctr->info.id = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_11));
1886 ZERO_STRUCTP(ctr->info.id11);
1887 init_sam_user_info11(ctr->info.id11, &expire,
1888 "BROOKFIELDS$", /* name */
1889 0x03ef, /* user rid */
1890 0x201, /* group rid */
1891 0x0080); /* acb info */
1898 ctr->info.id12 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_12);
1899 if (ctr->info.id12 == NULL)
1900 return NT_STATUS_NO_MEMORY;
1902 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1907 ctr->info.id20 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_20);
1908 if (ctr->info.id20 == NULL)
1909 return NT_STATUS_NO_MEMORY;
1910 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1915 ctr->info.id21 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_21);
1916 if (ctr->info.id21 == NULL)
1917 return NT_STATUS_NO_MEMORY;
1918 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1919 &info->sid, &domain_sid)))
1924 return NT_STATUS_INVALID_INFO_CLASS;
1927 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1929 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1934 /*******************************************************************
1935 samr_reply_query_usergroups
1936 ********************************************************************/
1938 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1940 SAM_ACCOUNT *sam_pass=NULL;
1941 struct passwd *passwd;
1944 DOM_GID *gids = NULL;
1947 int i, num_gids, num_sids;
1953 * from the SID in the request:
1954 * we should send back the list of DOMAIN GROUPS
1955 * the user is a member of
1957 * and only the DOMAIN GROUPS
1958 * no ALIASES !!! neither aliases of the domain
1959 * nor aliases of the builtin SID
1964 r_u->status = NT_STATUS_OK;
1966 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1968 /* find the policy handle. open a policy on it. */
1969 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1970 return NT_STATUS_INVALID_HANDLE;
1972 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
1976 if (!sid_check_is_in_our_domain(&sid))
1977 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1979 pdb_init_sam(&sam_pass);
1982 ret = pdb_getsampwsid(sam_pass, &sid);
1986 pdb_free_sam(&sam_pass);
1987 return NT_STATUS_NO_SUCH_USER;
1990 passwd = getpwnam_alloc(pdb_get_username(sam_pass));
1991 if (passwd == NULL) {
1992 pdb_free_sam(&sam_pass);
1993 return NT_STATUS_NO_SUCH_USER;
2000 result = pdb_enum_group_memberships(pdb_get_username(sam_pass),
2002 &sids, &unix_gids, &num_groups);
2005 pdb_free_sam(&sam_pass);
2006 passwd_free(&passwd);
2008 if (!NT_STATUS_IS_OK(result))
2011 SAFE_FREE(unix_gids);
2016 for (i=0; i<num_groups; i++) {
2019 if (!sid_peek_check_rid(get_global_sam_sid(),
2023 gids = TALLOC_REALLOC_ARRAY(p->mem_ctx, gids, DOM_GID, num_gids+1);
2024 gids[num_gids].attr=7;
2025 gids[num_gids].g_rid = rid;
2030 /* construct the response. lkclXXXX: gids are not copied! */
2031 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
2033 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2038 /*******************************************************************
2039 _samr_query_dom_info
2040 ********************************************************************/
2042 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2044 struct samr_info *info = NULL;
2046 uint32 min_pass_len,pass_hist,flag;
2047 time_t u_expire, u_min_age;
2048 NTTIME nt_expire, nt_min_age;
2050 time_t u_lock_duration, u_reset_time;
2051 NTTIME nt_lock_duration, nt_reset_time;
2057 uint32 account_policy_temp;
2059 uint32 num_users=0, num_groups=0, num_aliases=0;
2061 if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
2062 return NT_STATUS_NO_MEMORY;
2066 r_u->status = NT_STATUS_OK;
2068 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2070 /* find the policy handle. open a policy on it. */
2071 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2072 return NT_STATUS_INVALID_HANDLE;
2074 switch (q_u->switch_value) {
2077 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2078 min_pass_len = account_policy_temp;
2080 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2081 pass_hist = account_policy_temp;
2083 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2084 flag = account_policy_temp;
2086 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2087 u_expire = account_policy_temp;
2089 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2090 u_min_age = account_policy_temp;
2092 unix_to_nt_time_abs(&nt_expire, u_expire);
2093 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2095 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2096 flag, nt_expire, nt_min_age);
2100 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2102 if (!NT_STATUS_IS_OK(r_u->status)) {
2103 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2106 num_users=info->disp_info.num_user_account;
2109 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2110 if (!NT_STATUS_IS_OK(r_u->status)) {
2111 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2114 num_groups=info->disp_info.num_group_account;
2117 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
2118 u_logout = account_policy_temp;
2120 unix_to_nt_time_abs(&nt_logout, u_logout);
2122 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2123 init_unk_info2(&ctr->info.inf2, "", lp_workgroup(), global_myname(), (uint32) time(NULL),
2124 num_users, num_groups, num_aliases, nt_logout);
2127 account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
2128 unix_to_nt_time_abs(&nt_logout, u_logout);
2130 init_unk_info3(&ctr->info.inf3, nt_logout);
2133 init_unk_info5(&ctr->info.inf5, global_myname());
2136 init_unk_info6(&ctr->info.inf6);
2139 init_unk_info7(&ctr->info.inf7);
2142 init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
2145 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2146 u_lock_duration = account_policy_temp * 60;
2148 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2149 u_reset_time = account_policy_temp * 60;
2151 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2152 lockout = account_policy_temp;
2154 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2155 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2157 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2160 return NT_STATUS_INVALID_INFO_CLASS;
2163 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2165 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2170 /*******************************************************************
2172 Create an account, can be either a normal user or a machine.
2173 This funcion will need to be updated for bdc/domain trusts.
2174 ********************************************************************/
2176 NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2178 SAM_ACCOUNT *sam_pass=NULL;
2182 POLICY_HND dom_pol = q_u->domain_pol;
2183 UNISTR2 user_account = q_u->uni_name;
2184 uint16 acb_info = q_u->acb_info;
2185 POLICY_HND *user_pol = &r_u->user_pol;
2186 struct samr_info *info = NULL;
2194 /* check this, when giving away 'add computer to domain' privs */
2195 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2197 /* Get the domain SID stored in the domain policy */
2198 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2199 return NT_STATUS_INVALID_HANDLE;
2201 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2205 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST || acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
2206 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
2207 this parameter is not an account type */
2208 return NT_STATUS_INVALID_PARAMETER;
2211 /* find the account: tell the caller if it exists.
2212 lkclXXXX i have *no* idea if this is a problem or not
2213 or even if you are supposed to construct a different
2214 reply if the account already exists...
2217 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2218 strlower_m(account);
2220 pdb_init_sam(&sam_pass);
2223 ret = pdb_getsampwnam(sam_pass, account);
2226 /* this account exists: say so */
2227 pdb_free_sam(&sam_pass);
2228 return NT_STATUS_USER_EXISTS;
2231 pdb_free_sam(&sam_pass);
2234 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2235 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2236 * that only people with write access to the smbpasswd file will be able
2237 * to create a user. JRA.
2241 * add the user in the /etc/passwd file or the unix authority system.
2242 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2243 * a) local_password_change() checks for us if the /etc/passwd account really exists
2244 * b) smb_create_user() would return an error if the account already exists
2245 * and as it could return an error also if it can't create the account, it would be tricky.
2247 * So we go the easy way, only check after if the account exists.
2248 * JFM (2/3/2001), to clear any possible bad understanding (-:
2250 * We now have seperate script paramaters for adding users/machines so we
2251 * now have some sainity-checking to match.
2254 DEBUG(10,("checking account %s at pos %lu for $ termination\n",account, (unsigned long)strlen(account)-1));
2257 * we used to have code here that made sure the acb_info flags
2258 * matched with the users named (e.g. an account flags as a machine
2259 * trust account ended in '$'). It has been ifdef'd out for a long
2260 * time, so I replaced it with this comment. --jerry
2263 /* the passdb lookup has failed; check to see if we need to run the
2264 add user/machine script */
2266 pw = Get_Pwnam(account);
2268 /*********************************************************************
2269 * HEADS UP! If we have to create a new user account, we have to get
2270 * a new RID from somewhere. This used to be done by the passdb
2271 * backend. It has been moved into idmap now. Since idmap is now
2272 * wrapped up behind winbind, this means you have to run winbindd if you
2273 * want new accounts to get a new RID when "enable rid algorithm = no".
2274 * Tough. We now have a uniform way of allocating RIDs regardless
2275 * of what ever passdb backend people may use.
2276 * --jerry (2003-07-10)
2277 *********************************************************************/
2281 * we can't check both the ending $ and the acb_info.
2283 * UserManager creates trust accounts (ending in $,
2284 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2287 if (account[strlen(account)-1] == '$')
2288 pstrcpy(add_script, lp_addmachine_script());
2290 pstrcpy(add_script, lp_adduser_script());
2294 all_string_sub(add_script, "%u", account, sizeof(add_script));
2295 add_ret = smbrun(add_script,NULL);
2296 DEBUG(3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2298 else /* no add user script -- ask winbindd to do it */
2300 if ( !winbind_create_user( account, &new_rid ) ) {
2301 DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n",
2308 /* implicit call to getpwnam() next. we have a valid SID coming out of this call */
2310 if ( !NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pass, account, new_rid)) )
2313 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2315 if (!pdb_add_sam_account(sam_pass)) {
2316 pdb_free_sam(&sam_pass);
2317 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2319 return NT_STATUS_ACCESS_DENIED;
2322 /* Get the user's SID */
2323 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2325 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2326 se_map_generic(&des_access, &usr_generic_mapping);
2327 if (!NT_STATUS_IS_OK(nt_status =
2328 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2329 des_access, &acc_granted, "_samr_create_user"))) {
2333 /* associate the user's SID with the new handle. */
2334 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2335 pdb_free_sam(&sam_pass);
2336 return NT_STATUS_NO_MEMORY;
2341 info->acc_granted = acc_granted;
2343 /* get a (unique) handle. open a policy on it. */
2344 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2345 pdb_free_sam(&sam_pass);
2346 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2349 r_u->user_rid=pdb_get_user_rid(sam_pass);
2351 r_u->access_granted = acc_granted;
2353 pdb_free_sam(&sam_pass);
2355 return NT_STATUS_OK;
2358 /*******************************************************************
2359 samr_reply_connect_anon
2360 ********************************************************************/
2362 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2364 struct samr_info *info = NULL;
2365 uint32 des_access = q_u->access_mask;
2369 if (!pipe_access_check(p)) {
2370 DEBUG(3, ("access denied to samr_connect_anon\n"));
2371 r_u->status = NT_STATUS_ACCESS_DENIED;
2375 /* set up the SAMR connect_anon response */
2377 r_u->status = NT_STATUS_OK;
2379 /* associate the user's SID with the new handle. */
2380 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2381 return NT_STATUS_NO_MEMORY;
2383 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
2384 was observed from a win98 client trying to enumerate users (when configured
2385 user level access control on shares) --jerry */
2387 se_map_generic( &des_access, &sam_generic_mapping );
2388 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2390 info->status = q_u->unknown_0;
2392 /* get a (unique) handle. open a policy on it. */
2393 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2394 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2399 /*******************************************************************
2401 ********************************************************************/
2403 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2405 struct samr_info *info = NULL;
2406 SEC_DESC *psd = NULL;
2408 uint32 des_access = q_u->access_mask;
2413 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2417 if (!pipe_access_check(p)) {
2418 DEBUG(3, ("access denied to samr_connect\n"));
2419 r_u->status = NT_STATUS_ACCESS_DENIED;
2423 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2424 se_map_generic(&des_access, &sam_generic_mapping);
2425 if (!NT_STATUS_IS_OK(nt_status =
2426 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2427 des_access, &acc_granted, "_samr_connect"))) {
2431 r_u->status = NT_STATUS_OK;
2433 /* associate the user's SID and access granted with the new handle. */
2434 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2435 return NT_STATUS_NO_MEMORY;
2437 info->acc_granted = acc_granted;
2438 info->status = q_u->access_mask;
2440 /* get a (unique) handle. open a policy on it. */
2441 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2442 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2444 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2449 /*******************************************************************
2451 ********************************************************************/
2453 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2455 struct samr_info *info = NULL;
2456 SEC_DESC *psd = NULL;
2458 uint32 des_access = q_u->access_mask;
2463 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2467 if (!pipe_access_check(p)) {
2468 DEBUG(3, ("access denied to samr_connect4\n"));
2469 r_u->status = NT_STATUS_ACCESS_DENIED;
2473 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2474 se_map_generic(&des_access, &sam_generic_mapping);
2475 if (!NT_STATUS_IS_OK(nt_status =
2476 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2477 des_access, &acc_granted, "_samr_connect"))) {
2481 r_u->status = NT_STATUS_OK;
2483 /* associate the user's SID and access granted with the new handle. */
2484 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2485 return NT_STATUS_NO_MEMORY;
2487 info->acc_granted = acc_granted;
2488 info->status = q_u->access_mask;
2490 /* get a (unique) handle. open a policy on it. */
2491 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2492 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2494 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2499 /**********************************************************************
2500 api_samr_lookup_domain
2501 **********************************************************************/
2503 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2505 struct samr_info *info;
2506 fstring domain_name;
2509 r_u->status = NT_STATUS_OK;
2511 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2512 return NT_STATUS_INVALID_HANDLE;
2514 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
2515 SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_lookup_domain")))
2520 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2524 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2525 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2528 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2530 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2535 /******************************************************************
2536 makes a SAMR_R_ENUM_DOMAINS structure.
2537 ********************************************************************/
2539 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2540 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2546 DEBUG(5, ("make_enum_domains\n"));
2549 *pp_uni_name = NULL;
2551 if (num_sam_entries == 0)
2554 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
2555 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
2557 if (sam == NULL || uni_name == NULL)
2560 for (i = 0; i < num_sam_entries; i++) {
2561 init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
2562 init_sam_entry(&sam[i], &uni_name[i], 0);
2566 *pp_uni_name = uni_name;
2571 /**********************************************************************
2572 api_samr_enum_domains
2573 **********************************************************************/
2575 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2577 struct samr_info *info;
2578 uint32 num_entries = 2;
2582 r_u->status = NT_STATUS_OK;
2584 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2585 return NT_STATUS_INVALID_HANDLE;
2587 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2591 name = get_global_sam_name();
2593 fstrcpy(dom[0],name);
2595 fstrcpy(dom[1],"Builtin");
2597 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2598 return NT_STATUS_NO_MEMORY;
2600 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2605 /*******************************************************************
2607 ********************************************************************/
2609 NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2612 POLICY_HND domain_pol = q_u->dom_pol;
2613 uint32 alias_rid = q_u->rid_alias;
2614 POLICY_HND *alias_pol = &r_u->pol;
2615 struct samr_info *info = NULL;
2616 SEC_DESC *psd = NULL;
2618 uint32 des_access = q_u->access_mask;
2622 r_u->status = NT_STATUS_OK;
2624 /* find the domain policy and get the SID / access bits stored in the domain policy */
2625 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2626 return NT_STATUS_INVALID_HANDLE;
2628 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2632 /* append the alias' RID to it */
2633 if (!sid_append_rid(&sid, alias_rid))
2634 return NT_STATUS_NO_SUCH_USER;
2636 /*check if access can be granted as requested by client. */
2637 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2638 se_map_generic(&des_access,&ali_generic_mapping);
2639 if (!NT_STATUS_IS_OK(status =
2640 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2641 des_access, &acc_granted, "_samr_open_alias"))) {
2646 * we should check if the rid really exist !!!
2650 /* associate the user's SID with the new handle. */
2651 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2652 return NT_STATUS_NO_MEMORY;
2654 info->acc_granted = acc_granted;
2656 /* get a (unique) handle. open a policy on it. */
2657 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2658 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2663 /*******************************************************************
2665 ********************************************************************/
2667 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2669 SAM_ACCOUNT *pwd =NULL;
2674 ret = pdb_getsampwsid(pwd, sid);
2682 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2687 /* FIX ME: check if the value is really changed --metze */
2688 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2693 if(!pdb_update_sam_account(pwd)) {
2703 /*******************************************************************
2705 ********************************************************************/
2707 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2709 SAM_ACCOUNT *pwd = NULL;
2713 if(!pdb_getsampwsid(pwd, sid)) {
2719 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2724 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2728 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2732 if (!pdb_set_pass_changed_now (pwd)) {
2737 if(!pdb_update_sam_account(pwd)) {
2746 /*******************************************************************
2747 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2748 ********************************************************************/
2749 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2754 if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2756 DEBUG(2,("Could not get gid for primary group of "
2757 "user %s\n", pdb_get_username(sampass)));
2761 grp = getgrgid(gid);
2764 DEBUG(2,("Could not find primary group %lu for "
2765 "user %s\n", (unsigned long)gid,
2766 pdb_get_username(sampass)));
2770 if (smb_set_primary_group(grp->gr_name,
2771 pdb_get_username(sampass)) != 0) {
2772 DEBUG(2,("Could not set primary group for user %s to "
2774 pdb_get_username(sampass), grp->gr_name));
2782 /*******************************************************************
2784 ********************************************************************/
2786 static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, DOM_SID *sid)
2788 SAM_ACCOUNT *pwd = NULL;
2791 DEBUG(5, ("set_user_info_20: NULL id20\n"));
2797 if (!pdb_getsampwsid(pwd, sid)) {
2802 copy_id20_to_sam_passwd(pwd, id20);
2804 /* write the change out */
2805 if(!pdb_update_sam_account(pwd)) {
2814 /*******************************************************************
2816 ********************************************************************/
2818 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2820 SAM_ACCOUNT *pwd = NULL;
2823 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2829 if (!pdb_getsampwsid(pwd, sid)) {
2834 copy_id21_to_sam_passwd(pwd, id21);
2837 * The funny part about the previous two calls is
2838 * that pwd still has the password hashes from the
2839 * passdb entry. These have not been updated from
2840 * id21. I don't know if they need to be set. --jerry
2843 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2844 set_unix_primary_group(pwd);
2846 /* write the change out */
2847 if(!pdb_update_sam_account(pwd)) {
2857 /*******************************************************************
2859 ********************************************************************/
2861 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2863 SAM_ACCOUNT *pwd = NULL;
2864 pstring plaintext_buf;
2869 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2875 if (!pdb_getsampwsid(pwd, sid)) {
2880 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2881 pdb_get_username(pwd)));
2883 acct_ctrl = pdb_get_acct_ctrl(pwd);
2885 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2890 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2895 copy_id23_to_sam_passwd(pwd, id23);
2897 /* if it's a trust account, don't update /etc/passwd */
2898 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2899 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2900 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2901 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2903 /* update the UNIX password */
2904 if (lp_unix_password_sync() ) {
2905 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2907 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2910 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2917 ZERO_STRUCT(plaintext_buf);
2919 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2920 set_unix_primary_group(pwd);
2922 if(!pdb_update_sam_account(pwd)) {
2932 /*******************************************************************
2934 ********************************************************************/
2936 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2938 SAM_ACCOUNT *pwd = NULL;
2940 pstring plaintext_buf;
2945 if (!pdb_getsampwsid(pwd, sid)) {
2950 DEBUG(5, ("Attempting administrator password change for user %s\n",
2951 pdb_get_username(pwd)));
2953 acct_ctrl = pdb_get_acct_ctrl(pwd);
2955 ZERO_STRUCT(plaintext_buf);
2957 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2962 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2967 /* if it's a trust account, don't update /etc/passwd */
2968 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2969 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2970 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2971 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2973 /* update the UNIX password */
2974 if (lp_unix_password_sync()) {
2975 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2977 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2980 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2987 ZERO_STRUCT(plaintext_buf);
2989 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2991 /* update the SAMBA password */
2992 if(!pdb_update_sam_account(pwd)) {
3002 /*******************************************************************
3003 samr_reply_set_userinfo
3004 ********************************************************************/
3006 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
3009 POLICY_HND *pol = &q_u->pol;
3010 uint16 switch_value = q_u->switch_value;
3011 SAM_USERINFO_CTR *ctr = q_u->ctr;
3013 uint32 acc_required;
3015 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
3017 r_u->status = NT_STATUS_OK;
3019 /* find the policy handle. open a policy on it. */
3020 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3021 return NT_STATUS_INVALID_HANDLE;
3023 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3024 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
3028 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
3031 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
3032 return NT_STATUS_INVALID_INFO_CLASS;
3035 /* ok! user info levels (lots: see MSDEV help), off we go... */
3036 switch (switch_value) {
3038 if (!set_user_info_12(ctr->info.id12, &sid))
3039 return NT_STATUS_ACCESS_DENIED;
3043 if (!p->session_key.length) {
3044 return NT_STATUS_NO_USER_SESSION_KEY;
3046 SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
3048 dump_data(100, (char *)ctr->info.id24->pass, 516);
3050 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
3051 return NT_STATUS_ACCESS_DENIED;
3057 * Currently we don't really know how to unmarshall
3058 * the level 25 struct, and the password encryption
3059 * is different. This is a placeholder for when we
3060 * do understand it. In the meantime just return INVALID
3061 * info level and W2K SP2 drops down to level 23... JRA.
3064 if (!p->session_key.length) {
3065 return NT_STATUS_NO_USER_SESSION_KEY;
3067 SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
3069 dump_data(100, (char *)ctr->info.id25->pass, 532);
3071 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3072 return NT_STATUS_ACCESS_DENIED;
3075 return NT_STATUS_INVALID_INFO_CLASS;
3078 if (!p->session_key.length) {
3079 return NT_STATUS_NO_USER_SESSION_KEY;
3081 SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
3083 dump_data(100, (char *)ctr->info.id23->pass, 516);
3085 if (!set_user_info_23(ctr->info.id23, &sid))
3086 return NT_STATUS_ACCESS_DENIED;
3090 return NT_STATUS_INVALID_INFO_CLASS;
3096 /*******************************************************************
3097 samr_reply_set_userinfo2
3098 ********************************************************************/
3100 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3103 SAM_USERINFO_CTR *ctr = q_u->ctr;
3104 POLICY_HND *pol = &q_u->pol;
3105 uint16 switch_value = q_u->switch_value;
3107 uint32 acc_required;
3109 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3111 r_u->status = NT_STATUS_OK;
3113 /* find the policy handle. open a policy on it. */
3114 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3115 return NT_STATUS_INVALID_HANDLE;
3117 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3118 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3122 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3125 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3126 return NT_STATUS_INVALID_INFO_CLASS;
3129 switch_value=ctr->switch_value;
3131 /* ok! user info levels (lots: see MSDEV help), off we go... */
3132 switch (switch_value) {
3134 if (!set_user_info_21(ctr->info.id21, &sid))
3135 return NT_STATUS_ACCESS_DENIED;
3138 if (!set_user_info_20(ctr->info.id20, &sid))
3139 return NT_STATUS_ACCESS_DENIED;
3142 if (!set_user_info_10(ctr->info.id10, &sid))
3143 return NT_STATUS_ACCESS_DENIED;
3146 /* Used by AS/U JRA. */
3147 if (!set_user_info_12(ctr->info.id12, &sid))
3148 return NT_STATUS_ACCESS_DENIED;
3151 return NT_STATUS_INVALID_INFO_CLASS;
3157 /*********************************************************************
3158 _samr_query_aliasmem
3159 *********************************************************************/
3161 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3165 struct samr_info *info = NULL;
3176 r_u->status = NT_STATUS_OK;
3178 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3180 /* find the policy handle. open a policy on it. */
3181 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3182 return NT_STATUS_INVALID_HANDLE;
3184 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3185 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3187 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3188 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3189 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3190 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3194 if (!sid_check_is_domain(&info->sid) &&
3195 !sid_check_is_builtin(&info->sid))
3196 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3198 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, q_u->num_sids1);
3200 if (members == NULL)
3201 return NT_STATUS_NO_MEMORY;
3203 for (i=0; i<q_u->num_sids1; i++)
3204 sid_copy(&members[i], &q_u->sid[i].sid);
3207 res = pdb_enum_alias_memberships(members,
3208 q_u->num_sids1, &aliases,
3213 return NT_STATUS_UNSUCCESSFUL;
3218 for (i=0; i<num_aliases; i++) {
3221 if (!sid_peek_check_rid(&info->sid, &aliases[i], &rid))
3224 rids = TALLOC_REALLOC_ARRAY(p->mem_ctx, rids, uint32, num_groups+1);
3227 return NT_STATUS_NO_MEMORY;
3229 rids[num_groups] = rid;
3234 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3235 return NT_STATUS_OK;
3238 /*********************************************************************
3239 _samr_query_aliasmem
3240 *********************************************************************/
3242 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3254 /* find the policy handle. open a policy on it. */
3255 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3256 return NT_STATUS_INVALID_HANDLE;
3258 if (!NT_STATUS_IS_OK(r_u->status =
3259 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3263 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3265 if (!pdb_enum_aliasmem(&alias_sid, &sids, &num_sids))
3266 return NT_STATUS_NO_SUCH_ALIAS;
3268 sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_sids);
3269 if (num_sids!=0 && sid == NULL) {
3271 return NT_STATUS_NO_MEMORY;
3274 for (i = 0; i < num_sids; i++) {
3275 init_dom_sid2(&sid[i], &sids[i]);
3278 init_samr_r_query_aliasmem(r_u, num_sids, sid, NT_STATUS_OK);
3282 return NT_STATUS_OK;
3285 static void add_uid_to_array_unique(uid_t uid, uid_t **uids, int *num)
3289 for (i=0; i<*num; i++) {
3290 if ((*uids)[i] == uid)
3294 *uids = SMB_REALLOC_ARRAY(*uids, uid_t, *num+1);
3299 (*uids)[*num] = uid;
3304 static BOOL get_memberuids(gid_t gid, uid_t **uids, int *num)
3308 struct sys_pwent *userlist, *user;
3313 /* We only look at our own sam, so don't care about imported stuff */
3317 if ((grp = getgrgid(gid)) == NULL) {
3322 /* Primary group members */
3324 userlist = getpwent_list();
3326 for (user = userlist; user != NULL; user = user->next) {
3327 if (user->pw_gid != gid)
3329 add_uid_to_array_unique(user->pw_uid, uids, num);
3332 pwent_free(userlist);
3334 /* Secondary group members */
3336 for (gr = grp->gr_mem; (*gr != NULL) && ((*gr)[0] != '\0'); gr += 1) {
3337 struct passwd *pw = getpwnam(*gr);
3341 add_uid_to_array_unique(pw->pw_uid, uids, num);
3349 /*********************************************************************
3350 _samr_query_groupmem
3351 *********************************************************************/
3353 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3355 int final_num_rids, i;
3357 fstring group_sid_str;
3367 /* find the policy handle. open a policy on it. */
3368 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3369 return NT_STATUS_INVALID_HANDLE;
3371 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3375 sid_to_string(group_sid_str, &group_sid);
3376 DEBUG(10, ("sid is %s\n", group_sid_str));
3378 if (!sid_check_is_in_our_domain(&group_sid)) {
3379 DEBUG(3, ("sid %s is not in our domain\n", group_sid_str));
3380 return NT_STATUS_NO_SUCH_GROUP;
3383 DEBUG(10, ("lookup on Domain SID\n"));
3385 if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &gid)))
3386 return NT_STATUS_NO_SUCH_GROUP;
3388 if(!get_memberuids(gid, &uids, &num))
3389 return NT_STATUS_NO_SUCH_GROUP;
3391 rid=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num);
3392 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num);
3394 if (num!=0 && (rid==NULL || attr==NULL))
3395 return NT_STATUS_NO_MEMORY;
3399 for (i=0; i<num; i++) {
3402 if (!NT_STATUS_IS_OK(uid_to_sid(&sid, uids[i]))) {
3403 DEBUG(1, ("Could not map member uid to SID\n"));
3407 if (!sid_check_is_in_our_domain(&sid)) {
3408 DEBUG(1, ("Inconsistent SAM -- group member uid not "
3409 "in our domain\n"));
3413 sid_peek_rid(&sid, &rid[final_num_rids]);
3415 /* Hmm. In a trace I got the constant 7 here from NT. */
3416 attr[final_num_rids] = SID_NAME_USER;
3418 final_num_rids += 1;
3423 init_samr_r_query_groupmem(r_u, final_num_rids, rid, attr,
3426 return NT_STATUS_OK;
3429 /*********************************************************************
3431 *********************************************************************/
3433 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3438 /* Find the policy handle. Open a policy on it. */
3439 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3440 return NT_STATUS_INVALID_HANDLE;
3442 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3446 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3448 if (!pdb_add_aliasmem(&alias_sid, &q_u->sid.sid))
3449 return NT_STATUS_ACCESS_DENIED;
3451 return NT_STATUS_OK;
3454 /*********************************************************************
3456 *********************************************************************/
3458 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3463 /* Find the policy handle. Open a policy on it. */
3464 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3465 return NT_STATUS_INVALID_HANDLE;
3467 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3471 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
3472 sid_string_static(&alias_sid)));
3474 if (!pdb_del_aliasmem(&alias_sid, &q_u->sid.sid))
3475 return NT_STATUS_ACCESS_DENIED;
3477 return NT_STATUS_OK;
3480 /*********************************************************************
3482 *********************************************************************/
3484 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3488 fstring group_sid_str;
3495 SAM_ACCOUNT *sam_user=NULL;
3499 /* Find the policy handle. Open a policy on it. */
3500 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3501 return NT_STATUS_INVALID_HANDLE;
3503 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3507 sid_to_string(group_sid_str, &group_sid);
3508 DEBUG(10, ("sid is %s\n", group_sid_str));
3510 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3511 return NT_STATUS_NO_SUCH_GROUP;
3513 DEBUG(10, ("lookup on Domain SID\n"));
3515 if(!get_domain_group_from_sid(group_sid, &map))
3516 return NT_STATUS_NO_SUCH_GROUP;
3518 sid_copy(&user_sid, get_global_sam_sid());
3519 sid_append_rid(&user_sid, q_u->rid);
3521 ret = pdb_init_sam(&sam_user);
3522 if (!NT_STATUS_IS_OK(ret))
3525 check = pdb_getsampwsid(sam_user, &user_sid);
3527 if (check != True) {
3528 pdb_free_sam(&sam_user);
3529 return NT_STATUS_NO_SUCH_USER;
3532 /* check a real user exist before we run the script to add a user to a group */
3533 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3534 pdb_free_sam(&sam_user);
3535 return NT_STATUS_NO_SUCH_USER;
3538 pdb_free_sam(&sam_user);
3540 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3541 return NT_STATUS_NO_SUCH_USER;
3544 if ((grp=getgrgid(map.gid)) == NULL) {
3546 return NT_STATUS_NO_SUCH_GROUP;
3549 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3550 fstrcpy(grp_name, grp->gr_name);
3552 /* if the user is already in the group */
3553 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3555 return NT_STATUS_MEMBER_IN_GROUP;
3559 * ok, the group exist, the user exist, the user is not in the group,
3561 * we can (finally) add it to the group !
3564 smb_add_user_group(grp_name, pwd->pw_name);
3566 /* check if the user has been added then ... */
3567 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3569 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3573 return NT_STATUS_OK;
3576 /*********************************************************************
3578 *********************************************************************/
3580 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3584 SAM_ACCOUNT *sam_pass=NULL;
3591 * delete the group member named q_u->rid
3592 * who is a member of the sid associated with the handle
3593 * the rid is a user's rid as the group is a domain group.
3596 /* Find the policy handle. Open a policy on it. */
3597 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3598 return NT_STATUS_INVALID_HANDLE;
3600 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3604 if (!sid_check_is_in_our_domain(&group_sid))
3605 return NT_STATUS_NO_SUCH_GROUP;
3607 sid_copy(&user_sid, get_global_sam_sid());
3608 sid_append_rid(&user_sid, q_u->rid);
3610 if (!get_domain_group_from_sid(group_sid, &map))
3611 return NT_STATUS_NO_SUCH_GROUP;
3613 if ((grp=getgrgid(map.gid)) == NULL)
3614 return NT_STATUS_NO_SUCH_GROUP;
3616 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3617 fstrcpy(grp_name, grp->gr_name);
3619 /* check if the user exists before trying to remove it from the group */
3620 pdb_init_sam(&sam_pass);
3621 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3622 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3623 pdb_free_sam(&sam_pass);
3624 return NT_STATUS_NO_SUCH_USER;
3627 /* if the user is not in the group */
3628 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3629 pdb_free_sam(&sam_pass);
3630 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3633 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3635 /* check if the user has been removed then ... */
3636 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3637 pdb_free_sam(&sam_pass);
3638 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3641 pdb_free_sam(&sam_pass);
3642 return NT_STATUS_OK;
3646 /****************************************************************************
3647 Delete a UNIX user on demand.
3648 ****************************************************************************/
3650 static int smb_delete_user(const char *unix_user)
3655 /* try winbindd first since it is impossible to determine where
3656 a user came from via NSS. Try the delete user script if this fails
3657 meaning the user did not exist in winbindd's list of accounts */
3659 if ( winbind_delete_user( unix_user ) ) {
3660 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3665 /* fall back to 'delete user script' */
3667 pstrcpy(del_script, lp_deluser_script());
3670 all_string_sub(del_script, "%u", unix_user, sizeof(del_script));
3671 ret = smbrun(del_script,NULL);
3672 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3677 /*********************************************************************
3678 _samr_delete_dom_user
3679 *********************************************************************/
3681 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3684 SAM_ACCOUNT *sam_pass=NULL;
3687 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3689 /* Find the policy handle. Open a policy on it. */
3690 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3691 return NT_STATUS_INVALID_HANDLE;
3693 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3697 if (!sid_check_is_in_our_domain(&user_sid))
3698 return NT_STATUS_CANNOT_DELETE;
3700 /* check if the user exists before trying to delete */
3701 pdb_init_sam(&sam_pass);
3702 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3703 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
3704 sid_string_static(&user_sid)));
3705 pdb_free_sam(&sam_pass);
3706 return NT_STATUS_NO_SUCH_USER;
3709 /* First delete the samba side */
3710 if (!pdb_delete_sam_account(sam_pass)) {
3711 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3712 pdb_free_sam(&sam_pass);
3713 return NT_STATUS_CANNOT_DELETE;
3716 /* Now delete the unix side */
3718 * note: we don't check if the delete really happened
3719 * as the script is not necessary present
3720 * and maybe the sysadmin doesn't want to delete the unix side
3722 smb_delete_user(pdb_get_username(sam_pass));
3725 pdb_free_sam(&sam_pass);
3727 if (!close_policy_hnd(p, &q_u->user_pol))
3728 return NT_STATUS_OBJECT_NAME_INVALID;
3730 return NT_STATUS_OK;
3733 /*********************************************************************
3734 _samr_delete_dom_group
3735 *********************************************************************/
3737 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3742 fstring group_sid_str;
3748 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3750 /* Find the policy handle. Open a policy on it. */
3751 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3752 return NT_STATUS_INVALID_HANDLE;
3754 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3758 sid_copy(&dom_sid, &group_sid);
3759 sid_to_string(group_sid_str, &dom_sid);
3760 sid_split_rid(&dom_sid, &group_rid);
3762 DEBUG(10, ("sid is %s\n", group_sid_str));
3764 /* we check if it's our SID before deleting */
3765 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3766 return NT_STATUS_NO_SUCH_GROUP;
3768 DEBUG(10, ("lookup on Domain SID\n"));
3770 if(!get_domain_group_from_sid(group_sid, &map))
3771 return NT_STATUS_NO_SUCH_GROUP;
3775 /* check if group really exists */
3776 if ( (grp=getgrgid(gid)) == NULL)
3777 return NT_STATUS_NO_SUCH_GROUP;
3779 /* delete mapping first */
3780 if(!pdb_delete_group_mapping_entry(group_sid))
3781 return NT_STATUS_ACCESS_DENIED;
3783 /* we can delete the UNIX group */
3784 smb_delete_group(grp->gr_name);
3786 /* check if the group has been successfully deleted */
3787 if ( (grp=getgrgid(gid)) != NULL)
3788 return NT_STATUS_ACCESS_DENIED;
3791 if (!close_policy_hnd(p, &q_u->group_pol))
3792 return NT_STATUS_OBJECT_NAME_INVALID;
3794 return NT_STATUS_OK;
3797 /*********************************************************************
3798 _samr_delete_dom_alias
3799 *********************************************************************/
3801 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3806 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3808 /* Find the policy handle. Open a policy on it. */
3809 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3810 return NT_STATUS_INVALID_HANDLE;
3812 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3816 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3818 if (!sid_check_is_in_our_domain(&alias_sid))
3819 return NT_STATUS_NO_SUCH_ALIAS;
3821 DEBUG(10, ("lookup on Local SID\n"));
3823 /* Have passdb delete the alias */
3824 if (!pdb_delete_alias(&alias_sid))
3825 return NT_STATUS_ACCESS_DENIED;
3827 if (!close_policy_hnd(p, &q_u->alias_pol))
3828 return NT_STATUS_OBJECT_NAME_INVALID;
3830 return NT_STATUS_OK;
3833 /*********************************************************************
3834 _samr_create_dom_group
3835 *********************************************************************/
3837 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3844 struct samr_info *info;
3848 /* Find the policy handle. Open a policy on it. */
3849 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3850 return NT_STATUS_INVALID_HANDLE;
3852 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3856 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3857 return NT_STATUS_ACCESS_DENIED;
3859 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3861 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3863 /* check if group already exist */
3864 if ((grp=getgrnam(name)) != NULL)
3865 return NT_STATUS_GROUP_EXISTS;
3867 /* we can create the UNIX group */
3868 if (smb_create_group(name, &gid) != 0)
3869 return NT_STATUS_ACCESS_DENIED;
3871 /* check if the group has been successfully created */
3872 if ((grp=getgrgid(gid)) == NULL)
3873 return NT_STATUS_ACCESS_DENIED;
3875 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3877 /* add the group to the mapping table */
3878 sid_copy(&info_sid, get_global_sam_sid());
3879 sid_append_rid(&info_sid, r_u->rid);
3880 sid_to_string(sid_string, &info_sid);
3882 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
3883 return NT_STATUS_ACCESS_DENIED;
3885 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3886 return NT_STATUS_NO_MEMORY;
3888 /* get a (unique) handle. open a policy on it. */
3889 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3890 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3892 return NT_STATUS_OK;
3895 /*********************************************************************
3896 _samr_create_dom_alias
3897 *********************************************************************/
3899 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3905 struct samr_info *info;
3910 /* Find the policy handle. Open a policy on it. */
3911 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
3912 return NT_STATUS_INVALID_HANDLE;
3914 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3918 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3919 return NT_STATUS_ACCESS_DENIED;
3921 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3923 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3925 /* Have passdb create the alias */
3926 result = pdb_create_alias(name, &r_u->rid);
3928 if (!NT_STATUS_IS_OK(result))
3931 sid_copy(&info_sid, get_global_sam_sid());
3932 sid_append_rid(&info_sid, r_u->rid);
3934 if (!NT_STATUS_IS_OK(sid_to_gid(&info_sid, &gid)))
3935 return NT_STATUS_ACCESS_DENIED;
3937 /* check if the group has been successfully created */
3938 if ((grp=getgrgid(gid)) == NULL)
3939 return NT_STATUS_ACCESS_DENIED;
3941 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3942 return NT_STATUS_NO_MEMORY;
3944 /* get a (unique) handle. open a policy on it. */
3945 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
3946 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3948 return NT_STATUS_OK;
3951 /*********************************************************************
3952 _samr_query_groupinfo
3954 sends the name/comment pair of a domain group
3955 level 1 send also the number of users of that group
3956 *********************************************************************/
3958 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
3965 GROUP_INFO_CTR *ctr;
3969 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3970 return NT_STATUS_INVALID_HANDLE;
3972 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
3977 ret = get_domain_group_from_sid(group_sid, &map);
3980 return NT_STATUS_INVALID_HANDLE;
3982 ctr=TALLOC_ZERO_P(p->mem_ctx, GROUP_INFO_CTR);
3984 return NT_STATUS_NO_MEMORY;
3986 switch (q_u->switch_level) {
3988 ctr->switch_value1 = 1;
3989 if(!get_memberuids(map.gid, &uids, &num))
3990 return NT_STATUS_NO_SUCH_GROUP;
3992 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num);
3996 ctr->switch_value1 = 3;
3997 init_samr_group_info3(&ctr->group.info3);
4000 ctr->switch_value1 = 4;
4001 init_samr_group_info4(&ctr->group.info4, map.comment);
4004 return NT_STATUS_INVALID_INFO_CLASS;
4007 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4009 return NT_STATUS_OK;
4012 /*********************************************************************
4015 update a domain group's comment.
4016 *********************************************************************/
4018 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4022 GROUP_INFO_CTR *ctr;
4025 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4026 return NT_STATUS_INVALID_HANDLE;
4028 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4032 if (!get_domain_group_from_sid(group_sid, &map))
4033 return NT_STATUS_NO_SUCH_GROUP;
4037 switch (ctr->switch_value1) {
4039 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4042 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4045 return NT_STATUS_INVALID_INFO_CLASS;
4048 if(!pdb_update_group_mapping_entry(&map)) {
4049 return NT_STATUS_NO_SUCH_GROUP;
4052 return NT_STATUS_OK;
4055 /*********************************************************************
4058 update an alias's comment.
4059 *********************************************************************/
4061 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4064 struct acct_info info;
4065 ALIAS_INFO_CTR *ctr;
4068 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4069 return NT_STATUS_INVALID_HANDLE;
4071 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4077 switch (ctr->switch_value1) {
4079 unistr2_to_ascii(info.acct_desc,
4080 &(ctr->alias.info3.uni_acct_desc),
4081 sizeof(info.acct_desc)-1);
4084 return NT_STATUS_INVALID_INFO_CLASS;
4087 if(!pdb_set_aliasinfo(&group_sid, &info)) {
4088 return NT_STATUS_ACCESS_DENIED;
4091 return NT_STATUS_OK;
4094 /*********************************************************************
4095 _samr_get_dom_pwinfo
4096 *********************************************************************/
4098 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4100 /* Perform access check. Since this rpc does not require a
4101 policy handle it will not be caught by the access checks on
4102 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4104 if (!pipe_access_check(p)) {
4105 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4106 r_u->status = NT_STATUS_ACCESS_DENIED;
4110 /* Actually, returning zeros here works quite well :-). */
4112 return NT_STATUS_OK;
4115 /*********************************************************************
4117 *********************************************************************/
4119 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4124 struct samr_info *info;
4125 SEC_DESC *psd = NULL;
4127 uint32 des_access = q_u->access_mask;
4133 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4134 return NT_STATUS_INVALID_HANDLE;
4136 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4140 /*check if access can be granted as requested by client. */
4141 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4142 se_map_generic(&des_access,&grp_generic_mapping);
4143 if (!NT_STATUS_IS_OK(status =
4144 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4145 des_access, &acc_granted, "_samr_open_group"))) {
4150 /* this should not be hard-coded like this */
4151 if (!sid_equal(&sid, get_global_sam_sid()))
4152 return NT_STATUS_ACCESS_DENIED;
4154 sid_copy(&info_sid, get_global_sam_sid());
4155 sid_append_rid(&info_sid, q_u->rid_group);
4156 sid_to_string(sid_string, &info_sid);
4158 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4159 return NT_STATUS_NO_MEMORY;
4161 info->acc_granted = acc_granted;
4163 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4165 /* check if that group really exists */
4167 ret = get_domain_group_from_sid(info->sid, &map);
4170 return NT_STATUS_NO_SUCH_GROUP;
4172 /* get a (unique) handle. open a policy on it. */
4173 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4174 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4176 return NT_STATUS_OK;
4179 /*********************************************************************
4180 _samr_remove_sid_foreign_domain
4181 *********************************************************************/
4183 NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p,
4184 SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u,
4185 SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
4187 DOM_SID delete_sid, alias_sid;
4188 SAM_ACCOUNT *sam_pass=NULL;
4191 BOOL is_user = False;
4193 enum SID_NAME_USE type = SID_NAME_UNKNOWN;
4195 sid_copy( &delete_sid, &q_u->sid.sid );
4197 DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4198 sid_string_static(&delete_sid)));
4200 /* Find the policy handle. Open a policy on it. */
4202 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted))
4203 return NT_STATUS_INVALID_HANDLE;
4205 result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS,
4206 "_samr_remove_sid_foreign_domain");
4208 if (!NT_STATUS_IS_OK(result))
4211 DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n",
4212 sid_string_static(&alias_sid)));
4214 /* make sure we can handle this */
4216 if ( sid_check_is_domain(&alias_sid) )
4217 type = SID_NAME_DOM_GRP;
4218 else if ( sid_check_is_builtin(&alias_sid) )
4219 type = SID_NAME_ALIAS;
4221 if ( type == SID_NAME_UNKNOWN ) {
4222 DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
4223 return NT_STATUS_OK;
4226 /* check if the user exists before trying to delete */
4228 pdb_init_sam(&sam_pass);
4230 if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
4233 /* maybe it is a group */
4234 if( !pdb_getgrsid(&map, delete_sid) ) {
4235 DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
4236 sid_string_static(&delete_sid)));
4237 result = NT_STATUS_INVALID_SID;
4242 /* we can only delete a user from a group since we don't have
4243 nested groups anyways. So in the latter case, just say OK */
4246 GROUP_MAP *mappings = NULL;
4250 if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
4252 /* interate over the groups */
4253 for ( i=0; i<num_groups; i++ ) {
4255 grp2 = getgrgid(mappings[i].gid);
4258 DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
4262 if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
4265 smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
4267 if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
4268 /* should we fail here ? */
4269 DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
4270 pdb_get_username(sam_pass), grp2->gr_name ));
4274 DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
4275 pdb_get_username(sam_pass), grp2->gr_name ));
4278 SAFE_FREE(mappings);
4282 result = NT_STATUS_OK;
4285 pdb_free_sam(&sam_pass);
4290 /*******************************************************************
4292 ********************************************************************/
4294 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4296 struct samr_info *info = NULL;
4298 uint32 min_pass_len,pass_hist,flag;
4299 time_t u_expire, u_min_age;
4300 NTTIME nt_expire, nt_min_age;
4302 time_t u_lock_duration, u_reset_time;
4303 NTTIME nt_lock_duration, nt_reset_time;
4309 uint32 num_users=0, num_groups=0, num_aliases=0;
4311 uint32 account_policy_temp;
4313 if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
4314 return NT_STATUS_NO_MEMORY;
4318 r_u->status = NT_STATUS_OK;
4320 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4322 /* find the policy handle. open a policy on it. */
4323 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4324 return NT_STATUS_INVALID_HANDLE;
4326 switch (q_u->switch_value) {
4328 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4329 min_pass_len = account_policy_temp;
4331 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4332 pass_hist = account_policy_temp;
4334 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4335 flag = account_policy_temp;
4337 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4338 u_expire = account_policy_temp;
4340 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4341 u_min_age = account_policy_temp;
4343 unix_to_nt_time_abs(&nt_expire, u_expire);
4344 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4346 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4347 flag, nt_expire, nt_min_age);
4351 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4353 if (!NT_STATUS_IS_OK(r_u->status)) {
4354 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4357 num_users=info->disp_info.num_user_account;
4360 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4361 if (NT_STATUS_IS_ERR(r_u->status)) {
4362 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4365 num_groups=info->disp_info.num_group_account;
4368 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4369 u_logout = account_policy_temp;
4371 unix_to_nt_time_abs(&nt_logout, u_logout);
4373 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4374 init_unk_info2(&ctr->info.inf2, "", lp_workgroup(), global_myname(), (uint32) time(NULL),
4375 num_users, num_groups, num_aliases, nt_logout);
4378 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4379 u_logout = account_policy_temp;
4381 unix_to_nt_time_abs(&nt_logout, u_logout);
4383 init_unk_info3(&ctr->info.inf3, nt_logout);
4386 init_unk_info5(&ctr->info.inf5, global_myname());
4389 init_unk_info6(&ctr->info.inf6);
4392 init_unk_info7(&ctr->info.inf7);
4395 init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
4398 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4399 u_lock_duration = account_policy_temp * 60;
4401 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4402 u_reset_time = account_policy_temp * 60;
4404 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4405 lockout = account_policy_temp;
4407 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4408 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4410 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4413 return NT_STATUS_INVALID_INFO_CLASS;
4416 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4418 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4423 /*******************************************************************
4425 ********************************************************************/
4427 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4429 time_t u_expire, u_min_age;
4431 time_t u_lock_duration, u_reset_time;
4433 r_u->status = NT_STATUS_OK;
4435 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4437 /* find the policy handle. open a policy on it. */
4438 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4439 return NT_STATUS_INVALID_HANDLE;
4441 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4443 switch (q_u->switch_value) {
4445 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4446 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4448 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4449 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4450 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4451 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4452 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4457 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4458 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4467 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration)/60;
4468 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
4470 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4471 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4472 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4475 return NT_STATUS_INVALID_INFO_CLASS;
4478 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4480 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));