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) Anthony Liguori 2002,
11 * Copyright (C) Jim McDonough 2002.
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 DISP_USER_INFO *disp_user_info;
49 uint32 num_group_account;
50 DISP_GROUP_INFO *disp_group_info;
54 /* for use by the \PIPE\samr policy */
56 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
65 struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
66 struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
67 struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
68 struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
69 struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
71 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
73 /*******************************************************************
74 Checks if access to an object should be granted, and returns that
75 level of access for further checks.
76 ********************************************************************/
78 NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_token, uint32 des_access,
79 uint32 *acc_granted, const char *debug)
81 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
83 if (!se_access_check(psd, nt_user_token, des_access, acc_granted, &status)) {
84 if (geteuid() == sec_initial_uid()) {
85 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n",
87 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
88 status = NT_STATUS_OK;
91 DEBUG(2,("%s: ACCESS DENIED (requested: %#010x)\n",
98 /*******************************************************************
99 Checks if access to a function can be granted
100 ********************************************************************/
102 NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
104 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
105 debug, acc_granted, acc_required));
106 if ((acc_granted & acc_required) != acc_required) {
107 if (geteuid() == sec_initial_uid()) {
108 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
109 debug, acc_granted, acc_required));
110 DEBUGADD(4,("but overwritten by euid == 0\n"));
113 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
114 debug, acc_granted, acc_required));
115 return NT_STATUS_ACCESS_DENIED;
121 /*******************************************************************
122 Create a samr_info struct.
123 ********************************************************************/
125 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
127 struct samr_info *info;
132 sid_to_string(sid_str, psid);
134 fstrcpy(sid_str,"(NULL)");
137 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
139 if ((info = (struct samr_info *)talloc(mem_ctx, sizeof(struct samr_info))) == NULL)
143 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
145 sid_copy( &info->sid, psid);
147 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
149 info->mem_ctx = mem_ctx;
154 /*******************************************************************
155 Function to free the per handle data.
156 ********************************************************************/
157 static void free_samr_users(struct samr_info *info)
161 if (info->disp_info.user_dbloaded){
162 for (i=0; i<info->disp_info.num_user_account; i++) {
163 /* Not really a free, actually a 'clear' */
164 pdb_free_sam(&info->disp_info.disp_user_info[i].sam);
167 info->disp_info.user_dbloaded=False;
168 info->disp_info.num_user_account=0;
172 /*******************************************************************
173 Function to free the per handle data.
174 ********************************************************************/
175 static void free_samr_db(struct samr_info *info)
177 /* Groups are talloced */
179 free_samr_users(info);
181 info->disp_info.group_dbloaded=False;
182 info->disp_info.num_group_account=0;
186 static void free_samr_info(void *ptr)
188 struct samr_info *info=(struct samr_info *) ptr;
191 talloc_destroy(info->mem_ctx);
194 /*******************************************************************
195 Ensure password info is never given out. Paranioa... JRA.
196 ********************************************************************/
198 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
204 /* These now zero out the old password */
206 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
207 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
211 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL all_machines)
213 SAM_ACCOUNT *pwd = NULL;
214 DISP_USER_INFO *pwd_array = NULL;
215 NTSTATUS nt_status = NT_STATUS_OK;
216 TALLOC_CTX *mem_ctx = info->mem_ctx;
218 DEBUG(10,("load_sampwd_entries\n"));
220 /* if the snapshoot is already loaded, return */
221 if ((info->disp_info.user_dbloaded==True)
222 && (info->acb_mask == acb_mask)
223 && (info->all_machines == all_machines)) {
224 DEBUG(10,("load_sampwd_entries: already in memory\n"));
228 free_samr_users(info);
230 if (!pdb_setsampwent(False)) {
231 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
232 return NT_STATUS_ACCESS_DENIED;
235 for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd)))
236 && pdb_getsampwent(pwd) == True; pwd=NULL) {
239 if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST)
240 || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
241 DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
246 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
248 DEBUG(5,(" acb_mask %x reject\n", acb_mask));
253 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
254 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
256 DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
257 pwd_array=(DISP_USER_INFO *)talloc_realloc(mem_ctx, info->disp_info.disp_user_info,
258 (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(DISP_USER_INFO));
261 return NT_STATUS_NO_MEMORY;
263 info->disp_info.disp_user_info=pwd_array;
266 /* link the SAM_ACCOUNT to the array */
267 info->disp_info.disp_user_info[info->disp_info.num_user_account].sam=pwd;
269 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
271 info->disp_info.num_user_account++;
276 /* the snapshoot is in memory, we're ready to enumerate fast */
278 info->acb_mask = acb_mask;
279 info->all_machines = all_machines;
280 info->disp_info.user_dbloaded=True;
282 DEBUG(10,("load_sampwd_entries: done\n"));
287 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
290 DISP_GROUP_INFO *grp_array = NULL;
291 uint32 group_entries = 0;
293 TALLOC_CTX *mem_ctx = info->mem_ctx;
295 DEBUG(10,("load_group_domain_entries\n"));
297 /* if the snapshoot is already loaded, return */
298 if (info->disp_info.group_dbloaded==True) {
299 DEBUG(10,("load_group_domain_entries: already in memory\n"));
303 if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV)) {
304 DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
305 return NT_STATUS_NO_MEMORY;
308 info->disp_info.num_group_account=group_entries;
310 grp_array=(DISP_GROUP_INFO *)talloc(mem_ctx, info->disp_info.num_group_account*sizeof(DISP_GROUP_INFO));
312 if (group_entries!=0 && grp_array==NULL) {
313 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
315 return NT_STATUS_NO_MEMORY;
318 info->disp_info.disp_group_info=grp_array;
320 for (i=0; i<group_entries; i++) {
322 grp_array[i].grp=(DOMAIN_GRP *)talloc(mem_ctx, sizeof(DOMAIN_GRP));
324 fstrcpy(grp_array[i].grp->name, map[i].nt_name);
325 fstrcpy(grp_array[i].grp->comment, map[i].comment);
326 sid_split_rid(&map[i].sid, &grp_array[i].grp->rid);
327 grp_array[i].grp->attr=SID_NAME_DOM_GRP;
332 /* the snapshoot is in memory, we're ready to enumerate fast */
334 info->disp_info.group_dbloaded=True;
336 DEBUG(10,("load_group_domain_entries: done\n"));
342 /*******************************************************************
344 ********************************************************************/
346 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
348 r_u->status = NT_STATUS_OK;
350 /* close the policy handle */
351 if (!close_policy_hnd(p, &q_u->pol))
352 return NT_STATUS_OBJECT_NAME_INVALID;
354 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
359 /*******************************************************************
360 samr_reply_open_domain
361 ********************************************************************/
363 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
365 struct samr_info *info;
366 SEC_DESC *psd = NULL;
368 uint32 des_access = q_u->flags;
372 r_u->status = NT_STATUS_OK;
374 /* find the connection policy handle. */
375 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
376 return NT_STATUS_INVALID_HANDLE;
378 if (!NT_STATUS_IS_OK(status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN,"_samr_open_domain"))) {
382 /*check if access can be granted as requested by client. */
383 samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
384 se_map_generic(&des_access,&dom_generic_mapping);
386 if (!NT_STATUS_IS_OK(status =
387 access_check_samr_object(psd, p->pipe_user.nt_user_token,
388 des_access, &acc_granted, "_samr_open_domain"))) {
392 /* associate the domain SID with the (unique) handle. */
393 if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
394 return NT_STATUS_NO_MEMORY;
395 info->acc_granted = acc_granted;
397 /* get a (unique) handle. open a policy on it. */
398 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
399 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
401 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
406 /*******************************************************************
407 _samr_get_usrdom_pwinfo
408 ********************************************************************/
410 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
412 struct samr_info *info = NULL;
414 r_u->status = NT_STATUS_OK;
416 /* find the policy handle. open a policy on it. */
417 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
418 return NT_STATUS_INVALID_HANDLE;
420 if (!sid_check_is_in_our_domain(&info->sid))
421 return NT_STATUS_OBJECT_TYPE_MISMATCH;
423 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
425 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
428 * NT sometimes return NT_STATUS_ACCESS_DENIED
429 * I don't know yet why.
435 /*******************************************************************
437 ********************************************************************/
439 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
441 extern DOM_SID global_sid_World;
450 sid_copy(&adm_sid, &global_sid_Builtin);
451 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
453 sid_copy(&act_sid, &global_sid_Builtin);
454 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
456 /*basic access for every one*/
457 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
458 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
460 /*full access for builtin aliases Administrators and Account Operators*/
461 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS);
462 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
463 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
465 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
466 return NT_STATUS_NO_MEMORY;
468 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
469 return NT_STATUS_NO_MEMORY;
474 /*******************************************************************
476 ********************************************************************/
478 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
480 extern DOM_SID global_sid_World;
489 sid_copy(&adm_sid, &global_sid_Builtin);
490 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
492 sid_copy(&act_sid, &global_sid_Builtin);
493 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
495 /*basic access for every one*/
496 init_sec_access(&mask, GENERIC_RIGHTS_USER_EXECUTE | GENERIC_RIGHTS_USER_READ);
497 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
499 /*full access for builtin aliases Administrators and Account Operators*/
500 init_sec_access(&mask, GENERIC_RIGHTS_USER_ALL_ACCESS);
501 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
502 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
504 /*extended access for the user*/
505 init_sec_access(&mask,READ_CONTROL_ACCESS | SA_RIGHT_USER_CHANGE_PASSWORD | SA_RIGHT_USER_SET_LOC_COM);
506 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
508 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
509 return NT_STATUS_NO_MEMORY;
511 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
512 return NT_STATUS_NO_MEMORY;
517 /*******************************************************************
519 ********************************************************************/
521 static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
523 extern DOM_SID global_sid_World;
532 sid_copy(&adm_sid, &global_sid_Builtin);
533 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
535 sid_copy(&act_sid, &global_sid_Builtin);
536 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
538 /*basic access for every one*/
539 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
540 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
542 /*full access for builtin aliases Administrators and Account Operators*/
543 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_ALL_ACCESS);
544 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
545 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
547 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
548 return NT_STATUS_NO_MEMORY;
550 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
551 return NT_STATUS_NO_MEMORY;
556 /*******************************************************************
558 ********************************************************************/
560 static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
562 extern DOM_SID global_sid_World;
571 sid_copy(&adm_sid, &global_sid_Builtin);
572 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
574 sid_copy(&act_sid, &global_sid_Builtin);
575 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
577 /*basic access for every one*/
578 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
579 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
581 /*full access for builtin aliases Administrators and Account Operators*/
582 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_ALL_ACCESS);
583 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
584 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
586 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
587 return NT_STATUS_NO_MEMORY;
589 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
590 return NT_STATUS_NO_MEMORY;
595 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
597 struct samr_info *info = NULL;
599 /* find the policy handle. open a policy on it. */
600 if (!find_policy_by_hnd(p, pol, (void **)&info))
607 *acc_granted = info->acc_granted;
611 /*******************************************************************
613 ********************************************************************/
615 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
617 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
618 return NT_STATUS_NOT_IMPLEMENTED;
622 /*******************************************************************
624 ********************************************************************/
626 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
630 SEC_DESC * psd = NULL;
634 r_u->status = NT_STATUS_OK;
637 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
638 return NT_STATUS_INVALID_HANDLE;
642 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
644 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
646 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
647 if (pol_sid.sid_rev_num == 0)
649 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
650 r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
652 else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */
655 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
656 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
658 else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */
660 /* TODO: Builtin probably needs a different SD with restricted write access*/
661 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
662 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
664 else if (sid_check_is_in_our_domain(&pol_sid) ||
665 sid_check_is_in_builtin(&pol_sid))
667 /* TODO: different SDs have to be generated for aliases groups and users.
668 Currently all three get a default user SD */
669 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
670 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
672 else return NT_STATUS_OBJECT_TYPE_MISMATCH;
674 if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
675 return NT_STATUS_NO_MEMORY;
677 if (NT_STATUS_IS_OK(r_u->status))
683 /*******************************************************************
684 makes a SAM_ENTRY / UNISTR2* structure from a user list.
685 ********************************************************************/
687 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
688 uint32 num_entries, uint32 start_idx, DISP_USER_INFO *disp_user_info,
694 SAM_ACCOUNT *pwd = NULL;
695 UNISTR2 uni_temp_name;
696 const char *temp_name;
697 const DOM_SID *user_sid;
699 fstring user_sid_string;
700 fstring domain_sid_string;
705 if (num_entries == 0)
708 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_entries);
710 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_entries);
712 if (sam == NULL || uni_name == NULL) {
713 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
714 return NT_STATUS_NO_MEMORY;
717 for (i = 0; i < num_entries; i++) {
718 pwd = disp_user_info[i+start_idx].sam;
719 temp_name = pdb_get_username(pwd);
720 init_unistr2(&uni_temp_name, temp_name, strlen(temp_name)+1);
721 user_sid = pdb_get_user_sid(pwd);
723 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
724 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
725 "the domain sid %s. Failing operation.\n",
727 sid_to_string(user_sid_string, user_sid),
728 sid_to_string(domain_sid_string, domain_sid)));
729 return NT_STATUS_UNSUCCESSFUL;
732 init_sam_entry(&sam[i], uni_temp_name.uni_str_len, user_rid);
733 copy_unistr2(&uni_name[i], &uni_temp_name);
737 *uni_name_pp = uni_name;
741 /*******************************************************************
742 samr_reply_enum_dom_users
743 ********************************************************************/
745 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
746 SAMR_R_ENUM_DOM_USERS *r_u)
748 struct samr_info *info = NULL;
749 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
751 uint32 enum_context=q_u->start_idx;
752 uint32 max_size=q_u->max_size;
754 enum remote_arch_types ra_type = get_remote_arch();
755 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
756 uint32 max_entries = max_sam_entries;
759 r_u->status = NT_STATUS_OK;
761 /* find the policy handle. open a policy on it. */
762 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
763 return NT_STATUS_INVALID_HANDLE;
765 domain_sid = info->sid;
767 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
768 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
769 "_samr_enum_dom_users"))) {
773 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
776 r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
779 if (!NT_STATUS_IS_OK(r_u->status))
782 num_account = info->disp_info.num_user_account;
784 if (enum_context > num_account) {
785 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
789 /* verify we won't overflow */
790 if (max_entries > num_account-enum_context) {
791 max_entries = num_account-enum_context;
792 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
795 /* calculate the size and limit on the number of entries we will return */
796 temp_size=max_entries*struct_size;
798 if (temp_size>max_size) {
799 max_entries=MIN((max_size/struct_size),max_entries);;
800 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
804 * Note from JRA. total_entries is not being used here. Currently if there is a
805 * large user base then it looks like NT will enumerate until get_sampwd_entries
806 * returns False due to num_entries being zero. This will cause an access denied
807 * return. I don't think this is right and needs further investigation. Note that
808 * this is also the same in the TNG code (I don't think that has been tested with
809 * a very large user list as MAX_SAM_ENTRIES is set to 600).
811 * I also think that one of the 'num_entries' return parameters is probably
812 * the "max entries" parameter - but in the TNG code they're all currently set to the same
813 * value (again I think this is wrong).
816 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
817 max_entries, enum_context,
818 info->disp_info.disp_user_info,
821 if (!NT_STATUS_IS_OK(r_u->status))
824 if (enum_context+max_entries < num_account)
825 r_u->status = STATUS_MORE_ENTRIES;
827 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
829 init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
831 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
836 /*******************************************************************
837 makes a SAM_ENTRY / UNISTR2* structure from a group list.
838 ********************************************************************/
840 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
841 uint32 num_sam_entries, DOMAIN_GRP *grp)
850 if (num_sam_entries == 0)
853 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
855 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
857 if (sam == NULL || uni_name == NULL) {
858 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
862 for (i = 0; i < num_sam_entries; i++) {
864 * JRA. I think this should include the null. TNG does not.
866 int len = strlen(grp[i].name)+1;
868 init_sam_entry(&sam[i], len, grp[i].rid);
869 init_unistr2(&uni_name[i], grp[i].name, len);
873 *uni_name_pp = uni_name;
876 /*******************************************************************
877 Get the group entries - similar to get_sampwd_entries().
878 ********************************************************************/
880 static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
881 uint32 *p_num_entries, uint32 max_entries)
884 uint32 num_entries = 0;
887 GROUP_MAP *map = NULL;
889 sid_to_string(sid_str, sid);
890 DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str));
894 /* well-known aliases */
895 if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
897 pdb_enum_group_mapping(SID_NAME_WKN_GRP, &map, (int *)&num_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
899 if (num_entries != 0) {
900 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
902 return NT_STATUS_NO_MEMORY;
904 for(i=0; i<num_entries && i<max_entries; i++) {
905 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
906 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
912 } else if (sid_equal(sid, get_global_sam_sid()) && !lp_hide_local_users()) {
913 struct sys_grent *glist;
914 struct sys_grent *grp;
916 gid_t winbind_gid_low, winbind_gid_high;
917 BOOL winbind_groups_exist = lp_winbind_gid(&winbind_gid_low, &winbind_gid_high);
920 /* we return the UNIX groups here. This seems to be the right */
921 /* thing to do, since NT member servers return their local */
922 /* groups in the same situation. */
924 /* use getgrent_list() to retrieve the list of groups to avoid
925 * problems with getgrent possible infinite loop by internal
926 * libc grent structures overwrites by called functions */
927 grp = glist = getgrent_list();
929 return NT_STATUS_NO_MEMORY;
931 for (; (num_entries < max_entries) && (grp != NULL); grp = grp->next) {
934 if(!pdb_getgrgid(&smap, grp->gr_gid, MAPPING_WITHOUT_PRIV))
937 if (smap.sid_name_use!=SID_NAME_ALIAS) {
941 sid_split_rid(&smap.sid, &trid);
943 if (!sid_equal(sid, &smap.sid))
946 /* Don't return winbind groups as they are not local! */
947 if (winbind_groups_exist && (grp->gr_gid >= winbind_gid_low)&&(grp->gr_gid <= winbind_gid_high)) {
948 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
952 /* Don't return user private groups... */
954 if ((pw = Get_Pwnam(smap.nt_name)) != 0) {
955 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
959 for( i = 0; i < num_entries; i++)
960 if ( (*d_grp)[i].rid == trid )
963 if ( i < num_entries ) {
964 continue; /* rid was there, dup! */
967 /* JRA - added this for large group db enumeration... */
970 /* skip the requested number of entries.
971 not very efficient, but hey...
977 *d_grp=talloc_realloc(ctx,*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
980 return NT_STATUS_NO_MEMORY;
983 fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
984 (*d_grp)[num_entries].rid = trid;
986 DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries, trid));
992 *p_num_entries = num_entries;
994 DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries));
996 if (num_entries >= max_entries)
997 return STATUS_MORE_ENTRIES;
1001 /*******************************************************************
1002 Get the group entries - similar to get_sampwd_entries().
1003 ********************************************************************/
1005 static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
1006 uint32 *p_num_entries, uint32 max_entries)
1008 GROUP_MAP *map=NULL;
1010 uint32 group_entries = 0;
1011 uint32 num_entries = 0;
1015 pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
1017 num_entries=group_entries-start_idx;
1019 /* limit the number of entries */
1020 if (num_entries>max_entries) {
1021 DEBUG(5,("Limiting to %d entries\n", max_entries));
1022 num_entries=max_entries;
1025 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
1026 if (num_entries!=0 && *d_grp==NULL){
1028 return NT_STATUS_NO_MEMORY;
1031 for (i=0; i<num_entries; i++) {
1032 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
1033 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
1034 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
1035 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
1040 *p_num_entries = num_entries;
1042 return NT_STATUS_OK;
1045 /*******************************************************************
1046 samr_reply_enum_dom_groups
1047 ********************************************************************/
1049 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
1051 DOMAIN_GRP *grp=NULL;
1056 r_u->status = NT_STATUS_OK;
1058 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1059 return NT_STATUS_INVALID_HANDLE;
1061 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
1065 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1067 /* the domain group array is being allocated in the function below */
1068 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))) {
1072 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1074 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
1076 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1082 /*******************************************************************
1083 samr_reply_enum_dom_aliases
1084 ********************************************************************/
1086 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1088 DOMAIN_GRP *grp=NULL;
1089 uint32 num_entries = 0;
1095 r_u->status = NT_STATUS_OK;
1097 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1098 return NT_STATUS_INVALID_HANDLE;
1100 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1104 sid_to_string(sid_str, &sid);
1105 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1107 status = get_group_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1108 &num_entries, MAX_SAM_ENTRIES);
1109 if (NT_STATUS_IS_ERR(status)) return status;
1111 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1115 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1117 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1122 /*******************************************************************
1123 samr_reply_query_dispinfo
1124 ********************************************************************/
1125 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1126 SAMR_R_QUERY_DISPINFO *r_u)
1128 struct samr_info *info = NULL;
1129 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1131 uint32 max_entries=q_u->max_entries;
1132 uint32 enum_context=q_u->start_idx;
1133 uint32 max_size=q_u->max_size;
1135 SAM_DISPINFO_CTR *ctr;
1136 uint32 temp_size=0, total_data_size=0;
1138 uint32 num_account = 0;
1139 enum remote_arch_types ra_type = get_remote_arch();
1140 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1143 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1144 r_u->status = NT_STATUS_OK;
1146 /* find the policy handle. open a policy on it. */
1147 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1148 return NT_STATUS_INVALID_HANDLE;
1150 domain_sid = info->sid;
1153 * calculate how many entries we will return.
1155 * - the number of entries the client asked
1156 * - our limit on that
1157 * - the starting point (enumeration context)
1158 * - the buffer size the client will accept
1162 * We are a lot more like W2K. Instead of reading the SAM
1163 * each time to find the records we need to send back,
1164 * we read it once and link that copy to the sam handle.
1165 * For large user list (over the MAX_SAM_ENTRIES)
1166 * it's a definitive win.
1167 * second point to notice: between enumerations
1168 * our sam is now the same as it's a snapshoot.
1169 * third point: got rid of the static SAM_USER_21 struct
1170 * no more intermediate.
1171 * con: it uses much more memory, as a full copy is stored
1174 * If you want to change it, think twice and think
1175 * of the second point , that's really important.
1180 /* Get what we need from the password database */
1181 switch (q_u->switch_level) {
1183 /* When playing with usrmgr, this is necessary
1184 if you want immediate refresh after editing
1185 a user. I would like to do this after the
1186 setuserinfo2, but we do not have access to
1187 the domain handle in that call, only to the
1188 user handle. Where else does this hurt?
1192 /* We cannot do this here - it kills performace. JRA. */
1193 free_samr_users(info);
1198 /* Level 2 is for all machines, otherwise only 'normal' users */
1199 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1201 if (!NT_STATUS_IS_OK(r_u->status)) {
1202 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1205 num_account = info->disp_info.num_user_account;
1209 r_u->status = load_group_domain_entries(info, &info->sid);
1210 if (!NT_STATUS_IS_OK(r_u->status))
1212 num_account = info->disp_info.num_group_account;
1215 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1216 return NT_STATUS_INVALID_INFO_CLASS;
1219 /* first limit the number of entries we will return */
1220 if(max_entries > max_sam_entries) {
1221 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1222 max_entries = max_sam_entries;
1225 if (enum_context > num_account) {
1226 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1227 return NT_STATUS_NO_MORE_ENTRIES;
1230 /* verify we won't overflow */
1231 if (max_entries > num_account-enum_context) {
1232 max_entries = num_account-enum_context;
1233 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1236 /* calculate the size and limit on the number of entries we will return */
1237 temp_size=max_entries*struct_size;
1239 if (temp_size>max_size) {
1240 max_entries=MIN((max_size/struct_size),max_entries);;
1241 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1244 if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1245 return NT_STATUS_NO_MEMORY;
1249 /* Now create reply structure */
1250 switch (q_u->switch_level) {
1253 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
1254 return NT_STATUS_NO_MEMORY;
1256 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1257 info->disp_info.disp_user_info, &domain_sid);
1258 if (!NT_STATUS_IS_OK(disp_ret))
1263 if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1264 return NT_STATUS_NO_MEMORY;
1266 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1267 info->disp_info.disp_user_info, &domain_sid);
1268 if (!NT_STATUS_IS_OK(disp_ret))
1273 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1274 return NT_STATUS_NO_MEMORY;
1276 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1277 if (!NT_STATUS_IS_OK(disp_ret))
1282 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1283 return NT_STATUS_NO_MEMORY;
1285 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1286 if (!NT_STATUS_IS_OK(disp_ret))
1291 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1292 return NT_STATUS_NO_MEMORY;
1294 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1295 if (!NT_STATUS_IS_OK(disp_ret))
1300 ctr->sam.info = NULL;
1301 return NT_STATUS_INVALID_INFO_CLASS;
1304 /* calculate the total size */
1305 total_data_size=num_account*struct_size;
1307 if (enum_context+max_entries < num_account)
1308 r_u->status = STATUS_MORE_ENTRIES;
1310 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1312 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1318 /*******************************************************************
1319 samr_reply_query_aliasinfo
1320 ********************************************************************/
1322 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1328 r_u->status = NT_STATUS_OK;
1330 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1332 /* find the policy handle. open a policy on it. */
1333 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1334 return NT_STATUS_INVALID_HANDLE;
1335 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1339 if (!sid_check_is_in_our_domain(&sid) &&
1340 !sid_check_is_in_builtin(&sid))
1341 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1343 if (!pdb_getgrsid(&map, sid, MAPPING_WITHOUT_PRIV))
1344 return NT_STATUS_NO_SUCH_ALIAS;
1346 switch (q_u->switch_level) {
1349 r_u->ctr.switch_value1 = 1;
1350 init_samr_alias_info1(&r_u->ctr.alias.info1, map.nt_name, 1, map.comment);
1354 r_u->ctr.switch_value1 = 3;
1355 init_samr_alias_info3(&r_u->ctr.alias.info3, map.comment);
1358 return NT_STATUS_INVALID_INFO_CLASS;
1361 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1367 /*******************************************************************
1368 samr_reply_lookup_ids
1369 ********************************************************************/
1371 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1373 uint32 rid[MAX_SAM_ENTRIES];
1374 int num_rids = q_u->num_sids1;
1376 r_u->status = NT_STATUS_OK;
1378 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1380 if (num_rids > MAX_SAM_ENTRIES) {
1381 num_rids = MAX_SAM_ENTRIES;
1382 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1387 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1389 for (i = 0; i < num_rids && status == 0; i++)
1391 struct sam_passwd *sam_pass;
1395 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1396 q_u->uni_user_name[i].uni_str_len));
1398 /* find the user account */
1400 sam_pass = get_smb21pwd_entry(user_name, 0);
1403 if (sam_pass == NULL)
1405 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1410 rid[i] = sam_pass->user_rid;
1416 rid[0] = BUILTIN_ALIAS_RID_USERS;
1418 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1420 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1426 /*******************************************************************
1428 ********************************************************************/
1430 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1432 uint32 rid[MAX_SAM_ENTRIES];
1434 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1435 enum SID_NAME_USE local_type;
1437 int num_rids = q_u->num_names2;
1442 r_u->status = NT_STATUS_OK;
1444 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1449 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1450 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1454 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 */
1458 if (num_rids > MAX_SAM_ENTRIES) {
1459 num_rids = MAX_SAM_ENTRIES;
1460 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1463 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1465 become_root(); /* local_lookup_name can require root privs */
1467 for (i = 0; i < num_rids; i++) {
1471 r_u->status = NT_STATUS_NONE_MAPPED;
1473 rid [i] = 0xffffffff;
1474 type[i] = SID_NAME_UNKNOWN;
1476 rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1479 * we are only looking for a name
1480 * the SID we get back can be outside
1481 * the scope of the pol_sid
1483 * in clear: it prevents to reply to domain\group: yes
1484 * when only builtin\group exists.
1486 * a cleaner code is to add the sid of the domain we're looking in
1487 * to the local_lookup_name function.
1489 if(local_lookup_name(name, &sid, &local_type)) {
1490 sid_split_rid(&sid, &local_rid);
1492 if (sid_equal(&sid, &pol_sid)) {
1495 r_u->status = NT_STATUS_OK;
1502 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1504 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1509 /*******************************************************************
1510 _samr_chgpasswd_user
1511 ********************************************************************/
1513 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1518 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1520 r_u->status = NT_STATUS_OK;
1522 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1523 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1525 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1528 * Pass the user through the NT -> unix user mapping
1532 (void)map_username(user_name);
1535 * UNIX username case mangling not required, pass_oem_change
1536 * is case insensitive.
1539 r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1540 q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1542 init_samr_r_chgpasswd_user(r_u, r_u->status);
1544 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1549 /*******************************************************************
1550 makes a SAMR_R_LOOKUP_RIDS structure.
1551 ********************************************************************/
1553 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1554 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1557 UNIHDR *hdr_name=NULL;
1558 UNISTR2 *uni_name=NULL;
1560 *pp_uni_name = NULL;
1561 *pp_hdr_name = NULL;
1563 if (num_names != 0) {
1564 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1565 if (hdr_name == NULL)
1568 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1569 if (uni_name == NULL)
1573 for (i = 0; i < num_names; i++) {
1574 int len = names[i] != NULL ? strlen(names[i]) : 0;
1575 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1576 init_uni_hdr(&hdr_name[i], len);
1577 init_unistr2(&uni_name[i], names[i], len);
1580 *pp_uni_name = uni_name;
1581 *pp_hdr_name = hdr_name;
1586 /*******************************************************************
1588 ********************************************************************/
1590 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1592 fstring group_names[MAX_SAM_ENTRIES];
1593 uint32 *group_attrs = NULL;
1594 UNIHDR *hdr_name = NULL;
1595 UNISTR2 *uni_name = NULL;
1597 int num_rids = q_u->num_rids1;
1601 r_u->status = NT_STATUS_OK;
1603 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1605 /* find the policy handle. open a policy on it. */
1606 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1607 return NT_STATUS_INVALID_HANDLE;
1609 if (num_rids > MAX_SAM_ENTRIES) {
1610 num_rids = MAX_SAM_ENTRIES;
1611 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1615 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1616 return NT_STATUS_NO_MEMORY;
1619 r_u->status = NT_STATUS_NONE_MAPPED;
1621 become_root(); /* lookup_sid can require root privs */
1623 for (i = 0; i < num_rids; i++) {
1627 enum SID_NAME_USE type;
1629 group_attrs[i] = SID_NAME_UNKNOWN;
1630 *group_names[i] = '\0';
1632 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1633 sid_copy(&sid, &pol_sid);
1634 sid_append_rid(&sid, q_u->rid[i]);
1636 if (lookup_sid(&sid, domname, tmpname, &type)) {
1637 r_u->status = NT_STATUS_OK;
1638 group_attrs[i] = (uint32)type;
1639 fstrcpy(group_names[i],tmpname);
1640 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1647 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1648 return NT_STATUS_NO_MEMORY;
1650 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1652 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1657 /*******************************************************************
1658 _api_samr_open_user. Safe - gives out no passwd info.
1659 ********************************************************************/
1661 NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1663 SAM_ACCOUNT *sampass=NULL;
1665 POLICY_HND domain_pol = q_u->domain_pol;
1666 POLICY_HND *user_pol = &r_u->user_pol;
1667 struct samr_info *info = NULL;
1668 SEC_DESC *psd = NULL;
1670 uint32 des_access = q_u->access_mask;
1675 r_u->status = NT_STATUS_OK;
1677 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1678 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1679 return NT_STATUS_INVALID_HANDLE;
1681 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1685 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1686 if (!NT_STATUS_IS_OK(nt_status)) {
1690 /* append the user's RID to it */
1691 if (!sid_append_rid(&sid, q_u->user_rid))
1692 return NT_STATUS_NO_SUCH_USER;
1694 /* check if access can be granted as requested by client. */
1695 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1696 se_map_generic(&des_access, &usr_generic_mapping);
1697 if (!NT_STATUS_IS_OK(nt_status =
1698 access_check_samr_object(psd, p->pipe_user.nt_user_token,
1699 des_access, &acc_granted, "_samr_open_user"))) {
1704 ret=pdb_getsampwsid(sampass, &sid);
1707 /* check that the SID exists in our domain. */
1709 return NT_STATUS_NO_SUCH_USER;
1712 pdb_free_sam(&sampass);
1714 /* associate the user's SID and access bits with the new handle. */
1715 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1716 return NT_STATUS_NO_MEMORY;
1717 info->acc_granted = acc_granted;
1719 /* get a (unique) handle. open a policy on it. */
1720 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1721 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1726 /*************************************************************************
1727 get_user_info_10. Safe. Only gives out acb bits.
1728 *************************************************************************/
1730 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1732 SAM_ACCOUNT *smbpass=NULL;
1736 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1738 if (!NT_STATUS_IS_OK(nt_status)) {
1743 ret = pdb_getsampwsid(smbpass, user_sid);
1747 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1748 return NT_STATUS_NO_SUCH_USER;
1751 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1754 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1756 pdb_free_sam(&smbpass);
1758 return NT_STATUS_OK;
1761 /*************************************************************************
1762 get_user_info_12. OK - this is the killer as it gives out password info.
1763 Ensure that this is only allowed on an encrypted connection with a root
1765 *************************************************************************/
1767 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1769 SAM_ACCOUNT *smbpass=NULL;
1773 if (!p->ntlmssp_auth_validated)
1774 return NT_STATUS_ACCESS_DENIED;
1776 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1777 return NT_STATUS_ACCESS_DENIED;
1780 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1783 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1785 if (!NT_STATUS_IS_OK(nt_status)) {
1789 ret = pdb_getsampwsid(smbpass, user_sid);
1792 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1793 pdb_free_sam(&smbpass);
1794 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1797 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1799 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1800 pdb_free_sam(&smbpass);
1801 return NT_STATUS_ACCOUNT_DISABLED;
1805 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1807 pdb_free_sam(&smbpass);
1809 return NT_STATUS_OK;
1812 /*************************************************************************
1814 *************************************************************************/
1816 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1818 SAM_ACCOUNT *sampass=NULL;
1821 pdb_init_sam_talloc(mem_ctx, &sampass);
1824 ret = pdb_getsampwsid(sampass, user_sid);
1828 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1829 return NT_STATUS_NO_SUCH_USER;
1832 samr_clear_sam_passwd(sampass);
1834 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1837 init_sam_user_info20A(id20, sampass);
1839 pdb_free_sam(&sampass);
1841 return NT_STATUS_OK;
1844 /*************************************************************************
1846 *************************************************************************/
1848 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1849 DOM_SID *user_sid, DOM_SID *domain_sid)
1851 SAM_ACCOUNT *sampass=NULL;
1855 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1856 if (!NT_STATUS_IS_OK(nt_status)) {
1861 ret = pdb_getsampwsid(sampass, user_sid);
1865 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1866 return NT_STATUS_NO_SUCH_USER;
1869 samr_clear_sam_passwd(sampass);
1871 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1874 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1876 pdb_free_sam(&sampass);
1878 return NT_STATUS_OK;
1881 /*******************************************************************
1882 _samr_query_userinfo
1883 ********************************************************************/
1885 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1887 SAM_USERINFO_CTR *ctr;
1888 struct samr_info *info = NULL;
1892 r_u->status=NT_STATUS_OK;
1894 /* search for the handle */
1895 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1896 return NT_STATUS_INVALID_HANDLE;
1898 domain_sid = info->sid;
1900 sid_split_rid(&domain_sid, &rid);
1902 if (!sid_check_is_in_our_domain(&info->sid))
1903 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1905 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1907 ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1909 return NT_STATUS_NO_MEMORY;
1913 /* ok! user info levels (lots: see MSDEV help), off we go... */
1914 ctr->switch_value = q_u->switch_value;
1916 switch (q_u->switch_value) {
1918 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1919 if (ctr->info.id10 == NULL)
1920 return NT_STATUS_NO_MEMORY;
1922 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1927 /* whoops - got this wrong. i think. or don't understand what's happening. */
1931 info = (void *)&id11;
1933 expire.low = 0xffffffff;
1934 expire.high = 0x7fffffff;
1936 ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1941 ZERO_STRUCTP(ctr->info.id11);
1942 init_sam_user_info11(ctr->info.id11, &expire,
1943 "BROOKFIELDS$", /* name */
1944 0x03ef, /* user rid */
1945 0x201, /* group rid */
1946 0x0080); /* acb info */
1953 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1954 if (ctr->info.id12 == NULL)
1955 return NT_STATUS_NO_MEMORY;
1957 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1962 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1963 if (ctr->info.id20 == NULL)
1964 return NT_STATUS_NO_MEMORY;
1965 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1970 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1971 if (ctr->info.id21 == NULL)
1972 return NT_STATUS_NO_MEMORY;
1973 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1974 &info->sid, &domain_sid)))
1979 return NT_STATUS_INVALID_INFO_CLASS;
1982 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1984 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1989 /*******************************************************************
1990 samr_reply_query_usergroups
1991 ********************************************************************/
1993 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1995 SAM_ACCOUNT *sam_pass=NULL;
1997 DOM_GID *gids = NULL;
2003 * from the SID in the request:
2004 * we should send back the list of DOMAIN GROUPS
2005 * the user is a member of
2007 * and only the DOMAIN GROUPS
2008 * no ALIASES !!! neither aliases of the domain
2009 * nor aliases of the builtin SID
2014 r_u->status = NT_STATUS_OK;
2016 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2018 /* find the policy handle. open a policy on it. */
2019 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
2020 return NT_STATUS_INVALID_HANDLE;
2022 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
2026 if (!sid_check_is_in_our_domain(&sid))
2027 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2029 pdb_init_sam(&sam_pass);
2032 ret = pdb_getsampwsid(sam_pass, &sid);
2036 pdb_free_sam(&sam_pass);
2037 return NT_STATUS_NO_SUCH_USER;
2040 if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
2041 pdb_free_sam(&sam_pass);
2042 return NT_STATUS_NO_SUCH_GROUP;
2045 /* construct the response. lkclXXXX: gids are not copied! */
2046 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
2048 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2050 pdb_free_sam(&sam_pass);
2055 /*******************************************************************
2056 _samr_query_dom_info
2057 ********************************************************************/
2059 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2061 struct samr_info *info = NULL;
2063 uint32 min_pass_len,pass_hist,flag;
2064 time_t u_expire, u_min_age;
2065 NTTIME nt_expire, nt_min_age;
2067 time_t u_lock_duration, u_reset_time;
2068 NTTIME nt_lock_duration, nt_reset_time;
2074 uint32 account_policy_temp;
2076 uint32 num_users=0, num_groups=0, num_aliases=0;
2078 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
2079 return NT_STATUS_NO_MEMORY;
2083 r_u->status = NT_STATUS_OK;
2085 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2087 /* find the policy handle. open a policy on it. */
2088 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2089 return NT_STATUS_INVALID_HANDLE;
2091 switch (q_u->switch_value) {
2094 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2095 min_pass_len = account_policy_temp;
2097 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2098 pass_hist = account_policy_temp;
2100 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2101 flag = account_policy_temp;
2103 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2104 u_expire = account_policy_temp;
2106 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2107 u_min_age = account_policy_temp;
2109 unix_to_nt_time_abs(&nt_expire, u_expire);
2110 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2112 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2113 flag, nt_expire, nt_min_age);
2117 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2119 if (!NT_STATUS_IS_OK(r_u->status)) {
2120 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2123 num_users=info->disp_info.num_user_account;
2126 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2127 if (!NT_STATUS_IS_OK(r_u->status)) {
2128 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2131 num_groups=info->disp_info.num_group_account;
2134 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2135 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
2136 num_users, num_groups, num_aliases);
2139 account_policy_get(AP_TIME_TO_LOGOUT, (int *)&u_logout);
2140 unix_to_nt_time_abs(&nt_logout, u_logout);
2142 init_unk_info3(&ctr->info.inf3, nt_logout);
2145 init_unk_info5(&ctr->info.inf5, global_myname());
2148 init_unk_info6(&ctr->info.inf6);
2151 init_unk_info7(&ctr->info.inf7);
2154 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2155 u_lock_duration = account_policy_temp;
2157 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2158 u_reset_time = account_policy_temp;
2160 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2161 lockout = account_policy_temp;
2163 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2164 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2166 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2169 return NT_STATUS_INVALID_INFO_CLASS;
2172 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2174 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2179 /*******************************************************************
2180 _api_samr_create_user
2181 Create an account, can be either a normal user or a machine.
2182 This funcion will need to be updated for bdc/domain trusts.
2183 ********************************************************************/
2185 NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2187 SAM_ACCOUNT *sam_pass=NULL;
2191 POLICY_HND dom_pol = q_u->domain_pol;
2192 UNISTR2 user_account = q_u->uni_name;
2193 uint16 acb_info = q_u->acb_info;
2194 POLICY_HND *user_pol = &r_u->user_pol;
2195 struct samr_info *info = NULL;
2204 /* Get the domain SID stored in the domain policy */
2205 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2206 return NT_STATUS_INVALID_HANDLE;
2208 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2212 /* find the account: tell the caller if it exists.
2213 lkclXXXX i have *no* idea if this is a problem or not
2214 or even if you are supposed to construct a different
2215 reply if the account already exists...
2218 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2221 pdb_init_sam(&sam_pass);
2224 ret = pdb_getsampwnam(sam_pass, account);
2227 /* this account exists: say so */
2228 pdb_free_sam(&sam_pass);
2229 return NT_STATUS_USER_EXISTS;
2232 pdb_free_sam(&sam_pass);
2235 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2236 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2237 * that only people with write access to the smbpasswd file will be able
2238 * to create a user. JRA.
2242 * add the user in the /etc/passwd file or the unix authority system.
2243 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2244 * a) local_password_change() checks for us if the /etc/passwd account really exists
2245 * b) smb_create_user() would return an error if the account already exists
2246 * and as it could return an error also if it can't create the account, it would be tricky.
2248 * So we go the easy way, only check after if the account exists.
2249 * JFM (2/3/2001), to clear any possible bad understanding (-:
2251 * We now have seperate script paramaters for adding users/machines so we
2252 * now have some sainity-checking to match.
2255 DEBUG(10,("checking account %s at pos %d for $ termination\n",account, strlen(account)-1));
2257 if ((acb_info & ACB_WSTRUST) && (account[strlen(account)-1] == '$')) {
2258 pstrcpy(add_script, lp_addmachine_script());
2259 } else if ((!(acb_info & ACB_WSTRUST)) && (account[strlen(account)-1] != '$')) {
2260 pstrcpy(add_script, lp_adduser_script());
2262 DEBUG(0, ("_api_samr_create_user: mismatch between trust flags and $ termination\n"));
2263 pdb_free_sam(&sam_pass);
2264 return NT_STATUS_UNSUCCESSFUL;
2269 * we can't check both the ending $ and the acb_info.
2271 * UserManager creates trust accounts (ending in $,
2272 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2275 if (account[strlen(account)-1] == '$')
2276 pstrcpy(add_script, lp_addmachine_script());
2278 pstrcpy(add_script, lp_adduser_script());
2282 all_string_sub(add_script, "%u", account, sizeof(account));
2283 add_ret = smbrun(add_script,NULL);
2284 DEBUG(3,("_api_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2287 pw = getpwnam_alloc(account);
2290 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sam_pass, pw))) {
2294 passwd_free(&pw); /* done with this now */
2296 DEBUG(3,("attempting to create non-unix account %s\n", account));
2298 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sam_pass))) {
2302 if (!pdb_set_username(sam_pass, account, PDB_CHANGED)) {
2303 pdb_free_sam(&sam_pass);
2304 return NT_STATUS_NO_MEMORY;
2308 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2310 if (!pdb_add_sam_account(sam_pass)) {
2311 pdb_free_sam(&sam_pass);
2312 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2314 return NT_STATUS_ACCESS_DENIED;
2317 pdb_reset_sam(sam_pass);
2319 if (!pdb_getsampwnam(sam_pass, account)) {
2320 pdb_free_sam(&sam_pass);
2321 DEBUG(0, ("could not find user/computer %s just added to passdb?!?\n",
2323 return NT_STATUS_ACCESS_DENIED;
2326 /* Get the user's SID */
2327 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2329 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2330 se_map_generic(&des_access, &usr_generic_mapping);
2331 if (!NT_STATUS_IS_OK(nt_status =
2332 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2333 des_access, &acc_granted, "_samr_create_user"))) {
2337 /* associate the user's SID with the new handle. */
2338 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2339 pdb_free_sam(&sam_pass);
2340 return NT_STATUS_NO_MEMORY;
2345 info->acc_granted = acc_granted;
2347 /* get a (unique) handle. open a policy on it. */
2348 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2349 pdb_free_sam(&sam_pass);
2350 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2353 r_u->user_rid=pdb_get_user_rid(sam_pass);
2355 r_u->access_granted = acc_granted;
2357 pdb_free_sam(&sam_pass);
2359 return NT_STATUS_OK;
2362 /*******************************************************************
2363 samr_reply_connect_anon
2364 ********************************************************************/
2366 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2368 struct samr_info *info = NULL;
2372 if (!pipe_access_check(p)) {
2373 DEBUG(3, ("access denied to samr_connect_anon\n"));
2374 r_u->status = NT_STATUS_ACCESS_DENIED;
2378 /* set up the SAMR connect_anon response */
2380 r_u->status = NT_STATUS_OK;
2382 /* associate the user's SID with the new handle. */
2383 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2384 return NT_STATUS_NO_MEMORY;
2386 info->status = q_u->unknown_0;
2388 /* get a (unique) handle. open a policy on it. */
2389 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2390 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2395 /*******************************************************************
2397 ********************************************************************/
2399 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2401 struct samr_info *info = NULL;
2402 SEC_DESC *psd = NULL;
2404 uint32 des_access = q_u->access_mask;
2409 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2413 if (!pipe_access_check(p)) {
2414 DEBUG(3, ("access denied to samr_connect\n"));
2415 r_u->status = NT_STATUS_ACCESS_DENIED;
2419 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2420 se_map_generic(&des_access, &sam_generic_mapping);
2421 if (!NT_STATUS_IS_OK(nt_status =
2422 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2423 des_access, &acc_granted, "_samr_connect"))) {
2427 r_u->status = NT_STATUS_OK;
2429 /* associate the user's SID and access granted with the new handle. */
2430 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2431 return NT_STATUS_NO_MEMORY;
2433 info->acc_granted = acc_granted;
2434 info->status = q_u->access_mask;
2436 /* get a (unique) handle. open a policy on it. */
2437 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2438 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2440 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2445 /*******************************************************************
2447 ********************************************************************/
2449 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2451 struct samr_info *info = NULL;
2452 SEC_DESC *psd = NULL;
2454 uint32 des_access = q_u->access_mask;
2459 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2463 if (!pipe_access_check(p)) {
2464 DEBUG(3, ("access denied to samr_connect4\n"));
2465 r_u->status = NT_STATUS_ACCESS_DENIED;
2469 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2470 se_map_generic(&des_access, &sam_generic_mapping);
2471 if (!NT_STATUS_IS_OK(nt_status =
2472 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2473 des_access, &acc_granted, "_samr_connect"))) {
2477 r_u->status = NT_STATUS_OK;
2479 /* associate the user's SID and access granted with the new handle. */
2480 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2481 return NT_STATUS_NO_MEMORY;
2483 info->acc_granted = acc_granted;
2484 info->status = q_u->access_mask;
2486 /* get a (unique) handle. open a policy on it. */
2487 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2488 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2490 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2495 /**********************************************************************
2496 api_samr_lookup_domain
2497 **********************************************************************/
2499 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2501 struct samr_info *info;
2502 fstring domain_name;
2505 r_u->status = NT_STATUS_OK;
2507 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2508 return NT_STATUS_INVALID_HANDLE;
2510 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain"))) {
2514 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2518 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2519 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2522 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2524 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2529 /******************************************************************
2530 makes a SAMR_R_ENUM_DOMAINS structure.
2531 ********************************************************************/
2533 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2534 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2540 DEBUG(5, ("make_enum_domains\n"));
2543 *pp_uni_name = NULL;
2545 if (num_sam_entries == 0)
2548 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2549 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2551 if (sam == NULL || uni_name == NULL)
2554 for (i = 0; i < num_sam_entries; i++) {
2555 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
2557 init_sam_entry(&sam[i], len, 0);
2558 init_unistr2(&uni_name[i], doms[i], len);
2562 *pp_uni_name = uni_name;
2567 /**********************************************************************
2568 api_samr_enum_domains
2569 **********************************************************************/
2571 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2573 struct samr_info *info;
2574 uint32 num_entries = 2;
2578 r_u->status = NT_STATUS_OK;
2580 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2581 return NT_STATUS_INVALID_HANDLE;
2583 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2587 switch (lp_server_role()) {
2588 case ROLE_DOMAIN_PDC:
2589 case ROLE_DOMAIN_BDC:
2590 name = lp_workgroup();
2593 name = global_myname();
2596 fstrcpy(dom[0],name);
2598 fstrcpy(dom[1],"Builtin");
2600 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2601 return NT_STATUS_NO_MEMORY;
2603 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2608 /*******************************************************************
2610 ********************************************************************/
2612 NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2615 POLICY_HND domain_pol = q_u->dom_pol;
2616 uint32 alias_rid = q_u->rid_alias;
2617 POLICY_HND *alias_pol = &r_u->pol;
2618 struct samr_info *info = NULL;
2619 SEC_DESC *psd = NULL;
2621 uint32 des_access = q_u->access_mask;
2625 r_u->status = NT_STATUS_OK;
2627 /* find the domain policy and get the SID / access bits stored in the domain policy */
2628 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2629 return NT_STATUS_INVALID_HANDLE;
2631 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2635 /* append the alias' RID to it */
2636 if (!sid_append_rid(&sid, alias_rid))
2637 return NT_STATUS_NO_SUCH_USER;
2639 /*check if access can be granted as requested by client. */
2640 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2641 se_map_generic(&des_access,&ali_generic_mapping);
2642 if (!NT_STATUS_IS_OK(status =
2643 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2644 des_access, &acc_granted, "_samr_open_alias"))) {
2649 * we should check if the rid really exist !!!
2653 /* associate the user's SID with the new handle. */
2654 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2655 return NT_STATUS_NO_MEMORY;
2657 info->acc_granted = acc_granted;
2659 /* get a (unique) handle. open a policy on it. */
2660 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2661 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2666 /*******************************************************************
2668 ********************************************************************/
2670 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2672 SAM_ACCOUNT *pwd =NULL;
2677 ret = pdb_getsampwsid(pwd, sid);
2685 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2690 /* FIX ME: check if the value is really changed --metze */
2691 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2696 if(!pdb_update_sam_account(pwd)) {
2706 /*******************************************************************
2708 ********************************************************************/
2710 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2712 SAM_ACCOUNT *pwd = NULL;
2716 if(!pdb_getsampwsid(pwd, sid)) {
2722 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2727 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2731 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2735 if (!pdb_set_pass_changed_now (pwd)) {
2740 if(!pdb_update_sam_account(pwd)) {
2749 /*******************************************************************
2751 ********************************************************************/
2753 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2755 SAM_ACCOUNT *pwd = NULL;
2758 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2764 if (!pdb_getsampwsid(pwd, sid)) {
2769 copy_id21_to_sam_passwd(pwd, id21);
2772 * The funny part about the previous two calls is
2773 * that pwd still has the password hashes from the
2774 * passdb entry. These have not been updated from
2775 * id21. I don't know if they need to be set. --jerry
2778 /* write the change out */
2779 if(!pdb_update_sam_account(pwd)) {
2789 /*******************************************************************
2791 ********************************************************************/
2793 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2795 SAM_ACCOUNT *pwd = NULL;
2796 pstring plaintext_buf;
2801 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2807 if (!pdb_getsampwsid(pwd, sid)) {
2812 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2813 pdb_get_username(pwd)));
2815 acct_ctrl = pdb_get_acct_ctrl(pwd);
2817 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
2822 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2827 copy_id23_to_sam_passwd(pwd, id23);
2829 /* if it's a trust account, don't update /etc/passwd */
2830 if ( (!IS_SAM_UNIX_USER(pwd)) ||
2831 ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2832 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2833 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2834 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2836 /* update the UNIX password */
2837 if (lp_unix_password_sync() )
2838 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2844 ZERO_STRUCT(plaintext_buf);
2846 if(!pdb_update_sam_account(pwd)) {
2856 /*******************************************************************
2858 ********************************************************************/
2860 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2862 SAM_ACCOUNT *pwd = NULL;
2864 pstring plaintext_buf;
2869 if (!pdb_getsampwsid(pwd, sid)) {
2874 DEBUG(5, ("Attempting administrator password change for user %s\n",
2875 pdb_get_username(pwd)));
2877 acct_ctrl = pdb_get_acct_ctrl(pwd);
2879 ZERO_STRUCT(plaintext_buf);
2881 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) {
2886 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2891 /* if it's a trust account, don't update /etc/passwd */
2892 if ( (!IS_SAM_UNIX_USER(pwd)) ||
2893 ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2894 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2895 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2896 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2898 /* update the UNIX password */
2899 if (lp_unix_password_sync()) {
2900 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2907 ZERO_STRUCT(plaintext_buf);
2909 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2911 /* update the SAMBA password */
2912 if(!pdb_update_sam_account(pwd)) {
2922 /*******************************************************************
2923 samr_reply_set_userinfo
2924 ********************************************************************/
2926 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2929 POLICY_HND *pol = &q_u->pol;
2930 uint16 switch_value = q_u->switch_value;
2931 SAM_USERINFO_CTR *ctr = q_u->ctr;
2933 uint32 acc_required;
2935 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2937 r_u->status = NT_STATUS_OK;
2939 /* find the policy handle. open a policy on it. */
2940 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2941 return NT_STATUS_INVALID_HANDLE;
2943 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
2944 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2948 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
2951 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2952 return NT_STATUS_INVALID_INFO_CLASS;
2955 /* ok! user info levels (lots: see MSDEV help), off we go... */
2956 switch (switch_value) {
2958 if (!set_user_info_12(ctr->info.id12, &sid))
2959 return NT_STATUS_ACCESS_DENIED;
2963 SamOEMhash(ctr->info.id24->pass, p->session_key, 516);
2965 dump_data(100, (char *)ctr->info.id24->pass, 516);
2967 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
2968 return NT_STATUS_ACCESS_DENIED;
2974 * Currently we don't really know how to unmarshall
2975 * the level 25 struct, and the password encryption
2976 * is different. This is a placeholder for when we
2977 * do understand it. In the meantime just return INVALID
2978 * info level and W2K SP2 drops down to level 23... JRA.
2981 SamOEMhash(ctr->info.id25->pass, p->session_key, 532);
2983 dump_data(100, (char *)ctr->info.id25->pass, 532);
2985 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
2986 return NT_STATUS_ACCESS_DENIED;
2989 return NT_STATUS_INVALID_INFO_CLASS;
2992 SamOEMhash(ctr->info.id23->pass, p->session_key, 516);
2994 dump_data(100, (char *)ctr->info.id23->pass, 516);
2996 if (!set_user_info_23(ctr->info.id23, &sid))
2997 return NT_STATUS_ACCESS_DENIED;
3001 return NT_STATUS_INVALID_INFO_CLASS;
3007 /*******************************************************************
3008 samr_reply_set_userinfo2
3009 ********************************************************************/
3011 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3014 SAM_USERINFO_CTR *ctr = q_u->ctr;
3015 POLICY_HND *pol = &q_u->pol;
3016 uint16 switch_value = q_u->switch_value;
3018 uint32 acc_required;
3020 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3022 r_u->status = NT_STATUS_OK;
3024 /* find the policy handle. open a policy on it. */
3025 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3026 return NT_STATUS_INVALID_HANDLE;
3028 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3029 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3033 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3036 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3037 return NT_STATUS_INVALID_INFO_CLASS;
3040 switch_value=ctr->switch_value;
3042 /* ok! user info levels (lots: see MSDEV help), off we go... */
3043 switch (switch_value) {
3045 if (!set_user_info_21(ctr->info.id21, &sid))
3046 return NT_STATUS_ACCESS_DENIED;
3049 if (!set_user_info_10(ctr->info.id10, &sid))
3050 return NT_STATUS_ACCESS_DENIED;
3053 /* Used by AS/U JRA. */
3054 if (!set_user_info_12(ctr->info.id12, &sid))
3055 return NT_STATUS_ACCESS_DENIED;
3058 return NT_STATUS_INVALID_INFO_CLASS;
3064 /*********************************************************************
3065 _samr_query_aliasmem
3066 *********************************************************************/
3068 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3070 int num_groups = 0, tmp_num_groups=0;
3071 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3072 struct samr_info *info = NULL;
3078 /* until i see a real useraliases query, we fack one up */
3080 /* I have seen one, JFM 2/12/2001 */
3082 * Explanation of what this call does:
3083 * for all the SID given in the request:
3084 * return a list of alias (local groups)
3085 * that have those SID as members.
3087 * and that's the alias in the domain specified
3088 * in the policy_handle
3090 * if the policy handle is on an incorrect sid
3091 * for example a user's sid
3092 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3095 r_u->status = NT_STATUS_OK;
3097 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3099 /* find the policy handle. open a policy on it. */
3100 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3101 return NT_STATUS_INVALID_HANDLE;
3103 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3104 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3106 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3107 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3108 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3109 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3113 if (!sid_check_is_domain(&info->sid) &&
3114 !sid_check_is_builtin(&info->sid))
3115 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3118 for (i=0; i<q_u->num_sids1; i++) {
3120 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3123 * if there is an error, we just continue as
3124 * it can be an unfound user or group
3126 if (!NT_STATUS_IS_OK(r_u->status)) {
3127 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3131 if (tmp_num_groups==0) {
3132 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3136 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3137 if (new_rids==NULL) {
3138 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3139 return NT_STATUS_NO_MEMORY;
3143 for (j=0; j<tmp_num_groups; j++)
3144 rids[j+num_groups]=tmp_rids[j];
3146 safe_free(tmp_rids);
3148 num_groups+=tmp_num_groups;
3151 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3152 return NT_STATUS_OK;
3155 /*********************************************************************
3156 _samr_query_aliasmem
3157 *********************************************************************/
3159 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3171 fstring alias_sid_str;
3174 SAM_ACCOUNT *sam_user = NULL;
3178 /* find the policy handle. open a policy on it. */
3179 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3180 return NT_STATUS_INVALID_HANDLE;
3182 if (!NT_STATUS_IS_OK(r_u->status =
3183 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3187 sid_copy(&als_sid, &alias_sid);
3188 sid_to_string(alias_sid_str, &alias_sid);
3189 sid_split_rid(&alias_sid, &alias_rid);
3191 DEBUG(10, ("sid is %s\n", alias_sid_str));
3193 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
3194 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3195 if(!get_builtin_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
3196 return NT_STATUS_NO_SUCH_ALIAS;
3198 if (sid_equal(&alias_sid, get_global_sam_sid())) {
3199 DEBUG(10, ("lookup on Server SID\n"));
3200 if(!get_local_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
3201 return NT_STATUS_NO_SUCH_ALIAS;
3205 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3206 return NT_STATUS_NO_SUCH_ALIAS;
3208 DEBUG(10, ("sid is %s\n", alias_sid_str));
3209 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
3210 if (num_uids!=0 && sid == NULL)
3211 return NT_STATUS_NO_MEMORY;
3213 for (i = 0; i < num_uids; i++) {
3214 struct passwd *pass;
3217 sid_copy(&temp_sid, get_global_sam_sid());
3219 pass = getpwuid_alloc(uid[i]);
3220 if (!pass) continue;
3222 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3228 check = pdb_getsampwnam(sam_user, pass->pw_name);
3231 if (check != True) {
3232 pdb_free_sam(&sam_user);
3237 rid = pdb_get_user_rid(sam_user);
3239 pdb_free_sam(&sam_user);
3244 pdb_free_sam(&sam_user);
3247 sid_append_rid(&temp_sid, rid);
3249 init_dom_sid2(&sid[i], &temp_sid);
3252 DEBUG(10, ("sid is %s\n", alias_sid_str));
3253 init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
3255 return NT_STATUS_OK;
3258 /*********************************************************************
3259 _samr_query_groupmem
3260 *********************************************************************/
3262 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3268 fstring group_sid_str;
3276 SAM_ACCOUNT *sam_user = NULL;
3280 /* find the policy handle. open a policy on it. */
3281 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3282 return NT_STATUS_INVALID_HANDLE;
3284 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3288 /* todo: change to use sid_compare_front */
3290 sid_split_rid(&group_sid, &group_rid);
3291 sid_to_string(group_sid_str, &group_sid);
3292 DEBUG(10, ("sid is %s\n", group_sid_str));
3294 /* can we get a query for an SID outside our domain ? */
3295 if (!sid_equal(&group_sid, get_global_sam_sid()))
3296 return NT_STATUS_NO_SUCH_GROUP;
3298 sid_append_rid(&group_sid, group_rid);
3299 DEBUG(10, ("lookup on Domain SID\n"));
3301 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3302 return NT_STATUS_NO_SUCH_GROUP;
3304 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3305 return NT_STATUS_NO_SUCH_GROUP;
3307 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3308 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3310 if (num_uids!=0 && (rid==NULL || attr==NULL))
3311 return NT_STATUS_NO_MEMORY;
3313 for (i=0; i<num_uids; i++) {
3314 struct passwd *pass;
3317 pass = getpwuid_alloc(uid[i]);
3318 if (!pass) continue;
3320 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3326 check = pdb_getsampwnam(sam_user, pass->pw_name);
3329 if (check != True) {
3330 pdb_free_sam(&sam_user);
3335 urid = pdb_get_user_rid(sam_user);
3337 pdb_free_sam(&sam_user);
3342 pdb_free_sam(&sam_user);
3346 attr[i] = SID_NAME_USER;
3349 init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
3351 return NT_STATUS_OK;
3354 /*********************************************************************
3356 *********************************************************************/
3358 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3361 fstring alias_sid_str;
3368 SAM_ACCOUNT *sam_user = NULL;
3372 /* Find the policy handle. Open a policy on it. */
3373 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3374 return NT_STATUS_INVALID_HANDLE;
3376 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3380 sid_to_string(alias_sid_str, &alias_sid);
3381 DEBUG(10, ("sid is %s\n", alias_sid_str));
3383 if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
3384 DEBUG(10, ("adding member on Server SID\n"));
3385 if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3386 return NT_STATUS_NO_SUCH_ALIAS;
3389 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
3390 DEBUG(10, ("adding member on BUILTIN SID\n"));
3391 if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3392 return NT_STATUS_NO_SUCH_ALIAS;
3395 return NT_STATUS_NO_SUCH_ALIAS;
3398 ret = pdb_init_sam(&sam_user);
3399 if (!NT_STATUS_IS_OK(ret))
3402 check = pdb_getsampwsid(sam_user, &q_u->sid.sid);
3404 if (check != True) {
3405 pdb_free_sam(&sam_user);
3406 return NT_STATUS_NO_SUCH_USER;
3409 uid = pdb_get_uid(sam_user);
3411 pdb_free_sam(&sam_user);
3412 return NT_STATUS_NO_SUCH_USER;
3415 pdb_free_sam(&sam_user);
3417 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3418 return NT_STATUS_NO_SUCH_USER;
3421 if ((grp=getgrgid(map.gid)) == NULL) {
3423 return NT_STATUS_NO_SUCH_ALIAS;
3426 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3427 fstrcpy(grp_name, grp->gr_name);
3429 /* if the user is already in the group */
3430 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3432 return NT_STATUS_MEMBER_IN_ALIAS;
3436 * ok, the group exist, the user exist, the user is not in the group,
3437 * we can (finally) add it to the group !
3439 smb_add_user_group(grp_name, pwd->pw_name);
3441 /* check if the user has been added then ... */
3442 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3444 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3448 return NT_STATUS_OK;
3451 /*********************************************************************
3453 *********************************************************************/
3455 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3458 fstring alias_sid_str;
3462 SAM_ACCOUNT *sam_pass=NULL;
3465 /* Find the policy handle. Open a policy on it. */
3466 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3467 return NT_STATUS_INVALID_HANDLE;
3469 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3473 sid_to_string(alias_sid_str, &alias_sid);
3474 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
3476 if (!sid_check_is_in_our_domain(&alias_sid) &&
3477 !sid_check_is_in_builtin(&alias_sid)) {
3478 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3479 return NT_STATUS_NO_SUCH_ALIAS;
3482 if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3483 return NT_STATUS_NO_SUCH_ALIAS;
3485 if ((grp=getgrgid(map.gid)) == NULL)
3486 return NT_STATUS_NO_SUCH_ALIAS;
3488 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3489 fstrcpy(grp_name, grp->gr_name);
3491 /* check if the user exists before trying to remove it from the group */
3492 pdb_init_sam(&sam_pass);
3493 if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
3494 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3495 pdb_free_sam(&sam_pass);
3496 return NT_STATUS_NO_SUCH_USER;
3499 /* if the user is not in the group */
3500 if(!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3501 pdb_free_sam(&sam_pass);
3502 return NT_STATUS_MEMBER_IN_ALIAS;
3505 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3507 /* check if the user has been removed then ... */
3508 if(user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3509 pdb_free_sam(&sam_pass);
3510 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3513 pdb_free_sam(&sam_pass);
3514 return NT_STATUS_OK;
3517 /*********************************************************************
3519 *********************************************************************/
3521 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3525 fstring group_sid_str;
3532 SAM_ACCOUNT *sam_user=NULL;
3536 /* Find the policy handle. Open a policy on it. */
3537 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3538 return NT_STATUS_INVALID_HANDLE;
3540 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3544 sid_to_string(group_sid_str, &group_sid);
3545 DEBUG(10, ("sid is %s\n", group_sid_str));
3547 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3548 return NT_STATUS_NO_SUCH_GROUP;
3550 DEBUG(10, ("lookup on Domain SID\n"));
3552 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3553 return NT_STATUS_NO_SUCH_GROUP;
3555 sid_copy(&user_sid, get_global_sam_sid());
3556 sid_append_rid(&user_sid, q_u->rid);
3558 ret = pdb_init_sam(&sam_user);
3559 if (!NT_STATUS_IS_OK(ret))
3562 check = pdb_getsampwsid(sam_user, &user_sid);
3564 if (check != True) {
3565 pdb_free_sam(&sam_user);
3566 return NT_STATUS_NO_SUCH_USER;
3569 uid = pdb_get_uid(sam_user);
3571 pdb_free_sam(&sam_user);
3572 return NT_STATUS_NO_SUCH_USER;
3575 pdb_free_sam(&sam_user);
3577 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3578 return NT_STATUS_NO_SUCH_USER;
3581 if ((grp=getgrgid(map.gid)) == NULL) {
3583 return NT_STATUS_NO_SUCH_GROUP;
3586 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3587 fstrcpy(grp_name, grp->gr_name);
3589 /* if the user is already in the group */
3590 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3592 return NT_STATUS_MEMBER_IN_GROUP;
3596 * ok, the group exist, the user exist, the user is not in the group,
3598 * we can (finally) add it to the group !
3601 smb_add_user_group(grp_name, pwd->pw_name);
3603 /* check if the user has been added then ... */
3604 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3606 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3610 return NT_STATUS_OK;
3613 /*********************************************************************
3615 *********************************************************************/
3617 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3621 SAM_ACCOUNT *sam_pass=NULL;
3628 * delete the group member named q_u->rid
3629 * who is a member of the sid associated with the handle
3630 * the rid is a user's rid as the group is a domain group.
3633 /* Find the policy handle. Open a policy on it. */
3634 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3635 return NT_STATUS_INVALID_HANDLE;
3637 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3641 if (!sid_check_is_in_our_domain(&group_sid))
3642 return NT_STATUS_NO_SUCH_GROUP;
3644 sid_copy(&user_sid, get_global_sam_sid());
3645 sid_append_rid(&user_sid, q_u->rid);
3647 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3648 return NT_STATUS_NO_SUCH_GROUP;
3650 if ((grp=getgrgid(map.gid)) == NULL)
3651 return NT_STATUS_NO_SUCH_GROUP;
3653 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3654 fstrcpy(grp_name, grp->gr_name);
3656 /* check if the user exists before trying to remove it from the group */
3657 pdb_init_sam(&sam_pass);
3658 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3659 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3660 pdb_free_sam(&sam_pass);
3661 return NT_STATUS_NO_SUCH_USER;
3664 /* if the user is not in the group */
3665 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3666 pdb_free_sam(&sam_pass);
3667 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3670 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3672 /* check if the user has been removed then ... */
3673 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3674 pdb_free_sam(&sam_pass);
3675 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3678 pdb_free_sam(&sam_pass);
3679 return NT_STATUS_OK;
3683 /****************************************************************************
3684 Delete a UNIX user on demand.
3685 ****************************************************************************/
3687 static int smb_delete_user(const char *unix_user)
3692 pstrcpy(del_script, lp_deluser_script());
3695 all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3696 ret = smbrun(del_script,NULL);
3697 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3701 /*********************************************************************
3702 _samr_delete_dom_user
3703 *********************************************************************/
3705 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3708 SAM_ACCOUNT *sam_pass=NULL;
3711 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3713 /* Find the policy handle. Open a policy on it. */
3714 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3715 return NT_STATUS_INVALID_HANDLE;
3717 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3721 if (!sid_check_is_in_our_domain(&user_sid))
3722 return NT_STATUS_CANNOT_DELETE;
3724 /* check if the user exists before trying to delete */
3725 pdb_init_sam(&sam_pass);
3726 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3727 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3728 pdb_free_sam(&sam_pass);
3729 return NT_STATUS_NO_SUCH_USER;
3732 /* delete the unix side */
3734 * note: we don't check if the delete really happened
3735 * as the script is not necessary present
3736 * and maybe the sysadmin doesn't want to delete the unix side
3738 smb_delete_user(pdb_get_username(sam_pass));
3740 /* and delete the samba side */
3741 if (!pdb_delete_sam_account(sam_pass)) {
3742 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3743 pdb_free_sam(&sam_pass);
3744 return NT_STATUS_CANNOT_DELETE;
3747 pdb_free_sam(&sam_pass);
3749 if (!close_policy_hnd(p, &q_u->user_pol))
3750 return NT_STATUS_OBJECT_NAME_INVALID;
3752 return NT_STATUS_OK;
3755 /*********************************************************************
3756 _samr_delete_dom_group
3757 *********************************************************************/
3759 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3764 fstring group_sid_str;
3770 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3772 /* Find the policy handle. Open a policy on it. */
3773 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3774 return NT_STATUS_INVALID_HANDLE;
3776 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3780 sid_copy(&dom_sid, &group_sid);
3781 sid_to_string(group_sid_str, &dom_sid);
3782 sid_split_rid(&dom_sid, &group_rid);
3784 DEBUG(10, ("sid is %s\n", group_sid_str));
3786 /* we check if it's our SID before deleting */
3787 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3788 return NT_STATUS_NO_SUCH_GROUP;
3790 DEBUG(10, ("lookup on Domain SID\n"));
3792 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3793 return NT_STATUS_NO_SUCH_GROUP;
3797 /* check if group really exists */
3798 if ( (grp=getgrgid(gid)) == NULL)
3799 return NT_STATUS_NO_SUCH_GROUP;
3801 /* we can delete the UNIX group */
3802 smb_delete_group(grp->gr_name);
3804 /* check if the group has been successfully deleted */
3805 if ( (grp=getgrgid(gid)) != NULL)
3806 return NT_STATUS_ACCESS_DENIED;
3808 if(!pdb_delete_group_mapping_entry(group_sid))
3809 return NT_STATUS_ACCESS_DENIED;
3811 if (!close_policy_hnd(p, &q_u->group_pol))
3812 return NT_STATUS_OBJECT_NAME_INVALID;
3814 return NT_STATUS_OK;
3817 /*********************************************************************
3818 _samr_delete_dom_alias
3819 *********************************************************************/
3821 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3826 fstring alias_sid_str;
3832 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3834 /* Find the policy handle. Open a policy on it. */
3835 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3836 return NT_STATUS_INVALID_HANDLE;
3838 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3842 sid_copy(&dom_sid, &alias_sid);
3843 sid_to_string(alias_sid_str, &dom_sid);
3844 sid_split_rid(&dom_sid, &alias_rid);
3846 DEBUG(10, ("sid is %s\n", alias_sid_str));
3848 /* we check if it's our SID before deleting */
3849 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3850 return NT_STATUS_NO_SUCH_ALIAS;
3852 DEBUG(10, ("lookup on Local SID\n"));
3854 if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3855 return NT_STATUS_NO_SUCH_ALIAS;
3859 /* check if group really exists */
3860 if ( (grp=getgrgid(gid)) == NULL)
3861 return NT_STATUS_NO_SUCH_ALIAS;
3863 /* we can delete the UNIX group */
3864 smb_delete_group(grp->gr_name);
3866 /* check if the group has been successfully deleted */
3867 if ( (grp=getgrgid(gid)) != NULL)
3868 return NT_STATUS_ACCESS_DENIED;
3870 /* don't check if we removed it as it could be an un-mapped group */
3871 pdb_delete_group_mapping_entry(alias_sid);
3873 if (!close_policy_hnd(p, &q_u->alias_pol))
3874 return NT_STATUS_OBJECT_NAME_INVALID;
3876 return NT_STATUS_OK;
3879 /*********************************************************************
3880 _samr_create_dom_group
3881 *********************************************************************/
3883 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3890 struct samr_info *info;
3891 PRIVILEGE_SET priv_set;
3895 init_privilege(&priv_set);
3897 /* Find the policy handle. Open a policy on it. */
3898 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3899 return NT_STATUS_INVALID_HANDLE;
3901 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3905 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3906 return NT_STATUS_ACCESS_DENIED;
3908 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3910 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3912 /* check if group already exist */
3913 if ((grp=getgrnam(name)) != NULL)
3914 return NT_STATUS_GROUP_EXISTS;
3916 /* we can create the UNIX group */
3917 if (smb_create_group(name, &gid) != 0)
3918 return NT_STATUS_ACCESS_DENIED;
3920 /* check if the group has been successfully created */
3921 if ((grp=getgrgid(gid)) == NULL)
3922 return NT_STATUS_ACCESS_DENIED;
3924 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3926 /* add the group to the mapping table */
3927 sid_copy(&info_sid, get_global_sam_sid());
3928 sid_append_rid(&info_sid, r_u->rid);
3929 sid_to_string(sid_string, &info_sid);
3931 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
3932 return NT_STATUS_ACCESS_DENIED;
3934 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3935 return NT_STATUS_NO_MEMORY;
3937 /* get a (unique) handle. open a policy on it. */
3938 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3939 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3941 return NT_STATUS_OK;
3944 /*********************************************************************
3945 _samr_create_dom_alias
3946 *********************************************************************/
3948 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3955 struct samr_info *info;
3956 PRIVILEGE_SET priv_set;
3960 init_privilege(&priv_set);
3962 /* Find the policy handle. Open a policy on it. */
3963 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
3964 return NT_STATUS_INVALID_HANDLE;
3966 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3970 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3971 return NT_STATUS_ACCESS_DENIED;
3973 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3975 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3977 /* check if group already exists */
3978 if ( (grp=getgrnam(name)) != NULL)
3979 return NT_STATUS_GROUP_EXISTS;
3981 /* we can create the UNIX group */
3982 if (smb_create_group(name, &gid) != 0)
3983 return NT_STATUS_ACCESS_DENIED;
3985 /* check if the group has been successfully created */
3986 if ((grp=getgrgid(gid)) == NULL)
3987 return NT_STATUS_ACCESS_DENIED;
3989 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3991 sid_copy(&info_sid, get_global_sam_sid());
3992 sid_append_rid(&info_sid, r_u->rid);
3993 sid_to_string(sid_string, &info_sid);
3995 /* add the group to the mapping table */
3996 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
3997 return NT_STATUS_ACCESS_DENIED;
3999 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4000 return NT_STATUS_NO_MEMORY;
4002 /* get a (unique) handle. open a policy on it. */
4003 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4004 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4006 return NT_STATUS_OK;
4009 /*********************************************************************
4010 _samr_query_groupinfo
4012 sends the name/comment pair of a domain group
4013 level 1 send also the number of users of that group
4014 *********************************************************************/
4016 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4022 GROUP_INFO_CTR *ctr;
4025 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4026 return NT_STATUS_INVALID_HANDLE;
4028 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4032 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
4033 return NT_STATUS_INVALID_HANDLE;
4035 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
4037 return NT_STATUS_NO_MEMORY;
4039 switch (q_u->switch_level) {
4041 ctr->switch_value1 = 1;
4042 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
4043 return NT_STATUS_NO_SUCH_GROUP;
4044 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
4048 ctr->switch_value1 = 3;
4049 init_samr_group_info3(&ctr->group.info3);
4052 ctr->switch_value1 = 4;
4053 init_samr_group_info4(&ctr->group.info4, map.comment);
4056 return NT_STATUS_INVALID_INFO_CLASS;
4059 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4061 return NT_STATUS_OK;
4064 /*********************************************************************
4067 update a domain group's comment.
4068 *********************************************************************/
4070 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4074 GROUP_INFO_CTR *ctr;
4077 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4078 return NT_STATUS_INVALID_HANDLE;
4080 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4084 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
4085 return NT_STATUS_NO_SUCH_GROUP;
4089 switch (ctr->switch_value1) {
4091 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4094 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4097 free_privilege(&map.priv_set);
4098 return NT_STATUS_INVALID_INFO_CLASS;
4101 if(!pdb_update_group_mapping_entry(&map)) {
4102 free_privilege(&map.priv_set);
4103 return NT_STATUS_NO_SUCH_GROUP;
4106 free_privilege(&map.priv_set);
4108 return NT_STATUS_OK;
4111 /*********************************************************************
4114 update an alias's comment.
4115 *********************************************************************/
4117 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4121 ALIAS_INFO_CTR *ctr;
4124 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4125 return NT_STATUS_INVALID_HANDLE;
4127 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4131 if (!get_local_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
4132 return NT_STATUS_NO_SUCH_GROUP;
4136 switch (ctr->switch_value1) {
4138 unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
4141 free_privilege(&map.priv_set);
4142 return NT_STATUS_INVALID_INFO_CLASS;
4145 if(!pdb_update_group_mapping_entry(&map)) {
4146 free_privilege(&map.priv_set);
4147 return NT_STATUS_NO_SUCH_GROUP;
4150 free_privilege(&map.priv_set);
4152 return NT_STATUS_OK;
4155 /*********************************************************************
4156 _samr_get_dom_pwinfo
4157 *********************************************************************/
4159 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4161 /* Perform access check. Since this rpc does not require a
4162 policy handle it will not be caught by the access checks on
4163 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4165 if (!pipe_access_check(p)) {
4166 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4167 r_u->status = NT_STATUS_ACCESS_DENIED;
4171 /* Actually, returning zeros here works quite well :-). */
4173 return NT_STATUS_OK;
4176 /*********************************************************************
4178 *********************************************************************/
4180 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4185 struct samr_info *info;
4186 SEC_DESC *psd = NULL;
4193 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4194 return NT_STATUS_INVALID_HANDLE;
4196 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4200 /*check if access can be granted as requested by client. */
4201 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4202 se_map_generic(&des_access,&grp_generic_mapping);
4203 if (!NT_STATUS_IS_OK(status =
4204 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4205 des_access, &acc_granted, "_samr_open_group"))) {
4210 /* this should not be hard-coded like this */
4211 if (!sid_equal(&sid, get_global_sam_sid()))
4212 return NT_STATUS_ACCESS_DENIED;
4214 sid_copy(&info_sid, get_global_sam_sid());
4215 sid_append_rid(&info_sid, q_u->rid_group);
4216 sid_to_string(sid_string, &info_sid);
4218 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4219 return NT_STATUS_NO_MEMORY;
4221 info->acc_granted = acc_granted;
4223 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4225 /* check if that group really exists */
4226 if (!get_domain_group_from_sid(info->sid, &map, MAPPING_WITHOUT_PRIV))
4227 return NT_STATUS_NO_SUCH_GROUP;
4229 /* get a (unique) handle. open a policy on it. */
4230 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4231 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4233 return NT_STATUS_OK;
4236 /*********************************************************************
4238 *********************************************************************/
4240 NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
4242 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
4243 return NT_STATUS_NOT_IMPLEMENTED;
4246 /*******************************************************************
4248 ********************************************************************/
4250 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4252 struct samr_info *info = NULL;
4254 uint32 min_pass_len,pass_hist,flag;
4255 time_t u_expire, u_min_age;
4256 NTTIME nt_expire, nt_min_age;
4258 time_t u_lock_duration, u_reset_time;
4259 NTTIME nt_lock_duration, nt_reset_time;
4265 uint32 num_users=0, num_groups=0, num_aliases=0;
4267 uint32 account_policy_temp;
4269 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4270 return NT_STATUS_NO_MEMORY;
4274 r_u->status = NT_STATUS_OK;
4276 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4278 /* find the policy handle. open a policy on it. */
4279 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4280 return NT_STATUS_INVALID_HANDLE;
4282 switch (q_u->switch_value) {
4284 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4285 min_pass_len = account_policy_temp;
4287 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4288 pass_hist = account_policy_temp;
4290 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4291 flag = account_policy_temp;
4293 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4294 u_expire = account_policy_temp;
4296 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4297 u_min_age = account_policy_temp;
4299 unix_to_nt_time_abs(&nt_expire, u_expire);
4300 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4302 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4303 flag, nt_expire, nt_min_age);
4307 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4309 if (!NT_STATUS_IS_OK(r_u->status)) {
4310 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4313 num_users=info->disp_info.num_user_account;
4316 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4317 if (NT_STATUS_IS_ERR(r_u->status)) {
4318 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4321 num_groups=info->disp_info.num_group_account;
4324 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4325 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
4326 num_users, num_groups, num_aliases);
4329 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4330 u_logout = account_policy_temp;
4332 unix_to_nt_time_abs(&nt_logout, u_logout);
4334 init_unk_info3(&ctr->info.inf3, nt_logout);
4337 init_unk_info5(&ctr->info.inf5, global_myname());
4340 init_unk_info6(&ctr->info.inf6);
4343 init_unk_info7(&ctr->info.inf7);
4346 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4347 u_lock_duration = account_policy_temp;
4349 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4350 u_reset_time = account_policy_temp;
4352 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4353 lockout = account_policy_temp;
4355 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4356 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4358 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4361 return NT_STATUS_INVALID_INFO_CLASS;
4364 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4366 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4371 /*******************************************************************
4373 ********************************************************************/
4375 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4377 time_t u_expire, u_min_age;
4379 time_t u_lock_duration, u_reset_time;
4381 r_u->status = NT_STATUS_OK;
4383 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4385 /* find the policy handle. open a policy on it. */
4386 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4387 return NT_STATUS_INVALID_HANDLE;
4389 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4391 switch (q_u->switch_value) {
4393 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4394 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4396 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4397 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4398 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4399 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4400 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4405 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4406 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4415 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4416 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count);
4418 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4419 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4420 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4423 return NT_STATUS_INVALID_INFO_CLASS;
4426 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4428 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));