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 - 2004,
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 static 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 static 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;
453 DOM_SID adm_sid, act_sid, domadmin_sid;
460 sid_copy(&adm_sid, &global_sid_Builtin);
461 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
463 sid_copy(&act_sid, &global_sid_Builtin);
464 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
466 /*basic access for every one*/
467 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
468 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
470 /*full access for builtin aliases Administrators and Account Operators*/
472 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS);
474 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
475 init_sec_ace(&ace[i++], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
477 /* add domain admins if we are a DC */
480 sid_copy( &domadmin_sid, get_global_sam_sid() );
481 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
482 init_sec_ace(&ace[i++], &domadmin_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
485 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
486 return NT_STATUS_NO_MEMORY;
488 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
489 return NT_STATUS_NO_MEMORY;
494 /*******************************************************************
496 ********************************************************************/
498 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
500 extern DOM_SID global_sid_World;
501 DOM_SID adm_sid, act_sid, domadmin_sid;
509 sid_copy(&adm_sid, &global_sid_Builtin);
510 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
512 sid_copy(&act_sid, &global_sid_Builtin);
513 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
515 /*basic access for every one*/
517 init_sec_access(&mask, GENERIC_RIGHTS_USER_EXECUTE | GENERIC_RIGHTS_USER_READ);
518 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
520 /*full access for builtin aliases Administrators and Account Operators*/
522 init_sec_access(&mask, GENERIC_RIGHTS_USER_ALL_ACCESS);
523 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
524 init_sec_ace(&ace[i++], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
526 /* add domain admins if we are a DC */
529 sid_copy( &domadmin_sid, get_global_sam_sid() );
530 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
531 init_sec_ace(&ace[i++], &domadmin_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
534 /*extended access for the user*/
536 init_sec_access(&mask,READ_CONTROL_ACCESS | SA_RIGHT_USER_CHANGE_PASSWORD | SA_RIGHT_USER_SET_LOC_COM);
537 init_sec_ace(&ace[i++], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
539 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
540 return NT_STATUS_NO_MEMORY;
542 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
543 return NT_STATUS_NO_MEMORY;
548 /*******************************************************************
550 ********************************************************************/
552 static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
554 extern DOM_SID global_sid_World;
563 sid_copy(&adm_sid, &global_sid_Builtin);
564 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
566 sid_copy(&act_sid, &global_sid_Builtin);
567 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
569 /*basic access for every one*/
570 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
571 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
573 /*full access for builtin aliases Administrators and Account Operators*/
574 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_ALL_ACCESS);
575 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
576 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
578 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
579 return NT_STATUS_NO_MEMORY;
581 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
582 return NT_STATUS_NO_MEMORY;
587 /*******************************************************************
589 ********************************************************************/
591 static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
593 extern DOM_SID global_sid_World;
602 sid_copy(&adm_sid, &global_sid_Builtin);
603 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
605 sid_copy(&act_sid, &global_sid_Builtin);
606 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
608 /*basic access for every one*/
609 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
610 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
612 /*full access for builtin aliases Administrators and Account Operators*/
613 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_ALL_ACCESS);
614 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
615 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
617 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
618 return NT_STATUS_NO_MEMORY;
620 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
621 return NT_STATUS_NO_MEMORY;
626 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
628 struct samr_info *info = NULL;
630 /* find the policy handle. open a policy on it. */
631 if (!find_policy_by_hnd(p, pol, (void **)&info))
638 *acc_granted = info->acc_granted;
642 /*******************************************************************
644 ********************************************************************/
646 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
648 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
649 return NT_STATUS_NOT_IMPLEMENTED;
653 /*******************************************************************
655 ********************************************************************/
657 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
661 SEC_DESC * psd = NULL;
665 r_u->status = NT_STATUS_OK;
668 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
669 return NT_STATUS_INVALID_HANDLE;
673 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
675 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
677 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
678 if (pol_sid.sid_rev_num == 0)
680 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
681 r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
683 else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */
686 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
687 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
689 else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */
691 /* TODO: Builtin probably needs a different SD with restricted write access*/
692 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
693 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
695 else if (sid_check_is_in_our_domain(&pol_sid) ||
696 sid_check_is_in_builtin(&pol_sid))
698 /* TODO: different SDs have to be generated for aliases groups and users.
699 Currently all three get a default user SD */
700 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
701 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
703 else return NT_STATUS_OBJECT_TYPE_MISMATCH;
705 if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
706 return NT_STATUS_NO_MEMORY;
708 if (NT_STATUS_IS_OK(r_u->status))
714 /*******************************************************************
715 makes a SAM_ENTRY / UNISTR2* structure from a user list.
716 ********************************************************************/
718 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
719 uint32 num_entries, uint32 start_idx, SAM_ACCOUNT *disp_user_info,
725 SAM_ACCOUNT *pwd = NULL;
726 UNISTR2 uni_temp_name;
727 const char *temp_name;
728 const DOM_SID *user_sid;
730 fstring user_sid_string;
731 fstring domain_sid_string;
736 if (num_entries == 0)
739 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_entries);
741 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_entries);
743 if (sam == NULL || uni_name == NULL) {
744 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
745 return NT_STATUS_NO_MEMORY;
748 for (i = 0; i < num_entries; i++) {
749 pwd = &disp_user_info[i+start_idx];
750 temp_name = pdb_get_username(pwd);
753 * usrmgr expects a non-NULL terminated string with
754 * trust relationships
756 if (pdb_get_acct_ctrl(pwd) & ACB_DOMTRUST) {
757 init_unistr2(&uni_temp_name, temp_name, UNI_FLAGS_NONE);
759 init_unistr2(&uni_temp_name, temp_name, UNI_STR_TERMINATE);
762 user_sid = pdb_get_user_sid(pwd);
764 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
765 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
766 "the domain sid %s. Failing operation.\n",
768 sid_to_string(user_sid_string, user_sid),
769 sid_to_string(domain_sid_string, domain_sid)));
770 return NT_STATUS_UNSUCCESSFUL;
773 init_sam_entry(&sam[i], &uni_temp_name, user_rid);
774 copy_unistr2(&uni_name[i], &uni_temp_name);
778 *uni_name_pp = uni_name;
782 /*******************************************************************
783 samr_reply_enum_dom_users
784 ********************************************************************/
786 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
787 SAMR_R_ENUM_DOM_USERS *r_u)
789 struct samr_info *info = NULL;
790 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
792 uint32 enum_context=q_u->start_idx;
793 uint32 max_size=q_u->max_size;
795 enum remote_arch_types ra_type = get_remote_arch();
796 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
797 uint32 max_entries = max_sam_entries;
800 r_u->status = NT_STATUS_OK;
802 /* find the policy handle. open a policy on it. */
803 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
804 return NT_STATUS_INVALID_HANDLE;
806 domain_sid = info->sid;
808 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
809 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
810 "_samr_enum_dom_users"))) {
814 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
817 r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
820 if (!NT_STATUS_IS_OK(r_u->status))
823 num_account = info->disp_info.num_user_account;
825 if (enum_context > num_account) {
826 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
830 /* verify we won't overflow */
831 if (max_entries > num_account-enum_context) {
832 max_entries = num_account-enum_context;
833 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
836 /* calculate the size and limit on the number of entries we will return */
837 temp_size=max_entries*struct_size;
839 if (temp_size>max_size) {
840 max_entries=MIN((max_size/struct_size),max_entries);;
841 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
845 * Note from JRA. total_entries is not being used here. Currently if there is a
846 * large user base then it looks like NT will enumerate until get_sampwd_entries
847 * returns False due to num_entries being zero. This will cause an access denied
848 * return. I don't think this is right and needs further investigation. Note that
849 * this is also the same in the TNG code (I don't think that has been tested with
850 * a very large user list as MAX_SAM_ENTRIES is set to 600).
852 * I also think that one of the 'num_entries' return parameters is probably
853 * the "max entries" parameter - but in the TNG code they're all currently set to the same
854 * value (again I think this is wrong).
857 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
858 max_entries, enum_context,
859 info->disp_info.disp_user_info,
862 if (!NT_STATUS_IS_OK(r_u->status))
865 if (enum_context+max_entries < num_account)
866 r_u->status = STATUS_MORE_ENTRIES;
868 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
870 init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
872 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
877 /*******************************************************************
878 makes a SAM_ENTRY / UNISTR2* structure from a group list.
879 ********************************************************************/
881 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
882 uint32 num_sam_entries, DOMAIN_GRP *grp)
891 if (num_sam_entries == 0)
894 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
895 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
897 if (sam == NULL || uni_name == NULL) {
898 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
902 for (i = 0; i < num_sam_entries; i++) {
904 * JRA. I think this should include the null. TNG does not.
906 init_unistr2(&uni_name[i], grp[i].name, UNI_STR_TERMINATE);
907 init_sam_entry(&sam[i], &uni_name[i], grp[i].rid);
911 *uni_name_pp = uni_name;
914 /*******************************************************************
915 Get the group entries - similar to get_sampwd_entries().
916 ******************************************************************/
918 static NTSTATUS get_group_domain_entries( TALLOC_CTX *ctx,
919 DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
920 uint32 *p_num_entries, uint32 max_entries )
924 uint32 group_entries = 0;
925 uint32 num_entries = 0;
929 /* access checks for the users were performed higher up. become/unbecome_root()
930 needed for some passdb backends to enumerate groups */
933 pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries,
937 num_entries=group_entries-start_idx;
939 /* limit the number of entries */
940 if (num_entries>max_entries) {
941 DEBUG(5,("Limiting to %d entries\n", max_entries));
942 num_entries=max_entries;
945 *d_grp=TALLOC_ZERO_ARRAY(ctx, DOMAIN_GRP, num_entries);
946 if (num_entries!=0 && *d_grp==NULL){
948 return NT_STATUS_NO_MEMORY;
951 for (i=0; i<num_entries; i++) {
952 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
953 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
954 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
955 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
960 *p_num_entries = num_entries;
962 DEBUG(10,("get_group_domain_entries: returning %d entries\n",
968 /*******************************************************************
969 Wrapper for enumerating local groups
970 ******************************************************************/
972 static NTSTATUS get_alias_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp,
973 const DOM_SID *sid, uint32 start_idx,
974 uint32 *p_num_entries, uint32 max_entries )
976 struct acct_info *info;
981 res = pdb_enum_aliases(sid, start_idx, max_entries,
982 p_num_entries, &info);
986 return NT_STATUS_ACCESS_DENIED;
988 if (*p_num_entries == 0)
991 *d_grp = TALLOC_ARRAY(ctx, DOMAIN_GRP, *p_num_entries);
993 if (*d_grp == NULL) {
995 return NT_STATUS_NO_MEMORY;
998 for (i=0; i<*p_num_entries; i++) {
999 fstrcpy((*d_grp)[i].name, info[i].acct_name);
1000 fstrcpy((*d_grp)[i].comment, info[i].acct_desc);
1001 (*d_grp)[i].rid = info[i].rid;
1002 (*d_grp)[i].attr = SID_NAME_ALIAS;
1006 return NT_STATUS_OK;
1009 /*******************************************************************
1010 samr_reply_enum_dom_groups
1011 ********************************************************************/
1013 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
1015 DOMAIN_GRP *grp=NULL;
1020 r_u->status = NT_STATUS_OK;
1022 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1023 return NT_STATUS_INVALID_HANDLE;
1025 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
1029 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1031 /* the domain group array is being allocated in the function below */
1032 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))) {
1036 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1038 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
1040 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1046 /*******************************************************************
1047 samr_reply_enum_dom_aliases
1048 ********************************************************************/
1050 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1052 DOMAIN_GRP *grp=NULL;
1053 uint32 num_entries = 0;
1059 r_u->status = NT_STATUS_OK;
1061 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1062 return NT_STATUS_INVALID_HANDLE;
1064 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1068 sid_to_string(sid_str, &sid);
1069 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1071 status = get_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1072 &num_entries, MAX_SAM_ENTRIES);
1073 if (!NT_STATUS_IS_OK(status)) return status;
1075 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1079 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1081 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1086 /*******************************************************************
1087 samr_reply_query_dispinfo
1088 ********************************************************************/
1090 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1091 SAMR_R_QUERY_DISPINFO *r_u)
1093 struct samr_info *info = NULL;
1094 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1096 uint32 max_entries=q_u->max_entries;
1097 uint32 enum_context=q_u->start_idx;
1098 uint32 max_size=q_u->max_size;
1100 SAM_DISPINFO_CTR *ctr;
1101 uint32 temp_size=0, total_data_size=0;
1103 uint32 num_account = 0;
1104 enum remote_arch_types ra_type = get_remote_arch();
1105 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1108 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1109 r_u->status = NT_STATUS_OK;
1111 /* find the policy handle. open a policy on it. */
1112 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1113 return NT_STATUS_INVALID_HANDLE;
1115 domain_sid = info->sid;
1118 * calculate how many entries we will return.
1120 * - the number of entries the client asked
1121 * - our limit on that
1122 * - the starting point (enumeration context)
1123 * - the buffer size the client will accept
1127 * We are a lot more like W2K. Instead of reading the SAM
1128 * each time to find the records we need to send back,
1129 * we read it once and link that copy to the sam handle.
1130 * For large user list (over the MAX_SAM_ENTRIES)
1131 * it's a definitive win.
1132 * second point to notice: between enumerations
1133 * our sam is now the same as it's a snapshoot.
1134 * third point: got rid of the static SAM_USER_21 struct
1135 * no more intermediate.
1136 * con: it uses much more memory, as a full copy is stored
1139 * If you want to change it, think twice and think
1140 * of the second point , that's really important.
1145 /* Get what we need from the password database */
1146 switch (q_u->switch_level) {
1148 /* When playing with usrmgr, this is necessary
1149 if you want immediate refresh after editing
1150 a user. I would like to do this after the
1151 setuserinfo2, but we do not have access to
1152 the domain handle in that call, only to the
1153 user handle. Where else does this hurt?
1157 /* We cannot do this here - it kills performace. JRA. */
1158 free_samr_users(info);
1163 /* Level 2 is for all machines, otherwise only 'normal' users */
1164 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1166 if (!NT_STATUS_IS_OK(r_u->status)) {
1167 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1170 num_account = info->disp_info.num_user_account;
1174 r_u->status = load_group_domain_entries(info, &info->sid);
1175 if (!NT_STATUS_IS_OK(r_u->status))
1177 num_account = info->disp_info.num_group_account;
1180 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1181 return NT_STATUS_INVALID_INFO_CLASS;
1184 /* first limit the number of entries we will return */
1185 if(max_entries > max_sam_entries) {
1186 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1187 max_entries = max_sam_entries;
1190 if (enum_context > num_account) {
1191 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1192 return NT_STATUS_NO_MORE_ENTRIES;
1195 /* verify we won't overflow */
1196 if (max_entries > num_account-enum_context) {
1197 max_entries = num_account-enum_context;
1198 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1201 /* calculate the size and limit on the number of entries we will return */
1202 temp_size=max_entries*struct_size;
1204 if (temp_size>max_size) {
1205 max_entries=MIN((max_size/struct_size),max_entries);;
1206 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1209 if (!(ctr = TALLOC_ZERO_P(p->mem_ctx,SAM_DISPINFO_CTR)))
1210 return NT_STATUS_NO_MEMORY;
1214 /* Now create reply structure */
1215 switch (q_u->switch_level) {
1218 if (!(ctr->sam.info1 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_1,max_entries)))
1219 return NT_STATUS_NO_MEMORY;
1221 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1222 info->disp_info.disp_user_info, &domain_sid);
1223 if (!NT_STATUS_IS_OK(disp_ret))
1228 if (!(ctr->sam.info2 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_2,max_entries)))
1229 return NT_STATUS_NO_MEMORY;
1231 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1232 info->disp_info.disp_user_info, &domain_sid);
1233 if (!NT_STATUS_IS_OK(disp_ret))
1238 if (!(ctr->sam.info3 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_3,max_entries)))
1239 return NT_STATUS_NO_MEMORY;
1241 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1242 if (!NT_STATUS_IS_OK(disp_ret))
1247 if (!(ctr->sam.info4 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_4,max_entries)))
1248 return NT_STATUS_NO_MEMORY;
1250 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1251 if (!NT_STATUS_IS_OK(disp_ret))
1256 if (!(ctr->sam.info5 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_5,max_entries)))
1257 return NT_STATUS_NO_MEMORY;
1259 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1260 if (!NT_STATUS_IS_OK(disp_ret))
1265 ctr->sam.info = NULL;
1266 return NT_STATUS_INVALID_INFO_CLASS;
1269 /* calculate the total size */
1270 total_data_size=num_account*struct_size;
1272 if (enum_context+max_entries < num_account)
1273 r_u->status = STATUS_MORE_ENTRIES;
1275 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1277 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1283 /*******************************************************************
1284 samr_reply_query_aliasinfo
1285 ********************************************************************/
1287 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1290 struct acct_info info;
1294 r_u->status = NT_STATUS_OK;
1296 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1298 /* find the policy handle. open a policy on it. */
1299 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1300 return NT_STATUS_INVALID_HANDLE;
1301 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1306 ret = pdb_get_aliasinfo(&sid, &info);
1310 return NT_STATUS_NO_SUCH_ALIAS;
1312 switch (q_u->switch_level) {
1315 r_u->ctr.switch_value1 = 1;
1316 init_samr_alias_info1(&r_u->ctr.alias.info1,
1317 info.acct_name, 1, info.acct_desc);
1321 r_u->ctr.switch_value1 = 3;
1322 init_samr_alias_info3(&r_u->ctr.alias.info3, info.acct_desc);
1325 return NT_STATUS_INVALID_INFO_CLASS;
1328 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1334 /*******************************************************************
1335 samr_reply_lookup_ids
1336 ********************************************************************/
1338 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1340 uint32 rid[MAX_SAM_ENTRIES];
1341 int num_rids = q_u->num_sids1;
1343 r_u->status = NT_STATUS_OK;
1345 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1347 if (num_rids > MAX_SAM_ENTRIES) {
1348 num_rids = MAX_SAM_ENTRIES;
1349 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1354 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1356 for (i = 0; i < num_rids && status == 0; i++)
1358 struct sam_passwd *sam_pass;
1362 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1363 q_u->uni_user_name[i].uni_str_len));
1365 /* find the user account */
1367 sam_pass = get_smb21pwd_entry(user_name, 0);
1370 if (sam_pass == NULL)
1372 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1377 rid[i] = sam_pass->user_rid;
1383 rid[0] = BUILTIN_ALIAS_RID_USERS;
1385 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1387 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1393 /*******************************************************************
1395 ********************************************************************/
1397 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1399 uint32 rid[MAX_SAM_ENTRIES];
1401 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1402 enum SID_NAME_USE local_type;
1404 int num_rids = q_u->num_names2;
1409 r_u->status = NT_STATUS_OK;
1411 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1416 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1417 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1421 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 */
1425 if (num_rids > MAX_SAM_ENTRIES) {
1426 num_rids = MAX_SAM_ENTRIES;
1427 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1430 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1432 for (i = 0; i < num_rids; i++) {
1437 r_u->status = NT_STATUS_NONE_MAPPED;
1439 rid [i] = 0xffffffff;
1440 type[i] = SID_NAME_UNKNOWN;
1442 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1445 * we are only looking for a name
1446 * the SID we get back can be outside
1447 * the scope of the pol_sid
1449 * in clear: it prevents to reply to domain\group: yes
1450 * when only builtin\group exists.
1452 * a cleaner code is to add the sid of the domain we're looking in
1453 * to the local_lookup_name function.
1456 if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
1457 sid_split_rid(&sid, &local_rid);
1459 if (sid_equal(&sid, &pol_sid)) {
1462 /* Windows does not return WKN_GRP here, even
1463 * on lookups in builtin */
1464 type[i] = (local_type == SID_NAME_WKN_GRP) ?
1465 SID_NAME_ALIAS : local_type;
1467 r_u->status = NT_STATUS_OK;
1472 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1474 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1479 /*******************************************************************
1480 _samr_chgpasswd_user
1481 ********************************************************************/
1483 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1488 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1490 r_u->status = NT_STATUS_OK;
1492 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1493 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1495 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1498 * Pass the user through the NT -> unix user mapping
1502 (void)map_username(user_name);
1505 * UNIX username case mangling not required, pass_oem_change
1506 * is case insensitive.
1509 r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1510 q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1512 init_samr_r_chgpasswd_user(r_u, r_u->status);
1514 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1519 /*******************************************************************
1520 makes a SAMR_R_LOOKUP_RIDS structure.
1521 ********************************************************************/
1523 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1524 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1527 UNIHDR *hdr_name=NULL;
1528 UNISTR2 *uni_name=NULL;
1530 *pp_uni_name = NULL;
1531 *pp_hdr_name = NULL;
1533 if (num_names != 0) {
1534 hdr_name = TALLOC_ZERO_ARRAY(ctx, UNIHDR, num_names);
1535 if (hdr_name == NULL)
1538 uni_name = TALLOC_ZERO_ARRAY(ctx,UNISTR2, num_names);
1539 if (uni_name == NULL)
1543 for (i = 0; i < num_names; i++) {
1544 DEBUG(10, ("names[%d]:%s\n", i, names[i] ? names[i] : ""));
1545 init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
1546 init_uni_hdr(&hdr_name[i], &uni_name[i]);
1549 *pp_uni_name = uni_name;
1550 *pp_hdr_name = hdr_name;
1555 /*******************************************************************
1557 ********************************************************************/
1559 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1561 fstring group_names[MAX_SAM_ENTRIES];
1562 uint32 *group_attrs = NULL;
1563 UNIHDR *hdr_name = NULL;
1564 UNISTR2 *uni_name = NULL;
1566 int num_rids = q_u->num_rids1;
1570 r_u->status = NT_STATUS_OK;
1572 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1574 /* find the policy handle. open a policy on it. */
1575 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1576 return NT_STATUS_INVALID_HANDLE;
1578 if (num_rids > MAX_SAM_ENTRIES) {
1579 num_rids = MAX_SAM_ENTRIES;
1580 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1584 if ((group_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids )) == NULL)
1585 return NT_STATUS_NO_MEMORY;
1588 r_u->status = NT_STATUS_NONE_MAPPED;
1590 become_root(); /* lookup_sid can require root privs */
1592 for (i = 0; i < num_rids; i++) {
1596 enum SID_NAME_USE type;
1598 group_attrs[i] = SID_NAME_UNKNOWN;
1599 *group_names[i] = '\0';
1601 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1602 sid_copy(&sid, &pol_sid);
1603 sid_append_rid(&sid, q_u->rid[i]);
1605 if (lookup_sid(&sid, domname, tmpname, &type)) {
1606 r_u->status = NT_STATUS_OK;
1607 group_attrs[i] = (uint32)type;
1608 fstrcpy(group_names[i],tmpname);
1609 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1616 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1617 return NT_STATUS_NO_MEMORY;
1619 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1621 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1626 /*******************************************************************
1627 _samr_open_user. Safe - gives out no passwd info.
1628 ********************************************************************/
1630 NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1632 SAM_ACCOUNT *sampass=NULL;
1634 POLICY_HND domain_pol = q_u->domain_pol;
1635 POLICY_HND *user_pol = &r_u->user_pol;
1636 struct samr_info *info = NULL;
1637 SEC_DESC *psd = NULL;
1639 uint32 des_access = q_u->access_mask;
1644 r_u->status = NT_STATUS_OK;
1646 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1647 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1648 return NT_STATUS_INVALID_HANDLE;
1650 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1654 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1655 if (!NT_STATUS_IS_OK(nt_status)) {
1659 /* append the user's RID to it */
1660 if (!sid_append_rid(&sid, q_u->user_rid))
1661 return NT_STATUS_NO_SUCH_USER;
1663 /* check if access can be granted as requested by client. */
1664 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1665 se_map_generic(&des_access, &usr_generic_mapping);
1666 if (!NT_STATUS_IS_OK(nt_status =
1667 access_check_samr_object(psd, p->pipe_user.nt_user_token,
1668 des_access, &acc_granted, "_samr_open_user"))) {
1673 ret=pdb_getsampwsid(sampass, &sid);
1676 /* check that the SID exists in our domain. */
1678 return NT_STATUS_NO_SUCH_USER;
1681 pdb_free_sam(&sampass);
1683 /* associate the user's SID and access bits with the new handle. */
1684 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1685 return NT_STATUS_NO_MEMORY;
1686 info->acc_granted = acc_granted;
1688 /* get a (unique) handle. open a policy on it. */
1689 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1690 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1695 /*************************************************************************
1696 get_user_info_10. Safe. Only gives out acb bits.
1697 *************************************************************************/
1699 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1701 SAM_ACCOUNT *smbpass=NULL;
1705 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1707 if (!NT_STATUS_IS_OK(nt_status)) {
1712 ret = pdb_getsampwsid(smbpass, user_sid);
1716 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1717 return NT_STATUS_NO_SUCH_USER;
1720 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1723 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1725 pdb_free_sam(&smbpass);
1727 return NT_STATUS_OK;
1730 /*************************************************************************
1731 get_user_info_12. OK - this is the killer as it gives out password info.
1732 Ensure that this is only allowed on an encrypted connection with a root
1734 *************************************************************************/
1736 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1738 SAM_ACCOUNT *smbpass=NULL;
1742 if (!p->ntlmssp_auth_validated)
1743 return NT_STATUS_ACCESS_DENIED;
1745 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1746 return NT_STATUS_ACCESS_DENIED;
1749 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1752 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1754 if (!NT_STATUS_IS_OK(nt_status)) {
1758 ret = pdb_getsampwsid(smbpass, user_sid);
1761 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1762 pdb_free_sam(&smbpass);
1763 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1766 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1768 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1769 pdb_free_sam(&smbpass);
1770 return NT_STATUS_ACCOUNT_DISABLED;
1774 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1776 pdb_free_sam(&smbpass);
1778 return NT_STATUS_OK;
1781 /*************************************************************************
1783 *************************************************************************/
1785 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1787 SAM_ACCOUNT *sampass=NULL;
1790 pdb_init_sam_talloc(mem_ctx, &sampass);
1793 ret = pdb_getsampwsid(sampass, user_sid);
1797 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1798 return NT_STATUS_NO_SUCH_USER;
1801 samr_clear_sam_passwd(sampass);
1803 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1806 init_sam_user_info20A(id20, sampass);
1808 pdb_free_sam(&sampass);
1810 return NT_STATUS_OK;
1813 /*************************************************************************
1815 *************************************************************************/
1817 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1818 DOM_SID *user_sid, DOM_SID *domain_sid)
1820 SAM_ACCOUNT *sampass=NULL;
1824 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1825 if (!NT_STATUS_IS_OK(nt_status)) {
1830 ret = pdb_getsampwsid(sampass, user_sid);
1834 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1835 return NT_STATUS_NO_SUCH_USER;
1838 samr_clear_sam_passwd(sampass);
1840 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1843 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1845 pdb_free_sam(&sampass);
1847 return NT_STATUS_OK;
1850 /*******************************************************************
1851 _samr_query_userinfo
1852 ********************************************************************/
1854 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1856 SAM_USERINFO_CTR *ctr;
1857 struct samr_info *info = NULL;
1861 r_u->status=NT_STATUS_OK;
1863 /* search for the handle */
1864 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1865 return NT_STATUS_INVALID_HANDLE;
1867 domain_sid = info->sid;
1869 sid_split_rid(&domain_sid, &rid);
1871 if (!sid_check_is_in_our_domain(&info->sid))
1872 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1874 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1876 ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_USERINFO_CTR);
1878 return NT_STATUS_NO_MEMORY;
1882 /* ok! user info levels (lots: see MSDEV help), off we go... */
1883 ctr->switch_value = q_u->switch_value;
1885 switch (q_u->switch_value) {
1887 ctr->info.id10 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_10);
1888 if (ctr->info.id10 == NULL)
1889 return NT_STATUS_NO_MEMORY;
1891 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1896 /* whoops - got this wrong. i think. or don't understand what's happening. */
1900 info = (void *)&id11;
1902 expire.low = 0xffffffff;
1903 expire.high = 0x7fffffff;
1905 ctr->info.id = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_11));
1906 ZERO_STRUCTP(ctr->info.id11);
1907 init_sam_user_info11(ctr->info.id11, &expire,
1908 "BROOKFIELDS$", /* name */
1909 0x03ef, /* user rid */
1910 0x201, /* group rid */
1911 0x0080); /* acb info */
1918 ctr->info.id12 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_12);
1919 if (ctr->info.id12 == NULL)
1920 return NT_STATUS_NO_MEMORY;
1922 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1927 ctr->info.id20 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_20);
1928 if (ctr->info.id20 == NULL)
1929 return NT_STATUS_NO_MEMORY;
1930 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1935 ctr->info.id21 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_21);
1936 if (ctr->info.id21 == NULL)
1937 return NT_STATUS_NO_MEMORY;
1938 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1939 &info->sid, &domain_sid)))
1944 return NT_STATUS_INVALID_INFO_CLASS;
1947 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1949 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1954 /*******************************************************************
1955 samr_reply_query_usergroups
1956 ********************************************************************/
1958 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1960 SAM_ACCOUNT *sam_pass=NULL;
1961 struct passwd *passwd;
1964 DOM_GID *gids = NULL;
1967 int i, num_gids, num_sids;
1973 * from the SID in the request:
1974 * we should send back the list of DOMAIN GROUPS
1975 * the user is a member of
1977 * and only the DOMAIN GROUPS
1978 * no ALIASES !!! neither aliases of the domain
1979 * nor aliases of the builtin SID
1984 r_u->status = NT_STATUS_OK;
1986 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1988 /* find the policy handle. open a policy on it. */
1989 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1990 return NT_STATUS_INVALID_HANDLE;
1992 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
1996 if (!sid_check_is_in_our_domain(&sid))
1997 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1999 pdb_init_sam(&sam_pass);
2002 ret = pdb_getsampwsid(sam_pass, &sid);
2006 pdb_free_sam(&sam_pass);
2007 return NT_STATUS_NO_SUCH_USER;
2010 passwd = getpwnam_alloc(pdb_get_username(sam_pass));
2011 if (passwd == NULL) {
2012 pdb_free_sam(&sam_pass);
2013 return NT_STATUS_NO_SUCH_USER;
2020 result = pdb_enum_group_memberships(pdb_get_username(sam_pass),
2022 &sids, &unix_gids, &num_groups);
2025 pdb_free_sam(&sam_pass);
2026 passwd_free(&passwd);
2028 if (!NT_STATUS_IS_OK(result))
2031 SAFE_FREE(unix_gids);
2036 for (i=0; i<num_groups; i++) {
2039 if (!sid_peek_check_rid(get_global_sam_sid(),
2043 gids = TALLOC_REALLOC_ARRAY(p->mem_ctx, gids, DOM_GID, num_gids+1);
2044 gids[num_gids].attr=7;
2045 gids[num_gids].g_rid = rid;
2050 /* construct the response. lkclXXXX: gids are not copied! */
2051 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
2053 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2058 /*******************************************************************
2059 _samr_query_dom_info
2060 ********************************************************************/
2062 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2064 struct samr_info *info = NULL;
2066 uint32 min_pass_len,pass_hist,flag;
2067 time_t u_expire, u_min_age;
2068 NTTIME nt_expire, nt_min_age;
2070 time_t u_lock_duration, u_reset_time;
2071 NTTIME nt_lock_duration, nt_reset_time;
2077 uint32 account_policy_temp;
2079 uint32 num_users=0, num_groups=0, num_aliases=0;
2081 if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
2082 return NT_STATUS_NO_MEMORY;
2086 r_u->status = NT_STATUS_OK;
2088 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2090 /* find the policy handle. open a policy on it. */
2091 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2092 return NT_STATUS_INVALID_HANDLE;
2094 switch (q_u->switch_value) {
2097 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2098 min_pass_len = account_policy_temp;
2100 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2101 pass_hist = account_policy_temp;
2103 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2104 flag = account_policy_temp;
2106 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2107 u_expire = account_policy_temp;
2109 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2110 u_min_age = account_policy_temp;
2112 unix_to_nt_time_abs(&nt_expire, u_expire);
2113 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2115 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2116 flag, nt_expire, nt_min_age);
2120 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2122 if (!NT_STATUS_IS_OK(r_u->status)) {
2123 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2126 num_users=info->disp_info.num_user_account;
2129 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2130 if (!NT_STATUS_IS_OK(r_u->status)) {
2131 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2134 num_groups=info->disp_info.num_group_account;
2137 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
2138 u_logout = account_policy_temp;
2140 unix_to_nt_time_abs(&nt_logout, u_logout);
2142 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2143 init_unk_info2(&ctr->info.inf2, "", lp_workgroup(), global_myname(), (uint32) time(NULL),
2144 num_users, num_groups, num_aliases, nt_logout);
2147 account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
2148 unix_to_nt_time_abs(&nt_logout, u_logout);
2150 init_unk_info3(&ctr->info.inf3, nt_logout);
2153 init_unk_info5(&ctr->info.inf5, global_myname());
2156 init_unk_info6(&ctr->info.inf6);
2159 init_unk_info7(&ctr->info.inf7);
2162 init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
2165 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2166 u_lock_duration = account_policy_temp;
2167 if (u_lock_duration != -1)
2168 u_lock_duration *= 60;
2170 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2171 u_reset_time = account_policy_temp * 60;
2173 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2174 lockout = account_policy_temp;
2176 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2177 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2179 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2182 return NT_STATUS_INVALID_INFO_CLASS;
2185 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2187 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2192 /*******************************************************************
2194 Create an account, can be either a normal user or a machine.
2195 This funcion will need to be updated for bdc/domain trusts.
2196 ********************************************************************/
2198 NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2200 SAM_ACCOUNT *sam_pass=NULL;
2204 POLICY_HND dom_pol = q_u->domain_pol;
2205 UNISTR2 user_account = q_u->uni_name;
2206 uint16 acb_info = q_u->acb_info;
2207 POLICY_HND *user_pol = &r_u->user_pol;
2208 struct samr_info *info = NULL;
2216 /* check this, when giving away 'add computer to domain' privs */
2217 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2218 BOOL can_add_machines = False;
2219 SE_PRIV se_machineop = SE_MACHINE_ACCOUNT;
2221 /* Get the domain SID stored in the domain policy */
2222 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2223 return NT_STATUS_INVALID_HANDLE;
2225 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2229 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST || acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
2230 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
2231 this parameter is not an account type */
2232 return NT_STATUS_INVALID_PARAMETER;
2235 /* find the account: tell the caller if it exists.
2236 lkclXXXX i have *no* idea if this is a problem or not
2237 or even if you are supposed to construct a different
2238 reply if the account already exists...
2241 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2242 strlower_m(account);
2244 /* check to see if we are a domain admin */
2246 can_add_machines = user_has_privileges( p->pipe_user.nt_user_token, &se_machineop );
2248 DEBUG(5, ("_samr_create_user: %s is%s a member of the Domain Admins group\n",
2249 p->pipe_user_name, can_add_machines ? "" : " not"));
2251 pdb_init_sam(&sam_pass);
2254 ret = pdb_getsampwnam(sam_pass, account);
2257 /* this account exists: say so */
2258 pdb_free_sam(&sam_pass);
2259 return NT_STATUS_USER_EXISTS;
2262 pdb_free_sam(&sam_pass);
2265 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2266 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2267 * that only people with write access to the smbpasswd file will be able
2268 * to create a user. JRA.
2271 /*********************************************************************
2272 * HEADS UP! If we have to create a new user account, we have to get
2273 * a new RID from somewhere. This used to be done by the passdb
2274 * backend. It has been moved into idmap now. Since idmap is now
2275 * wrapped up behind winbind, this means you have to run winbindd if you
2276 * want new accounts to get a new RID when "enable rid algorithm = no".
2277 * Tough. We now have a uniform way of allocating RIDs regardless
2278 * of what ever passdb backend people may use.
2279 * --jerry (2003-07-10)
2280 *********************************************************************/
2282 pw = Get_Pwnam(account);
2284 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
2286 if ( can_add_machines )
2291 * we can't check both the ending $ and the acb_info.
2293 * UserManager creates trust accounts (ending in $,
2294 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2297 if (account[strlen(account)-1] == '$')
2298 pstrcpy(add_script, lp_addmachine_script());
2300 pstrcpy(add_script, lp_adduser_script());
2304 all_string_sub(add_script, "%u", account, sizeof(add_script));
2305 add_ret = smbrun(add_script,NULL);
2306 DEBUG(3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2308 else /* no add user script -- ask winbindd to do it */
2310 if ( !winbind_create_user( account, &new_rid ) ) {
2311 DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n",
2318 /* implicit call to getpwnam() next. we have a valid SID coming out of this call */
2320 if ( !NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pass, account, new_rid)) ) {
2321 if ( can_add_machines )
2326 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2328 ret = pdb_add_sam_account(sam_pass);
2330 if ( can_add_machines )
2333 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
2336 pdb_free_sam(&sam_pass);
2337 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2339 return NT_STATUS_ACCESS_DENIED;
2342 /* Get the user's SID */
2344 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2346 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2347 se_map_generic(&des_access, &usr_generic_mapping);
2349 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2350 des_access, &acc_granted, "_samr_create_user");
2352 if ( !NT_STATUS_IS_OK(nt_status) ) {
2356 /* associate the user's SID with the new handle. */
2357 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2358 pdb_free_sam(&sam_pass);
2359 return NT_STATUS_NO_MEMORY;
2364 info->acc_granted = acc_granted;
2366 /* get a (unique) handle. open a policy on it. */
2367 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2368 pdb_free_sam(&sam_pass);
2369 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2372 r_u->user_rid=pdb_get_user_rid(sam_pass);
2374 r_u->access_granted = acc_granted;
2376 pdb_free_sam(&sam_pass);
2378 return NT_STATUS_OK;
2381 /*******************************************************************
2382 samr_reply_connect_anon
2383 ********************************************************************/
2385 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2387 struct samr_info *info = NULL;
2388 uint32 des_access = q_u->access_mask;
2392 if (!pipe_access_check(p)) {
2393 DEBUG(3, ("access denied to samr_connect_anon\n"));
2394 r_u->status = NT_STATUS_ACCESS_DENIED;
2398 /* set up the SAMR connect_anon response */
2400 r_u->status = NT_STATUS_OK;
2402 /* associate the user's SID with the new handle. */
2403 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2404 return NT_STATUS_NO_MEMORY;
2406 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
2407 was observed from a win98 client trying to enumerate users (when configured
2408 user level access control on shares) --jerry */
2410 se_map_generic( &des_access, &sam_generic_mapping );
2411 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2413 info->status = q_u->unknown_0;
2415 /* get a (unique) handle. open a policy on it. */
2416 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2417 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2422 /*******************************************************************
2424 ********************************************************************/
2426 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2428 struct samr_info *info = NULL;
2429 SEC_DESC *psd = NULL;
2431 uint32 des_access = q_u->access_mask;
2436 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2440 if (!pipe_access_check(p)) {
2441 DEBUG(3, ("access denied to samr_connect\n"));
2442 r_u->status = NT_STATUS_ACCESS_DENIED;
2446 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2447 se_map_generic(&des_access, &sam_generic_mapping);
2448 if (!NT_STATUS_IS_OK(nt_status =
2449 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2450 des_access, &acc_granted, "_samr_connect"))) {
2454 r_u->status = NT_STATUS_OK;
2456 /* associate the user's SID and access granted with the new handle. */
2457 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2458 return NT_STATUS_NO_MEMORY;
2460 info->acc_granted = acc_granted;
2461 info->status = q_u->access_mask;
2463 /* get a (unique) handle. open a policy on it. */
2464 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2465 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2467 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2472 /*******************************************************************
2474 ********************************************************************/
2476 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2478 struct samr_info *info = NULL;
2479 SEC_DESC *psd = NULL;
2481 uint32 des_access = q_u->access_mask;
2486 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2490 if (!pipe_access_check(p)) {
2491 DEBUG(3, ("access denied to samr_connect4\n"));
2492 r_u->status = NT_STATUS_ACCESS_DENIED;
2496 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2497 se_map_generic(&des_access, &sam_generic_mapping);
2498 if (!NT_STATUS_IS_OK(nt_status =
2499 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2500 des_access, &acc_granted, "_samr_connect"))) {
2504 r_u->status = NT_STATUS_OK;
2506 /* associate the user's SID and access granted with the new handle. */
2507 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2508 return NT_STATUS_NO_MEMORY;
2510 info->acc_granted = acc_granted;
2511 info->status = q_u->access_mask;
2513 /* get a (unique) handle. open a policy on it. */
2514 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2515 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2517 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2522 /**********************************************************************
2523 api_samr_lookup_domain
2524 **********************************************************************/
2526 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2528 struct samr_info *info;
2529 fstring domain_name;
2532 r_u->status = NT_STATUS_OK;
2534 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2535 return NT_STATUS_INVALID_HANDLE;
2537 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
2538 SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_lookup_domain")))
2543 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2547 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2548 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2551 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2553 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2558 /******************************************************************
2559 makes a SAMR_R_ENUM_DOMAINS structure.
2560 ********************************************************************/
2562 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2563 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2569 DEBUG(5, ("make_enum_domains\n"));
2572 *pp_uni_name = NULL;
2574 if (num_sam_entries == 0)
2577 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
2578 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
2580 if (sam == NULL || uni_name == NULL)
2583 for (i = 0; i < num_sam_entries; i++) {
2584 init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
2585 init_sam_entry(&sam[i], &uni_name[i], 0);
2589 *pp_uni_name = uni_name;
2594 /**********************************************************************
2595 api_samr_enum_domains
2596 **********************************************************************/
2598 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2600 struct samr_info *info;
2601 uint32 num_entries = 2;
2605 r_u->status = NT_STATUS_OK;
2607 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2608 return NT_STATUS_INVALID_HANDLE;
2610 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2614 name = get_global_sam_name();
2616 fstrcpy(dom[0],name);
2618 fstrcpy(dom[1],"Builtin");
2620 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2621 return NT_STATUS_NO_MEMORY;
2623 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2628 /*******************************************************************
2630 ********************************************************************/
2632 NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2635 POLICY_HND domain_pol = q_u->dom_pol;
2636 uint32 alias_rid = q_u->rid_alias;
2637 POLICY_HND *alias_pol = &r_u->pol;
2638 struct samr_info *info = NULL;
2639 SEC_DESC *psd = NULL;
2641 uint32 des_access = q_u->access_mask;
2645 r_u->status = NT_STATUS_OK;
2647 /* find the domain policy and get the SID / access bits stored in the domain policy */
2648 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2649 return NT_STATUS_INVALID_HANDLE;
2651 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2655 /* append the alias' RID to it */
2656 if (!sid_append_rid(&sid, alias_rid))
2657 return NT_STATUS_NO_SUCH_USER;
2659 /*check if access can be granted as requested by client. */
2660 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2661 se_map_generic(&des_access,&ali_generic_mapping);
2662 if (!NT_STATUS_IS_OK(status =
2663 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2664 des_access, &acc_granted, "_samr_open_alias"))) {
2669 * we should check if the rid really exist !!!
2673 /* associate the user's SID with the new handle. */
2674 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2675 return NT_STATUS_NO_MEMORY;
2677 info->acc_granted = acc_granted;
2679 /* get a (unique) handle. open a policy on it. */
2680 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2681 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2686 /*******************************************************************
2688 ********************************************************************/
2690 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2692 SAM_ACCOUNT *pwd =NULL;
2697 ret = pdb_getsampwsid(pwd, sid);
2705 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2710 /* FIX ME: check if the value is really changed --metze */
2711 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2716 if(!pdb_update_sam_account(pwd)) {
2726 /*******************************************************************
2728 ********************************************************************/
2730 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2732 SAM_ACCOUNT *pwd = NULL;
2736 if(!pdb_getsampwsid(pwd, sid)) {
2742 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2747 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2751 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2755 if (!pdb_set_pass_changed_now (pwd)) {
2760 if(!pdb_update_sam_account(pwd)) {
2769 /*******************************************************************
2770 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2771 ********************************************************************/
2772 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2777 if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2779 DEBUG(2,("Could not get gid for primary group of "
2780 "user %s\n", pdb_get_username(sampass)));
2784 grp = getgrgid(gid);
2787 DEBUG(2,("Could not find primary group %lu for "
2788 "user %s\n", (unsigned long)gid,
2789 pdb_get_username(sampass)));
2793 if (smb_set_primary_group(grp->gr_name,
2794 pdb_get_username(sampass)) != 0) {
2795 DEBUG(2,("Could not set primary group for user %s to "
2797 pdb_get_username(sampass), grp->gr_name));
2805 /*******************************************************************
2807 ********************************************************************/
2809 static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, DOM_SID *sid)
2811 SAM_ACCOUNT *pwd = NULL;
2814 DEBUG(5, ("set_user_info_20: NULL id20\n"));
2820 if (!pdb_getsampwsid(pwd, sid)) {
2825 copy_id20_to_sam_passwd(pwd, id20);
2827 /* write the change out */
2828 if(!pdb_update_sam_account(pwd)) {
2837 /*******************************************************************
2839 ********************************************************************/
2841 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2843 SAM_ACCOUNT *pwd = NULL;
2846 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2852 if (!pdb_getsampwsid(pwd, sid)) {
2857 copy_id21_to_sam_passwd(pwd, id21);
2860 * The funny part about the previous two calls is
2861 * that pwd still has the password hashes from the
2862 * passdb entry. These have not been updated from
2863 * id21. I don't know if they need to be set. --jerry
2866 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2867 set_unix_primary_group(pwd);
2869 /* write the change out */
2870 if(!pdb_update_sam_account(pwd)) {
2880 /*******************************************************************
2882 ********************************************************************/
2884 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2886 SAM_ACCOUNT *pwd = NULL;
2887 pstring plaintext_buf;
2892 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2898 if (!pdb_getsampwsid(pwd, sid)) {
2903 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2904 pdb_get_username(pwd)));
2906 acct_ctrl = pdb_get_acct_ctrl(pwd);
2908 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2913 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2918 copy_id23_to_sam_passwd(pwd, id23);
2920 /* if it's a trust account, don't update /etc/passwd */
2921 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2922 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2923 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2924 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2926 /* update the UNIX password */
2927 if (lp_unix_password_sync() ) {
2928 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2930 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2933 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2940 ZERO_STRUCT(plaintext_buf);
2942 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2943 set_unix_primary_group(pwd);
2945 if(!pdb_update_sam_account(pwd)) {
2955 /*******************************************************************
2957 ********************************************************************/
2959 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2961 SAM_ACCOUNT *pwd = NULL;
2963 pstring plaintext_buf;
2968 if (!pdb_getsampwsid(pwd, sid)) {
2973 DEBUG(5, ("Attempting administrator password change for user %s\n",
2974 pdb_get_username(pwd)));
2976 acct_ctrl = pdb_get_acct_ctrl(pwd);
2978 ZERO_STRUCT(plaintext_buf);
2980 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2985 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2990 /* if it's a trust account, don't update /etc/passwd */
2991 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2992 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2993 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2994 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2996 /* update the UNIX password */
2997 if (lp_unix_password_sync()) {
2998 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
3000 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3003 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3010 ZERO_STRUCT(plaintext_buf);
3012 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
3014 /* update the SAMBA password */
3015 if(!pdb_update_sam_account(pwd)) {
3025 /*******************************************************************
3026 samr_reply_set_userinfo
3027 ********************************************************************/
3029 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
3032 POLICY_HND *pol = &q_u->pol;
3033 uint16 switch_value = q_u->switch_value;
3034 SAM_USERINFO_CTR *ctr = q_u->ctr;
3036 uint32 acc_required;
3037 BOOL can_add_machines;
3038 SE_PRIV se_machineop = SE_MACHINE_ACCOUNT;
3040 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
3042 r_u->status = NT_STATUS_OK;
3044 /* find the policy handle. open a policy on it. */
3045 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3046 return NT_STATUS_INVALID_HANDLE;
3048 /* the access mask depends on what the caller wants to do */
3050 switch (switch_value) {
3052 acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
3055 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3059 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
3063 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
3066 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
3067 return NT_STATUS_INVALID_INFO_CLASS;
3070 /* check to see if we are a domain admin */
3072 can_add_machines = user_has_privileges( p->pipe_user.nt_user_token, &se_machineop );
3074 DEBUG(5, ("_samr_create_user: %s is%s a member of the Domain Admins group\n",
3075 p->pipe_user_name, can_add_machines ? "" : " not"));
3077 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3079 if ( can_add_machines )
3082 /* ok! user info levels (lots: see MSDEV help), off we go... */
3084 switch (switch_value) {
3086 if (!set_user_info_12(ctr->info.id12, &sid))
3087 r_u->status = NT_STATUS_ACCESS_DENIED;
3091 if (!p->session_key.length) {
3092 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3094 SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
3096 dump_data(100, (char *)ctr->info.id24->pass, 516);
3098 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
3099 r_u->status = NT_STATUS_ACCESS_DENIED;
3105 * Currently we don't really know how to unmarshall
3106 * the level 25 struct, and the password encryption
3107 * is different. This is a placeholder for when we
3108 * do understand it. In the meantime just return INVALID
3109 * info level and W2K SP2 drops down to level 23... JRA.
3112 if (!p->session_key.length) {
3113 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3115 SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
3117 dump_data(100, (char *)ctr->info.id25->pass, 532);
3119 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3120 r_u->status = NT_STATUS_ACCESS_DENIED;
3123 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3127 if (!p->session_key.length) {
3128 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3130 SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
3132 dump_data(100, (char *)ctr->info.id23->pass, 516);
3134 if (!set_user_info_23(ctr->info.id23, &sid))
3135 r_u->status = NT_STATUS_ACCESS_DENIED;
3139 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3143 if ( can_add_machines )
3146 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3151 /*******************************************************************
3152 samr_reply_set_userinfo2
3153 ********************************************************************/
3155 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3158 SAM_USERINFO_CTR *ctr = q_u->ctr;
3159 POLICY_HND *pol = &q_u->pol;
3160 uint16 switch_value = q_u->switch_value;
3162 uint32 acc_required;
3163 BOOL can_add_machines;
3164 SE_PRIV se_machineop = SE_MACHINE_ACCOUNT;
3166 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3168 r_u->status = NT_STATUS_OK;
3170 /* find the policy handle. open a policy on it. */
3171 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3172 return NT_STATUS_INVALID_HANDLE;
3174 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3175 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3179 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3182 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3183 return NT_STATUS_INVALID_INFO_CLASS;
3186 switch_value=ctr->switch_value;
3188 /* check to see if we are a domain admin */
3190 can_add_machines = user_has_privileges( p->pipe_user.nt_user_token, &se_machineop );
3192 DEBUG(5, ("_samr_create_user: %s is%s a member of the Domain Admins group\n",
3193 p->pipe_user_name, can_add_machines ? "" : " not"));
3195 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3197 if ( can_add_machines )
3200 /* ok! user info levels (lots: see MSDEV help), off we go... */
3202 switch (switch_value) {
3204 if (!set_user_info_21(ctr->info.id21, &sid))
3205 return NT_STATUS_ACCESS_DENIED;
3208 if (!set_user_info_20(ctr->info.id20, &sid))
3209 r_u->status = NT_STATUS_ACCESS_DENIED;
3212 if (!set_user_info_10(ctr->info.id10, &sid))
3213 r_u->status = NT_STATUS_ACCESS_DENIED;
3216 /* Used by AS/U JRA. */
3217 if (!set_user_info_12(ctr->info.id12, &sid))
3218 r_u->status = NT_STATUS_ACCESS_DENIED;
3221 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3224 if ( can_add_machines )
3227 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3232 /*********************************************************************
3233 _samr_query_aliasmem
3234 *********************************************************************/
3236 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3240 struct samr_info *info = NULL;
3251 r_u->status = NT_STATUS_OK;
3253 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3255 /* find the policy handle. open a policy on it. */
3256 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3257 return NT_STATUS_INVALID_HANDLE;
3259 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3260 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3262 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3263 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3264 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3265 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3269 if (!sid_check_is_domain(&info->sid) &&
3270 !sid_check_is_builtin(&info->sid))
3271 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3273 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, q_u->num_sids1);
3275 if (members == NULL)
3276 return NT_STATUS_NO_MEMORY;
3278 for (i=0; i<q_u->num_sids1; i++)
3279 sid_copy(&members[i], &q_u->sid[i].sid);
3282 res = pdb_enum_alias_memberships(members,
3283 q_u->num_sids1, &aliases,
3288 return NT_STATUS_UNSUCCESSFUL;
3293 for (i=0; i<num_aliases; i++) {
3296 if (!sid_peek_check_rid(&info->sid, &aliases[i], &rid))
3299 rids = TALLOC_REALLOC_ARRAY(p->mem_ctx, rids, uint32, num_groups+1);
3302 return NT_STATUS_NO_MEMORY;
3304 rids[num_groups] = rid;
3309 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3310 return NT_STATUS_OK;
3313 /*********************************************************************
3314 _samr_query_aliasmem
3315 *********************************************************************/
3317 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3329 /* find the policy handle. open a policy on it. */
3330 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3331 return NT_STATUS_INVALID_HANDLE;
3333 if (!NT_STATUS_IS_OK(r_u->status =
3334 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3338 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3340 if (!pdb_enum_aliasmem(&alias_sid, &sids, &num_sids))
3341 return NT_STATUS_NO_SUCH_ALIAS;
3343 sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_sids);
3344 if (num_sids!=0 && sid == NULL) {
3346 return NT_STATUS_NO_MEMORY;
3349 for (i = 0; i < num_sids; i++) {
3350 init_dom_sid2(&sid[i], &sids[i]);
3353 init_samr_r_query_aliasmem(r_u, num_sids, sid, NT_STATUS_OK);
3357 return NT_STATUS_OK;
3360 static void add_uid_to_array_unique(uid_t uid, uid_t **uids, int *num)
3364 for (i=0; i<*num; i++) {
3365 if ((*uids)[i] == uid)
3369 *uids = SMB_REALLOC_ARRAY(*uids, uid_t, *num+1);
3374 (*uids)[*num] = uid;
3379 static BOOL get_memberuids(gid_t gid, uid_t **uids, int *num)
3383 struct sys_pwent *userlist, *user;
3388 /* We only look at our own sam, so don't care about imported stuff */
3392 if ((grp = getgrgid(gid)) == NULL) {
3397 /* Primary group members */
3399 userlist = getpwent_list();
3401 for (user = userlist; user != NULL; user = user->next) {
3402 if (user->pw_gid != gid)
3404 add_uid_to_array_unique(user->pw_uid, uids, num);
3407 pwent_free(userlist);
3409 /* Secondary group members */
3411 for (gr = grp->gr_mem; (*gr != NULL) && ((*gr)[0] != '\0'); gr += 1) {
3412 struct passwd *pw = getpwnam(*gr);
3416 add_uid_to_array_unique(pw->pw_uid, uids, num);
3424 /*********************************************************************
3425 _samr_query_groupmem
3426 *********************************************************************/
3428 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3430 int final_num_rids, i;
3432 fstring group_sid_str;
3442 /* find the policy handle. open a policy on it. */
3443 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3444 return NT_STATUS_INVALID_HANDLE;
3446 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3450 sid_to_string(group_sid_str, &group_sid);
3451 DEBUG(10, ("sid is %s\n", group_sid_str));
3453 if (!sid_check_is_in_our_domain(&group_sid)) {
3454 DEBUG(3, ("sid %s is not in our domain\n", group_sid_str));
3455 return NT_STATUS_NO_SUCH_GROUP;
3458 DEBUG(10, ("lookup on Domain SID\n"));
3460 if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &gid)))
3461 return NT_STATUS_NO_SUCH_GROUP;
3463 if(!get_memberuids(gid, &uids, &num))
3464 return NT_STATUS_NO_SUCH_GROUP;
3466 rid=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num);
3467 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num);
3469 if (num!=0 && (rid==NULL || attr==NULL))
3470 return NT_STATUS_NO_MEMORY;
3474 for (i=0; i<num; i++) {
3477 if (!NT_STATUS_IS_OK(uid_to_sid(&sid, uids[i]))) {
3478 DEBUG(1, ("Could not map member uid to SID\n"));
3482 if (!sid_check_is_in_our_domain(&sid)) {
3483 DEBUG(1, ("Inconsistent SAM -- group member uid not "
3484 "in our domain\n"));
3488 sid_peek_rid(&sid, &rid[final_num_rids]);
3490 /* Hmm. In a trace I got the constant 7 here from NT. */
3491 attr[final_num_rids] = SID_NAME_USER;
3493 final_num_rids += 1;
3498 init_samr_r_query_groupmem(r_u, final_num_rids, rid, attr,
3501 return NT_STATUS_OK;
3504 /*********************************************************************
3506 *********************************************************************/
3508 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3513 /* Find the policy handle. Open a policy on it. */
3514 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3515 return NT_STATUS_INVALID_HANDLE;
3517 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3521 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3523 if (!pdb_add_aliasmem(&alias_sid, &q_u->sid.sid))
3524 return NT_STATUS_ACCESS_DENIED;
3526 return NT_STATUS_OK;
3529 /*********************************************************************
3531 *********************************************************************/
3533 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3538 /* Find the policy handle. Open a policy on it. */
3539 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3540 return NT_STATUS_INVALID_HANDLE;
3542 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3546 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
3547 sid_string_static(&alias_sid)));
3549 if (!pdb_del_aliasmem(&alias_sid, &q_u->sid.sid))
3550 return NT_STATUS_ACCESS_DENIED;
3552 return NT_STATUS_OK;
3555 /*********************************************************************
3557 *********************************************************************/
3559 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3563 fstring group_sid_str;
3570 SAM_ACCOUNT *sam_user=NULL;
3574 /* Find the policy handle. Open a policy on it. */
3575 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3576 return NT_STATUS_INVALID_HANDLE;
3578 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3582 sid_to_string(group_sid_str, &group_sid);
3583 DEBUG(10, ("sid is %s\n", group_sid_str));
3585 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3586 return NT_STATUS_NO_SUCH_GROUP;
3588 DEBUG(10, ("lookup on Domain SID\n"));
3590 if(!get_domain_group_from_sid(group_sid, &map))
3591 return NT_STATUS_NO_SUCH_GROUP;
3593 sid_copy(&user_sid, get_global_sam_sid());
3594 sid_append_rid(&user_sid, q_u->rid);
3596 ret = pdb_init_sam(&sam_user);
3597 if (!NT_STATUS_IS_OK(ret))
3600 check = pdb_getsampwsid(sam_user, &user_sid);
3602 if (check != True) {
3603 pdb_free_sam(&sam_user);
3604 return NT_STATUS_NO_SUCH_USER;
3607 /* check a real user exist before we run the script to add a user to a group */
3608 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3609 pdb_free_sam(&sam_user);
3610 return NT_STATUS_NO_SUCH_USER;
3613 pdb_free_sam(&sam_user);
3615 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3616 return NT_STATUS_NO_SUCH_USER;
3619 if ((grp=getgrgid(map.gid)) == NULL) {
3621 return NT_STATUS_NO_SUCH_GROUP;
3624 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3625 fstrcpy(grp_name, grp->gr_name);
3627 /* if the user is already in the group */
3628 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3630 return NT_STATUS_MEMBER_IN_GROUP;
3634 * ok, the group exist, the user exist, the user is not in the group,
3636 * we can (finally) add it to the group !
3639 smb_add_user_group(grp_name, pwd->pw_name);
3641 /* check if the user has been added then ... */
3642 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3644 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3648 return NT_STATUS_OK;
3651 /*********************************************************************
3653 *********************************************************************/
3655 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3659 SAM_ACCOUNT *sam_pass=NULL;
3666 * delete the group member named q_u->rid
3667 * who is a member of the sid associated with the handle
3668 * the rid is a user's rid as the group is a domain group.
3671 /* Find the policy handle. Open a policy on it. */
3672 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3673 return NT_STATUS_INVALID_HANDLE;
3675 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3679 if (!sid_check_is_in_our_domain(&group_sid))
3680 return NT_STATUS_NO_SUCH_GROUP;
3682 sid_copy(&user_sid, get_global_sam_sid());
3683 sid_append_rid(&user_sid, q_u->rid);
3685 if (!get_domain_group_from_sid(group_sid, &map))
3686 return NT_STATUS_NO_SUCH_GROUP;
3688 if ((grp=getgrgid(map.gid)) == NULL)
3689 return NT_STATUS_NO_SUCH_GROUP;
3691 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3692 fstrcpy(grp_name, grp->gr_name);
3694 /* check if the user exists before trying to remove it from the group */
3695 pdb_init_sam(&sam_pass);
3696 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3697 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3698 pdb_free_sam(&sam_pass);
3699 return NT_STATUS_NO_SUCH_USER;
3702 /* if the user is not in the group */
3703 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3704 pdb_free_sam(&sam_pass);
3705 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3708 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3710 /* check if the user has been removed then ... */
3711 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3712 pdb_free_sam(&sam_pass);
3713 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3716 pdb_free_sam(&sam_pass);
3717 return NT_STATUS_OK;
3721 /****************************************************************************
3722 Delete a UNIX user on demand.
3723 ****************************************************************************/
3725 static int smb_delete_user(const char *unix_user)
3730 /* try winbindd first since it is impossible to determine where
3731 a user came from via NSS. Try the delete user script if this fails
3732 meaning the user did not exist in winbindd's list of accounts */
3734 if ( winbind_delete_user( unix_user ) ) {
3735 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3740 /* fall back to 'delete user script' */
3742 pstrcpy(del_script, lp_deluser_script());
3745 all_string_sub(del_script, "%u", unix_user, sizeof(del_script));
3746 ret = smbrun(del_script,NULL);
3747 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3752 /*********************************************************************
3753 _samr_delete_dom_user
3754 *********************************************************************/
3756 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3759 SAM_ACCOUNT *sam_pass=NULL;
3762 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3764 /* Find the policy handle. Open a policy on it. */
3765 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3766 return NT_STATUS_INVALID_HANDLE;
3768 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3772 if (!sid_check_is_in_our_domain(&user_sid))
3773 return NT_STATUS_CANNOT_DELETE;
3775 /* check if the user exists before trying to delete */
3776 pdb_init_sam(&sam_pass);
3777 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3778 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
3779 sid_string_static(&user_sid)));
3780 pdb_free_sam(&sam_pass);
3781 return NT_STATUS_NO_SUCH_USER;
3784 /* First delete the samba side */
3785 if (!pdb_delete_sam_account(sam_pass)) {
3786 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3787 pdb_free_sam(&sam_pass);
3788 return NT_STATUS_CANNOT_DELETE;
3791 /* Now delete the unix side */
3793 * note: we don't check if the delete really happened
3794 * as the script is not necessary present
3795 * and maybe the sysadmin doesn't want to delete the unix side
3797 smb_delete_user(pdb_get_username(sam_pass));
3800 pdb_free_sam(&sam_pass);
3802 if (!close_policy_hnd(p, &q_u->user_pol))
3803 return NT_STATUS_OBJECT_NAME_INVALID;
3805 return NT_STATUS_OK;
3808 /*********************************************************************
3809 _samr_delete_dom_group
3810 *********************************************************************/
3812 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3817 fstring group_sid_str;
3823 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3825 /* Find the policy handle. Open a policy on it. */
3826 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3827 return NT_STATUS_INVALID_HANDLE;
3829 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3833 sid_copy(&dom_sid, &group_sid);
3834 sid_to_string(group_sid_str, &dom_sid);
3835 sid_split_rid(&dom_sid, &group_rid);
3837 DEBUG(10, ("sid is %s\n", group_sid_str));
3839 /* we check if it's our SID before deleting */
3840 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3841 return NT_STATUS_NO_SUCH_GROUP;
3843 DEBUG(10, ("lookup on Domain SID\n"));
3845 if(!get_domain_group_from_sid(group_sid, &map))
3846 return NT_STATUS_NO_SUCH_GROUP;
3850 /* check if group really exists */
3851 if ( (grp=getgrgid(gid)) == NULL)
3852 return NT_STATUS_NO_SUCH_GROUP;
3854 /* delete mapping first */
3855 if(!pdb_delete_group_mapping_entry(group_sid))
3856 return NT_STATUS_ACCESS_DENIED;
3858 /* we can delete the UNIX group */
3859 smb_delete_group(grp->gr_name);
3861 /* check if the group has been successfully deleted */
3862 if ( (grp=getgrgid(gid)) != NULL)
3863 return NT_STATUS_ACCESS_DENIED;
3866 if (!close_policy_hnd(p, &q_u->group_pol))
3867 return NT_STATUS_OBJECT_NAME_INVALID;
3869 return NT_STATUS_OK;
3872 /*********************************************************************
3873 _samr_delete_dom_alias
3874 *********************************************************************/
3876 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3881 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3883 /* Find the policy handle. Open a policy on it. */
3884 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3885 return NT_STATUS_INVALID_HANDLE;
3887 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3891 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3893 if (!sid_check_is_in_our_domain(&alias_sid))
3894 return NT_STATUS_NO_SUCH_ALIAS;
3896 DEBUG(10, ("lookup on Local SID\n"));
3898 /* Have passdb delete the alias */
3899 if (!pdb_delete_alias(&alias_sid))
3900 return NT_STATUS_ACCESS_DENIED;
3902 if (!close_policy_hnd(p, &q_u->alias_pol))
3903 return NT_STATUS_OBJECT_NAME_INVALID;
3905 return NT_STATUS_OK;
3908 /*********************************************************************
3909 _samr_create_dom_group
3910 *********************************************************************/
3912 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3919 struct samr_info *info;
3923 /* Find the policy handle. Open a policy on it. */
3924 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3925 return NT_STATUS_INVALID_HANDLE;
3927 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3931 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3932 return NT_STATUS_ACCESS_DENIED;
3934 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3936 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3938 /* check if group already exist */
3939 if ((grp=getgrnam(name)) != NULL)
3940 return NT_STATUS_GROUP_EXISTS;
3942 /* we can create the UNIX group */
3943 if (smb_create_group(name, &gid) != 0)
3944 return NT_STATUS_ACCESS_DENIED;
3946 /* check if the group has been successfully created */
3947 if ((grp=getgrgid(gid)) == NULL)
3948 return NT_STATUS_ACCESS_DENIED;
3950 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3952 /* add the group to the mapping table */
3953 sid_copy(&info_sid, get_global_sam_sid());
3954 sid_append_rid(&info_sid, r_u->rid);
3955 sid_to_string(sid_string, &info_sid);
3957 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
3958 return NT_STATUS_ACCESS_DENIED;
3960 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3961 return NT_STATUS_NO_MEMORY;
3963 /* get a (unique) handle. open a policy on it. */
3964 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3965 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3967 return NT_STATUS_OK;
3970 /*********************************************************************
3971 _samr_create_dom_alias
3972 *********************************************************************/
3974 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3980 struct samr_info *info;
3985 /* Find the policy handle. Open a policy on it. */
3986 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
3987 return NT_STATUS_INVALID_HANDLE;
3989 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3993 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3994 return NT_STATUS_ACCESS_DENIED;
3996 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3998 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4000 /* Have passdb create the alias */
4001 result = pdb_create_alias(name, &r_u->rid);
4003 if (!NT_STATUS_IS_OK(result))
4006 sid_copy(&info_sid, get_global_sam_sid());
4007 sid_append_rid(&info_sid, r_u->rid);
4009 if (!NT_STATUS_IS_OK(sid_to_gid(&info_sid, &gid)))
4010 return NT_STATUS_ACCESS_DENIED;
4012 /* check if the group has been successfully created */
4013 if ((grp=getgrgid(gid)) == NULL)
4014 return NT_STATUS_ACCESS_DENIED;
4016 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4017 return NT_STATUS_NO_MEMORY;
4019 /* get a (unique) handle. open a policy on it. */
4020 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4021 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4023 return NT_STATUS_OK;
4026 /*********************************************************************
4027 _samr_query_groupinfo
4029 sends the name/comment pair of a domain group
4030 level 1 send also the number of users of that group
4031 *********************************************************************/
4033 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4040 GROUP_INFO_CTR *ctr;
4044 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4045 return NT_STATUS_INVALID_HANDLE;
4047 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4052 ret = get_domain_group_from_sid(group_sid, &map);
4055 return NT_STATUS_INVALID_HANDLE;
4057 ctr=TALLOC_ZERO_P(p->mem_ctx, GROUP_INFO_CTR);
4059 return NT_STATUS_NO_MEMORY;
4061 switch (q_u->switch_level) {
4063 ctr->switch_value1 = 1;
4064 if(!get_memberuids(map.gid, &uids, &num))
4065 return NT_STATUS_NO_SUCH_GROUP;
4067 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num);
4071 ctr->switch_value1 = 3;
4072 init_samr_group_info3(&ctr->group.info3);
4075 ctr->switch_value1 = 4;
4076 init_samr_group_info4(&ctr->group.info4, map.comment);
4079 return NT_STATUS_INVALID_INFO_CLASS;
4082 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4084 return NT_STATUS_OK;
4087 /*********************************************************************
4090 update a domain group's comment.
4091 *********************************************************************/
4093 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4097 GROUP_INFO_CTR *ctr;
4100 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4101 return NT_STATUS_INVALID_HANDLE;
4103 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4107 if (!get_domain_group_from_sid(group_sid, &map))
4108 return NT_STATUS_NO_SUCH_GROUP;
4112 switch (ctr->switch_value1) {
4114 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4117 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4120 return NT_STATUS_INVALID_INFO_CLASS;
4123 if(!pdb_update_group_mapping_entry(&map)) {
4124 return NT_STATUS_NO_SUCH_GROUP;
4127 return NT_STATUS_OK;
4130 /*********************************************************************
4133 update an alias's comment.
4134 *********************************************************************/
4136 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4139 struct acct_info info;
4140 ALIAS_INFO_CTR *ctr;
4143 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4144 return NT_STATUS_INVALID_HANDLE;
4146 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4152 switch (ctr->switch_value1) {
4154 unistr2_to_ascii(info.acct_desc,
4155 &(ctr->alias.info3.uni_acct_desc),
4156 sizeof(info.acct_desc)-1);
4159 return NT_STATUS_INVALID_INFO_CLASS;
4162 if(!pdb_set_aliasinfo(&group_sid, &info)) {
4163 return NT_STATUS_ACCESS_DENIED;
4166 return NT_STATUS_OK;
4169 /*********************************************************************
4170 _samr_get_dom_pwinfo
4171 *********************************************************************/
4173 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4175 /* Perform access check. Since this rpc does not require a
4176 policy handle it will not be caught by the access checks on
4177 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4179 if (!pipe_access_check(p)) {
4180 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4181 r_u->status = NT_STATUS_ACCESS_DENIED;
4185 /* Actually, returning zeros here works quite well :-). */
4187 return NT_STATUS_OK;
4190 /*********************************************************************
4192 *********************************************************************/
4194 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4199 struct samr_info *info;
4200 SEC_DESC *psd = NULL;
4202 uint32 des_access = q_u->access_mask;
4208 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4209 return NT_STATUS_INVALID_HANDLE;
4211 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4215 /*check if access can be granted as requested by client. */
4216 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4217 se_map_generic(&des_access,&grp_generic_mapping);
4218 if (!NT_STATUS_IS_OK(status =
4219 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4220 des_access, &acc_granted, "_samr_open_group"))) {
4225 /* this should not be hard-coded like this */
4226 if (!sid_equal(&sid, get_global_sam_sid()))
4227 return NT_STATUS_ACCESS_DENIED;
4229 sid_copy(&info_sid, get_global_sam_sid());
4230 sid_append_rid(&info_sid, q_u->rid_group);
4231 sid_to_string(sid_string, &info_sid);
4233 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4234 return NT_STATUS_NO_MEMORY;
4236 info->acc_granted = acc_granted;
4238 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4240 /* check if that group really exists */
4242 ret = get_domain_group_from_sid(info->sid, &map);
4245 return NT_STATUS_NO_SUCH_GROUP;
4247 /* get a (unique) handle. open a policy on it. */
4248 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4249 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4251 return NT_STATUS_OK;
4254 /*********************************************************************
4255 _samr_remove_sid_foreign_domain
4256 *********************************************************************/
4258 NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p,
4259 SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u,
4260 SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
4262 DOM_SID delete_sid, alias_sid;
4263 SAM_ACCOUNT *sam_pass=NULL;
4266 BOOL is_user = False;
4268 enum SID_NAME_USE type = SID_NAME_UNKNOWN;
4270 sid_copy( &delete_sid, &q_u->sid.sid );
4272 DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4273 sid_string_static(&delete_sid)));
4275 /* Find the policy handle. Open a policy on it. */
4277 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted))
4278 return NT_STATUS_INVALID_HANDLE;
4280 result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS,
4281 "_samr_remove_sid_foreign_domain");
4283 if (!NT_STATUS_IS_OK(result))
4286 DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n",
4287 sid_string_static(&alias_sid)));
4289 /* make sure we can handle this */
4291 if ( sid_check_is_domain(&alias_sid) )
4292 type = SID_NAME_DOM_GRP;
4293 else if ( sid_check_is_builtin(&alias_sid) )
4294 type = SID_NAME_ALIAS;
4296 if ( type == SID_NAME_UNKNOWN ) {
4297 DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
4298 return NT_STATUS_OK;
4301 /* check if the user exists before trying to delete */
4303 pdb_init_sam(&sam_pass);
4305 if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
4308 /* maybe it is a group */
4309 if( !pdb_getgrsid(&map, delete_sid) ) {
4310 DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
4311 sid_string_static(&delete_sid)));
4312 result = NT_STATUS_INVALID_SID;
4317 /* we can only delete a user from a group since we don't have
4318 nested groups anyways. So in the latter case, just say OK */
4321 GROUP_MAP *mappings = NULL;
4325 if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
4327 /* interate over the groups */
4328 for ( i=0; i<num_groups; i++ ) {
4330 grp2 = getgrgid(mappings[i].gid);
4333 DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
4337 if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
4340 smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
4342 if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
4343 /* should we fail here ? */
4344 DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
4345 pdb_get_username(sam_pass), grp2->gr_name ));
4349 DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
4350 pdb_get_username(sam_pass), grp2->gr_name ));
4353 SAFE_FREE(mappings);
4357 result = NT_STATUS_OK;
4360 pdb_free_sam(&sam_pass);
4365 /*******************************************************************
4367 ********************************************************************/
4369 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4371 struct samr_info *info = NULL;
4373 uint32 min_pass_len,pass_hist,flag;
4374 time_t u_expire, u_min_age;
4375 NTTIME nt_expire, nt_min_age;
4377 time_t u_lock_duration, u_reset_time;
4378 NTTIME nt_lock_duration, nt_reset_time;
4384 uint32 num_users=0, num_groups=0, num_aliases=0;
4386 uint32 account_policy_temp;
4388 if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
4389 return NT_STATUS_NO_MEMORY;
4393 r_u->status = NT_STATUS_OK;
4395 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4397 /* find the policy handle. open a policy on it. */
4398 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4399 return NT_STATUS_INVALID_HANDLE;
4401 switch (q_u->switch_value) {
4403 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4404 min_pass_len = account_policy_temp;
4406 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4407 pass_hist = account_policy_temp;
4409 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4410 flag = account_policy_temp;
4412 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4413 u_expire = account_policy_temp;
4415 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4416 u_min_age = account_policy_temp;
4418 unix_to_nt_time_abs(&nt_expire, u_expire);
4419 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4421 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4422 flag, nt_expire, nt_min_age);
4426 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4428 if (!NT_STATUS_IS_OK(r_u->status)) {
4429 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4432 num_users=info->disp_info.num_user_account;
4435 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4436 if (NT_STATUS_IS_ERR(r_u->status)) {
4437 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4440 num_groups=info->disp_info.num_group_account;
4443 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4444 u_logout = account_policy_temp;
4446 unix_to_nt_time_abs(&nt_logout, u_logout);
4448 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4449 init_unk_info2(&ctr->info.inf2, "", lp_workgroup(), global_myname(), (uint32) time(NULL),
4450 num_users, num_groups, num_aliases, nt_logout);
4453 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4454 u_logout = account_policy_temp;
4456 unix_to_nt_time_abs(&nt_logout, u_logout);
4458 init_unk_info3(&ctr->info.inf3, nt_logout);
4461 init_unk_info5(&ctr->info.inf5, global_myname());
4464 init_unk_info6(&ctr->info.inf6);
4467 init_unk_info7(&ctr->info.inf7);
4470 init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
4473 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4474 u_lock_duration = account_policy_temp;
4475 if (u_lock_duration != -1)
4476 u_lock_duration *= 60;
4478 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4479 u_reset_time = account_policy_temp * 60;
4481 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4482 lockout = account_policy_temp;
4484 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4485 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4487 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4490 return NT_STATUS_INVALID_INFO_CLASS;
4493 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4495 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4500 /*******************************************************************
4502 ********************************************************************/
4504 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4506 time_t u_expire, u_min_age;
4508 time_t u_lock_duration, u_reset_time;
4510 r_u->status = NT_STATUS_OK;
4512 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4514 /* find the policy handle. open a policy on it. */
4515 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4516 return NT_STATUS_INVALID_HANDLE;
4518 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4520 switch (q_u->switch_value) {
4522 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4523 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4525 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4526 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4527 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4528 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4529 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4534 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4535 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4544 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4545 if (u_lock_duration != -1)
4546 u_lock_duration /= 60;
4547 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
4549 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4550 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4551 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4554 return NT_STATUS_INVALID_INFO_CLASS;
4557 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4559 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));