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 fstring global_myworkgroup;
38 extern pstring global_myname;
39 extern DOM_SID global_sid_Builtin;
41 extern rid_name domain_group_rids[];
42 extern rid_name domain_alias_rids[];
43 extern rid_name builtin_alias_rids[];
46 typedef struct _disp_info {
48 uint32 num_user_account;
49 DISP_USER_INFO *disp_user_info;
51 uint32 num_group_account;
52 DISP_GROUP_INFO *disp_group_info;
56 /* for use by the \PIPE\samr policy */
58 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
67 struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
68 struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
69 struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
70 struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
71 struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
73 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
75 /*******************************************************************
76 Checks if access to an object should be granted, and returns that
77 level of access for further checks.
78 ********************************************************************/
80 NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_token, uint32 des_access,
81 uint32 *acc_granted, const char *debug)
83 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
85 if (!se_access_check(psd, nt_user_token, des_access, acc_granted, &status)) {
86 if (geteuid() == sec_initial_uid()) {
87 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n",
89 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
90 status = NT_STATUS_OK;
93 DEBUG(2,("%s: ACCESS DENIED (requested: %#010x)\n",
100 /*******************************************************************
101 Checks if access to a function can be granted
102 ********************************************************************/
104 NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
106 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
107 debug, acc_granted, acc_required));
108 if ((acc_granted & acc_required) != acc_required) {
109 if (geteuid() == sec_initial_uid()) {
110 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
111 debug, acc_granted, acc_required));
112 DEBUGADD(4,("but overwritten by euid == 0\n"));
115 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
116 debug, acc_granted, acc_required));
117 return NT_STATUS_ACCESS_DENIED;
123 /*******************************************************************
124 Create a samr_info struct.
125 ********************************************************************/
127 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
129 struct samr_info *info;
134 sid_to_string(sid_str, psid);
136 fstrcpy(sid_str,"(NULL)");
139 mem_ctx = talloc_init_named("samr_info for domain sid %s", sid_str);
141 if ((info = (struct samr_info *)talloc(mem_ctx, sizeof(struct samr_info))) == NULL)
145 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
147 sid_copy( &info->sid, psid);
149 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
151 info->mem_ctx = mem_ctx;
156 /*******************************************************************
157 Function to free the per handle data.
158 ********************************************************************/
159 static void free_samr_users(struct samr_info *info)
163 if (info->disp_info.user_dbloaded){
164 for (i=0; i<info->disp_info.num_user_account; i++) {
165 /* Not really a free, actually a 'clear' */
166 pdb_free_sam(&info->disp_info.disp_user_info[i].sam);
169 info->disp_info.user_dbloaded=False;
170 info->disp_info.num_user_account=0;
174 /*******************************************************************
175 Function to free the per handle data.
176 ********************************************************************/
177 static void free_samr_db(struct samr_info *info)
179 /* Groups are talloced */
181 free_samr_users(info);
183 info->disp_info.group_dbloaded=False;
184 info->disp_info.num_group_account=0;
188 static void free_samr_info(void *ptr)
190 struct samr_info *info=(struct samr_info *) ptr;
193 talloc_destroy(info->mem_ctx);
196 /*******************************************************************
197 Ensure password info is never given out. Paranioa... JRA.
198 ********************************************************************/
200 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
206 /* These now zero out the old password */
208 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
209 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
213 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL all_machines)
215 SAM_ACCOUNT *pwd = NULL;
216 DISP_USER_INFO *pwd_array = NULL;
217 NTSTATUS nt_status = NT_STATUS_OK;
218 TALLOC_CTX *mem_ctx = info->mem_ctx;
220 DEBUG(10,("load_sampwd_entries\n"));
222 /* if the snapshoot is already loaded, return */
223 if ((info->disp_info.user_dbloaded==True)
224 && (info->acb_mask == acb_mask)
225 && (info->all_machines == all_machines)) {
226 DEBUG(10,("load_sampwd_entries: already in memory\n"));
230 free_samr_users(info);
232 if (!pdb_setsampwent(False)) {
233 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
234 return NT_STATUS_ACCESS_DENIED;
237 for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd)))
238 && pdb_getsampwent(pwd) == True; pwd=NULL) {
241 if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST)
242 || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
243 DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
248 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
250 DEBUG(5,(" acb_mask %x reject\n", acb_mask));
255 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
256 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
258 DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
259 pwd_array=(DISP_USER_INFO *)talloc_realloc(mem_ctx, info->disp_info.disp_user_info,
260 (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(DISP_USER_INFO));
263 return NT_STATUS_NO_MEMORY;
265 info->disp_info.disp_user_info=pwd_array;
268 /* link the SAM_ACCOUNT to the array */
269 info->disp_info.disp_user_info[info->disp_info.num_user_account].sam=pwd;
271 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
273 info->disp_info.num_user_account++;
278 /* the snapshoot is in memory, we're ready to enumerate fast */
280 info->acb_mask = acb_mask;
281 info->all_machines = all_machines;
282 info->disp_info.user_dbloaded=True;
284 DEBUG(10,("load_sampwd_entries: done\n"));
289 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
292 DISP_GROUP_INFO *grp_array = NULL;
293 uint32 group_entries = 0;
295 TALLOC_CTX *mem_ctx = info->mem_ctx;
297 DEBUG(10,("load_group_domain_entries\n"));
299 /* if the snapshoot is already loaded, return */
300 if (info->disp_info.group_dbloaded==True) {
301 DEBUG(10,("load_group_domain_entries: already in memory\n"));
305 if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV)) {
306 return NT_STATUS_NO_MEMORY;
309 info->disp_info.num_group_account=group_entries;
311 grp_array=(DISP_GROUP_INFO *)talloc(mem_ctx, info->disp_info.num_group_account*sizeof(DISP_GROUP_INFO));
313 if (group_entries!=0 && grp_array==NULL) {
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?
1191 free_samr_users(info);
1195 /* Level 2 is for all machines, otherwise only 'normal' users */
1196 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1198 if (!NT_STATUS_IS_OK(r_u->status)) {
1199 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1202 num_account = info->disp_info.num_user_account;
1206 r_u->status = load_group_domain_entries(info, &info->sid);
1207 if (!NT_STATUS_IS_OK(r_u->status))
1209 num_account = info->disp_info.num_group_account;
1212 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1213 return NT_STATUS_INVALID_INFO_CLASS;
1216 /* first limit the number of entries we will return */
1217 if(max_entries > max_sam_entries) {
1218 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1219 max_entries = max_sam_entries;
1222 if (enum_context > num_account) {
1223 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1224 return NT_STATUS_NO_MORE_ENTRIES;
1227 /* verify we won't overflow */
1228 if (max_entries > num_account-enum_context) {
1229 max_entries = num_account-enum_context;
1230 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1233 /* calculate the size and limit on the number of entries we will return */
1234 temp_size=max_entries*struct_size;
1236 if (temp_size>max_size) {
1237 max_entries=MIN((max_size/struct_size),max_entries);;
1238 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1241 if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1242 return NT_STATUS_NO_MEMORY;
1246 /* Now create reply structure */
1247 switch (q_u->switch_level) {
1250 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
1251 return NT_STATUS_NO_MEMORY;
1253 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1254 info->disp_info.disp_user_info, &domain_sid);
1255 if (!NT_STATUS_IS_OK(disp_ret))
1260 if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1261 return NT_STATUS_NO_MEMORY;
1263 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1264 info->disp_info.disp_user_info, &domain_sid);
1265 if (!NT_STATUS_IS_OK(disp_ret))
1270 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1271 return NT_STATUS_NO_MEMORY;
1273 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1274 if (!NT_STATUS_IS_OK(disp_ret))
1279 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1280 return NT_STATUS_NO_MEMORY;
1282 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1283 if (!NT_STATUS_IS_OK(disp_ret))
1288 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1289 return NT_STATUS_NO_MEMORY;
1291 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1292 if (!NT_STATUS_IS_OK(disp_ret))
1297 ctr->sam.info = NULL;
1298 return NT_STATUS_INVALID_INFO_CLASS;
1301 /* calculate the total size */
1302 total_data_size=num_account*struct_size;
1304 if (enum_context+max_entries < num_account)
1305 r_u->status = STATUS_MORE_ENTRIES;
1307 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1309 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1315 /*******************************************************************
1316 samr_reply_query_aliasinfo
1317 ********************************************************************/
1319 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1325 r_u->status = NT_STATUS_OK;
1327 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1329 /* find the policy handle. open a policy on it. */
1330 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1331 return NT_STATUS_INVALID_HANDLE;
1332 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1336 if (!sid_check_is_in_our_domain(&sid) &&
1337 !sid_check_is_in_builtin(&sid))
1338 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1340 if (!pdb_getgrsid(&map, sid, MAPPING_WITHOUT_PRIV))
1341 return NT_STATUS_NO_SUCH_ALIAS;
1343 switch (q_u->switch_level) {
1346 r_u->ctr.switch_value1 = 1;
1347 init_samr_alias_info1(&r_u->ctr.alias.info1, map.nt_name, 1, map.comment);
1351 r_u->ctr.switch_value1 = 3;
1352 init_samr_alias_info3(&r_u->ctr.alias.info3, map.comment);
1355 return NT_STATUS_INVALID_INFO_CLASS;
1358 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1364 /*******************************************************************
1365 samr_reply_lookup_ids
1366 ********************************************************************/
1368 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1370 uint32 rid[MAX_SAM_ENTRIES];
1371 int num_rids = q_u->num_sids1;
1373 r_u->status = NT_STATUS_OK;
1375 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1377 if (num_rids > MAX_SAM_ENTRIES) {
1378 num_rids = MAX_SAM_ENTRIES;
1379 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1384 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1386 for (i = 0; i < num_rids && status == 0; i++)
1388 struct sam_passwd *sam_pass;
1392 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1393 q_u->uni_user_name[i].uni_str_len));
1395 /* find the user account */
1397 sam_pass = get_smb21pwd_entry(user_name, 0);
1400 if (sam_pass == NULL)
1402 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1407 rid[i] = sam_pass->user_rid;
1413 rid[0] = BUILTIN_ALIAS_RID_USERS;
1415 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1417 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1423 /*******************************************************************
1425 ********************************************************************/
1427 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1429 uint32 rid[MAX_SAM_ENTRIES];
1431 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1432 enum SID_NAME_USE local_type;
1434 int num_rids = q_u->num_names2;
1439 r_u->status = NT_STATUS_OK;
1441 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1446 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1447 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1451 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 */
1455 if (num_rids > MAX_SAM_ENTRIES) {
1456 num_rids = MAX_SAM_ENTRIES;
1457 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1460 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1462 become_root(); /* local_lookup_name can require root privs */
1464 for (i = 0; i < num_rids; i++) {
1468 r_u->status = NT_STATUS_NONE_MAPPED;
1470 rid [i] = 0xffffffff;
1471 type[i] = SID_NAME_UNKNOWN;
1473 rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1476 * we are only looking for a name
1477 * the SID we get back can be outside
1478 * the scope of the pol_sid
1480 * in clear: it prevents to reply to domain\group: yes
1481 * when only builtin\group exists.
1483 * a cleaner code is to add the sid of the domain we're looking in
1484 * to the local_lookup_name function.
1486 if(local_lookup_name(name, &sid, &local_type)) {
1487 sid_split_rid(&sid, &local_rid);
1489 if (sid_equal(&sid, &pol_sid)) {
1492 r_u->status = NT_STATUS_OK;
1499 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1501 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1506 /*******************************************************************
1507 _samr_chgpasswd_user
1508 ********************************************************************/
1510 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1515 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1517 r_u->status = NT_STATUS_OK;
1519 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1520 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1522 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1525 * Pass the user through the NT -> unix user mapping
1529 (void)map_username(user_name);
1532 * UNIX username case mangling not required, pass_oem_change
1533 * is case insensitive.
1536 if (!pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1537 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1538 r_u->status = NT_STATUS_WRONG_PASSWORD;
1540 init_samr_r_chgpasswd_user(r_u, r_u->status);
1542 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1547 /*******************************************************************
1548 makes a SAMR_R_LOOKUP_RIDS structure.
1549 ********************************************************************/
1551 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1552 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1555 UNIHDR *hdr_name=NULL;
1556 UNISTR2 *uni_name=NULL;
1558 *pp_uni_name = NULL;
1559 *pp_hdr_name = NULL;
1561 if (num_names != 0) {
1562 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1563 if (hdr_name == NULL)
1566 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1567 if (uni_name == NULL)
1571 for (i = 0; i < num_names; i++) {
1572 int len = names[i] != NULL ? strlen(names[i]) : 0;
1573 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1574 init_uni_hdr(&hdr_name[i], len);
1575 init_unistr2(&uni_name[i], names[i], len);
1578 *pp_uni_name = uni_name;
1579 *pp_hdr_name = hdr_name;
1584 /*******************************************************************
1586 ********************************************************************/
1588 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1590 fstring group_names[MAX_SAM_ENTRIES];
1591 uint32 *group_attrs = NULL;
1592 UNIHDR *hdr_name = NULL;
1593 UNISTR2 *uni_name = NULL;
1595 int num_rids = q_u->num_rids1;
1599 r_u->status = NT_STATUS_OK;
1601 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1603 /* find the policy handle. open a policy on it. */
1604 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1605 return NT_STATUS_INVALID_HANDLE;
1607 if (num_rids > MAX_SAM_ENTRIES) {
1608 num_rids = MAX_SAM_ENTRIES;
1609 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1613 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1614 return NT_STATUS_NO_MEMORY;
1617 r_u->status = NT_STATUS_NONE_MAPPED;
1619 become_root(); /* lookup_sid can require root privs */
1621 for (i = 0; i < num_rids; i++) {
1625 enum SID_NAME_USE type;
1627 group_attrs[i] = SID_NAME_UNKNOWN;
1628 *group_names[i] = '\0';
1630 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1631 sid_copy(&sid, &pol_sid);
1632 sid_append_rid(&sid, q_u->rid[i]);
1634 if (lookup_sid(&sid, domname, tmpname, &type)) {
1635 r_u->status = NT_STATUS_OK;
1636 group_attrs[i] = (uint32)type;
1637 fstrcpy(group_names[i],tmpname);
1638 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1645 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1646 return NT_STATUS_NO_MEMORY;
1648 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1650 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1655 /*******************************************************************
1656 _api_samr_open_user. Safe - gives out no passwd info.
1657 ********************************************************************/
1659 NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1661 SAM_ACCOUNT *sampass=NULL;
1663 POLICY_HND domain_pol = q_u->domain_pol;
1664 POLICY_HND *user_pol = &r_u->user_pol;
1665 struct samr_info *info = NULL;
1666 SEC_DESC *psd = NULL;
1668 uint32 des_access = q_u->access_mask;
1673 r_u->status = NT_STATUS_OK;
1675 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1676 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1677 return NT_STATUS_INVALID_HANDLE;
1679 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1683 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1684 if (!NT_STATUS_IS_OK(nt_status)) {
1688 /* append the user's RID to it */
1689 if (!sid_append_rid(&sid, q_u->user_rid))
1690 return NT_STATUS_NO_SUCH_USER;
1692 /* check if access can be granted as requested by client. */
1693 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1694 se_map_generic(&des_access, &usr_generic_mapping);
1695 if (!NT_STATUS_IS_OK(nt_status =
1696 access_check_samr_object(psd, p->pipe_user.nt_user_token,
1697 des_access, &acc_granted, "_samr_open_user"))) {
1702 ret=pdb_getsampwsid(sampass, &sid);
1705 /* check that the SID exists in our domain. */
1707 return NT_STATUS_NO_SUCH_USER;
1710 pdb_free_sam(&sampass);
1712 /* associate the user's SID and access bits with the new handle. */
1713 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1714 return NT_STATUS_NO_MEMORY;
1715 info->acc_granted = acc_granted;
1717 /* get a (unique) handle. open a policy on it. */
1718 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1719 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1724 /*************************************************************************
1725 get_user_info_10. Safe. Only gives out acb bits.
1726 *************************************************************************/
1728 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1730 SAM_ACCOUNT *smbpass=NULL;
1734 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1736 if (!NT_STATUS_IS_OK(nt_status)) {
1741 ret = pdb_getsampwsid(smbpass, user_sid);
1745 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1746 return NT_STATUS_NO_SUCH_USER;
1749 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1752 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1754 pdb_free_sam(&smbpass);
1756 return NT_STATUS_OK;
1759 /*************************************************************************
1760 get_user_info_12. OK - this is the killer as it gives out password info.
1761 Ensure that this is only allowed on an encrypted connection with a root
1763 *************************************************************************/
1765 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1767 SAM_ACCOUNT *smbpass=NULL;
1771 if (!p->ntlmssp_auth_validated)
1772 return NT_STATUS_ACCESS_DENIED;
1774 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1775 return NT_STATUS_ACCESS_DENIED;
1778 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1781 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1783 if (!NT_STATUS_IS_OK(nt_status)) {
1787 ret = pdb_getsampwsid(smbpass, user_sid);
1790 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1791 pdb_free_sam(&smbpass);
1792 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1795 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1797 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1798 pdb_free_sam(&smbpass);
1799 return NT_STATUS_ACCOUNT_DISABLED;
1803 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1805 pdb_free_sam(&smbpass);
1807 return NT_STATUS_OK;
1810 /*************************************************************************
1812 *************************************************************************/
1814 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1816 SAM_ACCOUNT *sampass=NULL;
1819 pdb_init_sam_talloc(mem_ctx, &sampass);
1822 ret = pdb_getsampwsid(sampass, user_sid);
1826 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1827 return NT_STATUS_NO_SUCH_USER;
1830 samr_clear_sam_passwd(sampass);
1832 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1835 init_sam_user_info20A(id20, sampass);
1837 pdb_free_sam(&sampass);
1839 return NT_STATUS_OK;
1842 /*************************************************************************
1844 *************************************************************************/
1846 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1847 DOM_SID *user_sid, DOM_SID *domain_sid)
1849 SAM_ACCOUNT *sampass=NULL;
1853 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1854 if (!NT_STATUS_IS_OK(nt_status)) {
1859 ret = pdb_getsampwsid(sampass, user_sid);
1863 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1864 return NT_STATUS_NO_SUCH_USER;
1867 samr_clear_sam_passwd(sampass);
1869 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1872 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1874 pdb_free_sam(&sampass);
1876 return NT_STATUS_OK;
1879 /*******************************************************************
1880 _samr_query_userinfo
1881 ********************************************************************/
1883 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1885 SAM_USERINFO_CTR *ctr;
1886 struct samr_info *info = NULL;
1890 r_u->status=NT_STATUS_OK;
1892 /* search for the handle */
1893 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1894 return NT_STATUS_INVALID_HANDLE;
1896 domain_sid = info->sid;
1898 sid_split_rid(&domain_sid, &rid);
1900 if (!sid_check_is_in_our_domain(&info->sid))
1901 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1903 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1905 ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1907 return NT_STATUS_NO_MEMORY;
1911 /* ok! user info levels (lots: see MSDEV help), off we go... */
1912 ctr->switch_value = q_u->switch_value;
1914 switch (q_u->switch_value) {
1916 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1917 if (ctr->info.id10 == NULL)
1918 return NT_STATUS_NO_MEMORY;
1920 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1925 /* whoops - got this wrong. i think. or don't understand what's happening. */
1929 info = (void *)&id11;
1931 expire.low = 0xffffffff;
1932 expire.high = 0x7fffffff;
1934 ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1939 ZERO_STRUCTP(ctr->info.id11);
1940 init_sam_user_info11(ctr->info.id11, &expire,
1941 "BROOKFIELDS$", /* name */
1942 0x03ef, /* user rid */
1943 0x201, /* group rid */
1944 0x0080); /* acb info */
1951 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1952 if (ctr->info.id12 == NULL)
1953 return NT_STATUS_NO_MEMORY;
1955 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1960 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1961 if (ctr->info.id20 == NULL)
1962 return NT_STATUS_NO_MEMORY;
1963 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1968 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1969 if (ctr->info.id21 == NULL)
1970 return NT_STATUS_NO_MEMORY;
1971 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1972 &info->sid, &domain_sid)))
1977 return NT_STATUS_INVALID_INFO_CLASS;
1980 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1982 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1987 /*******************************************************************
1988 samr_reply_query_usergroups
1989 ********************************************************************/
1991 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1993 SAM_ACCOUNT *sam_pass=NULL;
1995 DOM_GID *gids = NULL;
2001 * from the SID in the request:
2002 * we should send back the list of DOMAIN GROUPS
2003 * the user is a member of
2005 * and only the DOMAIN GROUPS
2006 * no ALIASES !!! neither aliases of the domain
2007 * nor aliases of the builtin SID
2012 r_u->status = NT_STATUS_OK;
2014 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2016 /* find the policy handle. open a policy on it. */
2017 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
2018 return NT_STATUS_INVALID_HANDLE;
2020 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
2024 if (!sid_check_is_in_our_domain(&sid))
2025 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2027 pdb_init_sam(&sam_pass);
2030 ret = pdb_getsampwsid(sam_pass, &sid);
2034 pdb_free_sam(&sam_pass);
2035 return NT_STATUS_NO_SUCH_USER;
2038 if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
2039 pdb_free_sam(&sam_pass);
2040 return NT_STATUS_NO_SUCH_GROUP;
2043 /* construct the response. lkclXXXX: gids are not copied! */
2044 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
2046 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2048 pdb_free_sam(&sam_pass);
2053 /*******************************************************************
2054 _samr_query_dom_info
2055 ********************************************************************/
2057 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2059 struct samr_info *info = NULL;
2061 uint32 min_pass_len,pass_hist,flag;
2062 time_t u_expire, u_min_age;
2063 NTTIME nt_expire, nt_min_age;
2065 time_t u_lock_duration, u_reset_time;
2066 NTTIME nt_lock_duration, nt_reset_time;
2072 uint32 account_policy_temp;
2074 uint32 num_users=0, num_groups=0, num_aliases=0;
2076 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
2077 return NT_STATUS_NO_MEMORY;
2081 r_u->status = NT_STATUS_OK;
2083 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2085 /* find the policy handle. open a policy on it. */
2086 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2087 return NT_STATUS_INVALID_HANDLE;
2089 switch (q_u->switch_value) {
2092 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2093 min_pass_len = account_policy_temp;
2095 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2096 pass_hist = account_policy_temp;
2098 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2099 flag = account_policy_temp;
2101 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2102 u_expire = account_policy_temp;
2104 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2105 u_min_age = account_policy_temp;
2107 unix_to_nt_time_abs(&nt_expire, u_expire);
2108 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2110 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2111 flag, nt_expire, nt_min_age);
2115 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2117 if (!NT_STATUS_IS_OK(r_u->status)) {
2118 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2121 num_users=info->disp_info.num_user_account;
2124 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2125 if (!NT_STATUS_IS_OK(r_u->status)) {
2126 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2129 num_groups=info->disp_info.num_group_account;
2132 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2133 init_unk_info2(&ctr->info.inf2, global_myworkgroup, global_myname, (uint32) time(NULL),
2134 num_users, num_groups, num_aliases);
2137 account_policy_get(AP_TIME_TO_LOGOUT, (int *)&u_logout);
2138 unix_to_nt_time_abs(&nt_logout, u_logout);
2140 init_unk_info3(&ctr->info.inf3, nt_logout);
2143 init_unk_info5(&ctr->info.inf5, global_myname);
2146 init_unk_info6(&ctr->info.inf6);
2149 init_unk_info7(&ctr->info.inf7);
2152 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2153 u_lock_duration = account_policy_temp;
2155 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2156 u_reset_time = account_policy_temp;
2158 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2159 lockout = account_policy_temp;
2161 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2162 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2164 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2167 return NT_STATUS_INVALID_INFO_CLASS;
2170 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2172 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2177 /*******************************************************************
2178 _api_samr_create_user
2179 Create an account, can be either a normal user or a machine.
2180 This funcion will need to be updated for bdc/domain trusts.
2181 ********************************************************************/
2183 NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2185 SAM_ACCOUNT *sam_pass=NULL;
2189 POLICY_HND dom_pol = q_u->domain_pol;
2190 UNISTR2 user_account = q_u->uni_name;
2191 uint16 acb_info = q_u->acb_info;
2192 POLICY_HND *user_pol = &r_u->user_pol;
2193 struct samr_info *info = NULL;
2202 /* Get the domain SID stored in the domain policy */
2203 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2204 return NT_STATUS_INVALID_HANDLE;
2206 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2210 /* find the account: tell the caller if it exists.
2211 lkclXXXX i have *no* idea if this is a problem or not
2212 or even if you are supposed to construct a different
2213 reply if the account already exists...
2216 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2219 pdb_init_sam(&sam_pass);
2222 ret = pdb_getsampwnam(sam_pass, account);
2225 /* this account exists: say so */
2226 pdb_free_sam(&sam_pass);
2227 return NT_STATUS_USER_EXISTS;
2230 pdb_free_sam(&sam_pass);
2233 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2234 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2235 * that only people with write access to the smbpasswd file will be able
2236 * to create a user. JRA.
2240 * add the user in the /etc/passwd file or the unix authority system.
2241 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2242 * a) local_password_change() checks for us if the /etc/passwd account really exists
2243 * b) smb_create_user() would return an error if the account already exists
2244 * and as it could return an error also if it can't create the account, it would be tricky.
2246 * So we go the easy way, only check after if the account exists.
2247 * JFM (2/3/2001), to clear any possible bad understanding (-:
2249 * We now have seperate script paramaters for adding users/machines so we
2250 * now have some sainity-checking to match.
2253 DEBUG(10,("checking account %s at pos %d for $ termination\n",account, strlen(account)-1));
2255 if ((acb_info & ACB_WSTRUST) && (account[strlen(account)-1] == '$')) {
2256 pstrcpy(add_script, lp_addmachine_script());
2257 } else if ((!(acb_info & ACB_WSTRUST)) && (account[strlen(account)-1] != '$')) {
2258 pstrcpy(add_script, lp_adduser_script());
2260 DEBUG(0, ("_api_samr_create_user: mismatch between trust flags and $ termination\n"));
2261 pdb_free_sam(&sam_pass);
2262 return NT_STATUS_UNSUCCESSFUL;
2267 * we can't check both the ending $ and the acb_info.
2269 * UserManager creates trust accounts (ending in $,
2270 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2273 if (account[strlen(account)-1] == '$')
2274 pstrcpy(add_script, lp_addmachine_script());
2276 pstrcpy(add_script, lp_adduser_script());
2280 all_string_sub(add_script, "%u", account, sizeof(account));
2281 add_ret = smbrun(add_script,NULL);
2282 DEBUG(3,("_api_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2285 pw = getpwnam_alloc(account);
2288 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sam_pass, pw))) {
2292 passwd_free(&pw); /* done with this now */
2294 DEBUG(3,("attempting to create non-unix account %s\n", account));
2296 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sam_pass))) {
2300 if (!pdb_set_username(sam_pass, account, PDB_CHANGED)) {
2301 pdb_free_sam(&sam_pass);
2302 return NT_STATUS_NO_MEMORY;
2306 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2308 if (!pdb_add_sam_account(sam_pass)) {
2309 pdb_free_sam(&sam_pass);
2310 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2312 return NT_STATUS_ACCESS_DENIED;
2315 pdb_reset_sam(sam_pass);
2317 if (!pdb_getsampwnam(sam_pass, account)) {
2318 pdb_free_sam(&sam_pass);
2319 DEBUG(0, ("could not find user/computer %s just added to passdb?!?\n",
2321 return NT_STATUS_ACCESS_DENIED;
2324 /* Get the user's SID */
2325 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2327 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2328 se_map_generic(&des_access, &usr_generic_mapping);
2329 if (!NT_STATUS_IS_OK(nt_status =
2330 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2331 des_access, &acc_granted, "_samr_create_user"))) {
2335 /* associate the user's SID with the new handle. */
2336 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2337 pdb_free_sam(&sam_pass);
2338 return NT_STATUS_NO_MEMORY;
2343 info->acc_granted = acc_granted;
2345 /* get a (unique) handle. open a policy on it. */
2346 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2347 pdb_free_sam(&sam_pass);
2348 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2351 r_u->user_rid=pdb_get_user_rid(sam_pass);
2353 r_u->access_granted = acc_granted;
2355 pdb_free_sam(&sam_pass);
2357 return NT_STATUS_OK;
2360 /*******************************************************************
2361 samr_reply_connect_anon
2362 ********************************************************************/
2364 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2366 struct samr_info *info = NULL;
2370 if (!pipe_access_check(p)) {
2371 DEBUG(3, ("access denied to samr_connect_anon\n"));
2372 r_u->status = NT_STATUS_ACCESS_DENIED;
2376 /* set up the SAMR connect_anon response */
2378 r_u->status = NT_STATUS_OK;
2380 /* associate the user's SID with the new handle. */
2381 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2382 return NT_STATUS_NO_MEMORY;
2384 info->status = q_u->unknown_0;
2386 /* get a (unique) handle. open a policy on it. */
2387 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2388 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2393 /*******************************************************************
2395 ********************************************************************/
2397 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2399 struct samr_info *info = NULL;
2400 SEC_DESC *psd = NULL;
2402 uint32 des_access = q_u->access_mask;
2407 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2411 if (!pipe_access_check(p)) {
2412 DEBUG(3, ("access denied to samr_connect\n"));
2413 r_u->status = NT_STATUS_ACCESS_DENIED;
2417 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2418 se_map_generic(&des_access, &sam_generic_mapping);
2419 if (!NT_STATUS_IS_OK(nt_status =
2420 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2421 des_access, &acc_granted, "_samr_connect"))) {
2425 r_u->status = NT_STATUS_OK;
2427 /* associate the user's SID and access granted with the new handle. */
2428 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2429 return NT_STATUS_NO_MEMORY;
2431 info->acc_granted = acc_granted;
2432 info->status = q_u->access_mask;
2434 /* get a (unique) handle. open a policy on it. */
2435 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2436 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2438 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2443 /*******************************************************************
2445 ********************************************************************/
2447 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2449 struct samr_info *info = NULL;
2450 SEC_DESC *psd = NULL;
2452 uint32 des_access = q_u->access_mask;
2457 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2461 if (!pipe_access_check(p)) {
2462 DEBUG(3, ("access denied to samr_connect4\n"));
2463 r_u->status = NT_STATUS_ACCESS_DENIED;
2467 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2468 se_map_generic(&des_access, &sam_generic_mapping);
2469 if (!NT_STATUS_IS_OK(nt_status =
2470 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2471 des_access, &acc_granted, "_samr_connect"))) {
2475 r_u->status = NT_STATUS_OK;
2477 /* associate the user's SID and access granted with the new handle. */
2478 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2479 return NT_STATUS_NO_MEMORY;
2481 info->acc_granted = acc_granted;
2482 info->status = q_u->access_mask;
2484 /* get a (unique) handle. open a policy on it. */
2485 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2486 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2488 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2493 /**********************************************************************
2494 api_samr_lookup_domain
2495 **********************************************************************/
2497 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2499 struct samr_info *info;
2500 fstring domain_name;
2503 r_u->status = NT_STATUS_OK;
2505 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2506 return NT_STATUS_INVALID_HANDLE;
2508 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain"))) {
2512 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2516 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2517 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2520 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2522 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2527 /******************************************************************
2528 makes a SAMR_R_ENUM_DOMAINS structure.
2529 ********************************************************************/
2531 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2532 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2538 DEBUG(5, ("make_enum_domains\n"));
2541 *pp_uni_name = NULL;
2543 if (num_sam_entries == 0)
2546 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2547 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2549 if (sam == NULL || uni_name == NULL)
2552 for (i = 0; i < num_sam_entries; i++) {
2553 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
2555 init_sam_entry(&sam[i], len, 0);
2556 init_unistr2(&uni_name[i], doms[i], len);
2560 *pp_uni_name = uni_name;
2565 /**********************************************************************
2566 api_samr_enum_domains
2567 **********************************************************************/
2569 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2571 struct samr_info *info;
2572 uint32 num_entries = 2;
2576 r_u->status = NT_STATUS_OK;
2578 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2579 return NT_STATUS_INVALID_HANDLE;
2581 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2585 switch (lp_server_role()) {
2586 case ROLE_DOMAIN_PDC:
2587 case ROLE_DOMAIN_BDC:
2588 name = global_myworkgroup;
2591 name = global_myname;
2594 fstrcpy(dom[0],name);
2596 fstrcpy(dom[1],"Builtin");
2598 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2599 return NT_STATUS_NO_MEMORY;
2601 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2606 /*******************************************************************
2608 ********************************************************************/
2610 NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2613 POLICY_HND domain_pol = q_u->dom_pol;
2614 uint32 alias_rid = q_u->rid_alias;
2615 POLICY_HND *alias_pol = &r_u->pol;
2616 struct samr_info *info = NULL;
2617 SEC_DESC *psd = NULL;
2619 uint32 des_access = q_u->access_mask;
2623 r_u->status = NT_STATUS_OK;
2625 /* find the domain policy and get the SID / access bits stored in the domain policy */
2626 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2627 return NT_STATUS_INVALID_HANDLE;
2629 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2633 /* append the alias' RID to it */
2634 if (!sid_append_rid(&sid, alias_rid))
2635 return NT_STATUS_NO_SUCH_USER;
2637 /*check if access can be granted as requested by client. */
2638 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2639 se_map_generic(&des_access,&ali_generic_mapping);
2640 if (!NT_STATUS_IS_OK(status =
2641 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2642 des_access, &acc_granted, "_samr_open_alias"))) {
2647 * we should check if the rid really exist !!!
2651 /* associate the user's SID with the new handle. */
2652 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2653 return NT_STATUS_NO_MEMORY;
2655 info->acc_granted = acc_granted;
2657 /* get a (unique) handle. open a policy on it. */
2658 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2659 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2664 /*******************************************************************
2666 ********************************************************************/
2668 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2670 SAM_ACCOUNT *pwd =NULL;
2675 ret = pdb_getsampwsid(pwd, sid);
2683 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2688 /* FIX ME: check if the value is really changed --metze */
2689 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2694 if(!pdb_update_sam_account(pwd)) {
2704 /*******************************************************************
2706 ********************************************************************/
2708 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2710 SAM_ACCOUNT *pwd = NULL;
2714 if(!pdb_getsampwsid(pwd, sid)) {
2720 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2725 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2729 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2733 if (!pdb_set_pass_changed_now (pwd)) {
2738 if(!pdb_update_sam_account(pwd)) {
2747 /*******************************************************************
2749 ********************************************************************/
2751 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2753 SAM_ACCOUNT *pwd = NULL;
2756 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2762 if (!pdb_getsampwsid(pwd, sid)) {
2767 copy_id21_to_sam_passwd(pwd, id21);
2770 * The funny part about the previous two calls is
2771 * that pwd still has the password hashes from the
2772 * passdb entry. These have not been updated from
2773 * id21. I don't know if they need to be set. --jerry
2776 /* write the change out */
2777 if(!pdb_update_sam_account(pwd)) {
2787 /*******************************************************************
2789 ********************************************************************/
2791 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2793 SAM_ACCOUNT *pwd = NULL;
2794 pstring plaintext_buf;
2799 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2805 if (!pdb_getsampwsid(pwd, sid)) {
2810 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2811 pdb_get_username(pwd)));
2813 acct_ctrl = pdb_get_acct_ctrl(pwd);
2815 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
2820 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2825 copy_id23_to_sam_passwd(pwd, id23);
2827 /* if it's a trust account, don't update /etc/passwd */
2828 if ( (!IS_SAM_UNIX_USER(pwd)) ||
2829 ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2830 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2831 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2832 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2834 /* update the UNIX password */
2835 if (lp_unix_password_sync() )
2836 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2842 ZERO_STRUCT(plaintext_buf);
2844 if(!pdb_update_sam_account(pwd)) {
2854 /*******************************************************************
2856 ********************************************************************/
2858 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2860 SAM_ACCOUNT *pwd = NULL;
2862 pstring plaintext_buf;
2867 if (!pdb_getsampwsid(pwd, sid)) {
2872 DEBUG(5, ("Attempting administrator password change for user %s\n",
2873 pdb_get_username(pwd)));
2875 acct_ctrl = pdb_get_acct_ctrl(pwd);
2877 ZERO_STRUCT(plaintext_buf);
2879 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) {
2884 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2889 /* if it's a trust account, don't update /etc/passwd */
2890 if ( (!IS_SAM_UNIX_USER(pwd)) ||
2891 ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2892 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2893 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2894 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2896 /* update the UNIX password */
2897 if (lp_unix_password_sync()) {
2898 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2905 ZERO_STRUCT(plaintext_buf);
2907 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2909 /* update the SAMBA password */
2910 if(!pdb_update_sam_account(pwd)) {
2920 /*******************************************************************
2921 samr_reply_set_userinfo
2922 ********************************************************************/
2924 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2927 POLICY_HND *pol = &q_u->pol;
2928 uint16 switch_value = q_u->switch_value;
2929 SAM_USERINFO_CTR *ctr = q_u->ctr;
2931 uint32 acc_required;
2933 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2935 r_u->status = NT_STATUS_OK;
2937 /* find the policy handle. open a policy on it. */
2938 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2939 return NT_STATUS_INVALID_HANDLE;
2941 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
2942 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2946 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
2949 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2950 return NT_STATUS_INVALID_INFO_CLASS;
2953 /* ok! user info levels (lots: see MSDEV help), off we go... */
2954 switch (switch_value) {
2956 if (!set_user_info_12(ctr->info.id12, &sid))
2957 return NT_STATUS_ACCESS_DENIED;
2961 SamOEMhash(ctr->info.id24->pass, p->session_key, 516);
2963 dump_data(100, (char *)ctr->info.id24->pass, 516);
2965 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
2966 return NT_STATUS_ACCESS_DENIED;
2972 * Currently we don't really know how to unmarshall
2973 * the level 25 struct, and the password encryption
2974 * is different. This is a placeholder for when we
2975 * do understand it. In the meantime just return INVALID
2976 * info level and W2K SP2 drops down to level 23... JRA.
2979 SamOEMhash(ctr->info.id25->pass, p->session_key, 532);
2981 dump_data(100, (char *)ctr->info.id25->pass, 532);
2983 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
2984 return NT_STATUS_ACCESS_DENIED;
2987 return NT_STATUS_INVALID_INFO_CLASS;
2990 SamOEMhash(ctr->info.id23->pass, p->session_key, 516);
2992 dump_data(100, (char *)ctr->info.id23->pass, 516);
2994 if (!set_user_info_23(ctr->info.id23, &sid))
2995 return NT_STATUS_ACCESS_DENIED;
2999 return NT_STATUS_INVALID_INFO_CLASS;
3005 /*******************************************************************
3006 samr_reply_set_userinfo2
3007 ********************************************************************/
3009 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3012 SAM_USERINFO_CTR *ctr = q_u->ctr;
3013 POLICY_HND *pol = &q_u->pol;
3014 uint16 switch_value = q_u->switch_value;
3016 uint32 acc_required;
3018 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3020 r_u->status = NT_STATUS_OK;
3022 /* find the policy handle. open a policy on it. */
3023 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3024 return NT_STATUS_INVALID_HANDLE;
3026 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3027 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3031 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3034 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3035 return NT_STATUS_INVALID_INFO_CLASS;
3038 switch_value=ctr->switch_value;
3040 /* ok! user info levels (lots: see MSDEV help), off we go... */
3041 switch (switch_value) {
3043 if (!set_user_info_21(ctr->info.id21, &sid))
3044 return NT_STATUS_ACCESS_DENIED;
3047 if (!set_user_info_10(ctr->info.id10, &sid))
3048 return NT_STATUS_ACCESS_DENIED;
3051 /* Used by AS/U JRA. */
3052 if (!set_user_info_12(ctr->info.id12, &sid))
3053 return NT_STATUS_ACCESS_DENIED;
3056 return NT_STATUS_INVALID_INFO_CLASS;
3062 /*********************************************************************
3063 _samr_query_aliasmem
3064 *********************************************************************/
3066 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3068 int num_groups = 0, tmp_num_groups=0;
3069 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3070 struct samr_info *info = NULL;
3076 /* until i see a real useraliases query, we fack one up */
3078 /* I have seen one, JFM 2/12/2001 */
3080 * Explanation of what this call does:
3081 * for all the SID given in the request:
3082 * return a list of alias (local groups)
3083 * that have those SID as members.
3085 * and that's the alias in the domain specified
3086 * in the policy_handle
3088 * if the policy handle is on an incorrect sid
3089 * for example a user's sid
3090 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3093 r_u->status = NT_STATUS_OK;
3095 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3097 /* find the policy handle. open a policy on it. */
3098 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3099 return NT_STATUS_INVALID_HANDLE;
3101 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3102 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3104 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3105 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3106 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3107 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3111 if (!sid_check_is_domain(&info->sid) &&
3112 !sid_check_is_builtin(&info->sid))
3113 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3116 for (i=0; i<q_u->num_sids1; i++) {
3118 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3121 * if there is an error, we just continue as
3122 * it can be an unfound user or group
3124 if (!NT_STATUS_IS_OK(r_u->status)) {
3125 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3129 if (tmp_num_groups==0) {
3130 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3134 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3135 if (new_rids==NULL) {
3136 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3137 return NT_STATUS_NO_MEMORY;
3141 for (j=0; j<tmp_num_groups; j++)
3142 rids[j+num_groups]=tmp_rids[j];
3144 safe_free(tmp_rids);
3146 num_groups+=tmp_num_groups;
3149 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3150 return NT_STATUS_OK;
3153 /*********************************************************************
3154 _samr_query_aliasmem
3155 *********************************************************************/
3157 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3169 fstring alias_sid_str;
3172 SAM_ACCOUNT *sam_user = NULL;
3176 /* find the policy handle. open a policy on it. */
3177 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3178 return NT_STATUS_INVALID_HANDLE;
3180 if (!NT_STATUS_IS_OK(r_u->status =
3181 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3185 sid_copy(&als_sid, &alias_sid);
3186 sid_to_string(alias_sid_str, &alias_sid);
3187 sid_split_rid(&alias_sid, &alias_rid);
3189 DEBUG(10, ("sid is %s\n", alias_sid_str));
3191 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
3192 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3193 if(!get_builtin_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
3194 return NT_STATUS_NO_SUCH_ALIAS;
3196 if (sid_equal(&alias_sid, get_global_sam_sid())) {
3197 DEBUG(10, ("lookup on Server SID\n"));
3198 if(!get_local_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
3199 return NT_STATUS_NO_SUCH_ALIAS;
3203 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3204 return NT_STATUS_NO_SUCH_ALIAS;
3206 DEBUG(10, ("sid is %s\n", alias_sid_str));
3207 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
3208 if (num_uids!=0 && sid == NULL)
3209 return NT_STATUS_NO_MEMORY;
3211 for (i = 0; i < num_uids; i++) {
3212 struct passwd *pass;
3215 sid_copy(&temp_sid, get_global_sam_sid());
3217 pass = getpwuid_alloc(uid[i]);
3218 if (!pass) continue;
3220 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3226 check = pdb_getsampwnam(sam_user, pass->pw_name);
3229 if (check != True) {
3230 pdb_free_sam(&sam_user);
3235 rid = pdb_get_user_rid(sam_user);
3237 pdb_free_sam(&sam_user);
3242 pdb_free_sam(&sam_user);
3245 sid_append_rid(&temp_sid, rid);
3247 init_dom_sid2(&sid[i], &temp_sid);
3250 DEBUG(10, ("sid is %s\n", alias_sid_str));
3251 init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
3253 return NT_STATUS_OK;
3256 /*********************************************************************
3257 _samr_query_groupmem
3258 *********************************************************************/
3260 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3266 fstring group_sid_str;
3274 SAM_ACCOUNT *sam_user = NULL;
3278 /* find the policy handle. open a policy on it. */
3279 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3280 return NT_STATUS_INVALID_HANDLE;
3282 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3286 /* todo: change to use sid_compare_front */
3288 sid_split_rid(&group_sid, &group_rid);
3289 sid_to_string(group_sid_str, &group_sid);
3290 DEBUG(10, ("sid is %s\n", group_sid_str));
3292 /* can we get a query for an SID outside our domain ? */
3293 if (!sid_equal(&group_sid, get_global_sam_sid()))
3294 return NT_STATUS_NO_SUCH_GROUP;
3296 sid_append_rid(&group_sid, group_rid);
3297 DEBUG(10, ("lookup on Domain SID\n"));
3299 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3300 return NT_STATUS_NO_SUCH_GROUP;
3302 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3303 return NT_STATUS_NO_SUCH_GROUP;
3305 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3306 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3308 if (num_uids!=0 && (rid==NULL || attr==NULL))
3309 return NT_STATUS_NO_MEMORY;
3311 for (i=0; i<num_uids; i++) {
3312 struct passwd *pass;
3315 pass = getpwuid_alloc(uid[i]);
3316 if (!pass) continue;
3318 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3324 check = pdb_getsampwnam(sam_user, pass->pw_name);
3327 if (check != True) {
3328 pdb_free_sam(&sam_user);
3333 urid = pdb_get_user_rid(sam_user);
3335 pdb_free_sam(&sam_user);
3340 pdb_free_sam(&sam_user);
3344 attr[i] = SID_NAME_USER;
3347 init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
3349 return NT_STATUS_OK;
3352 /*********************************************************************
3354 *********************************************************************/
3356 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3359 fstring alias_sid_str;
3366 SAM_ACCOUNT *sam_user = NULL;
3370 /* Find the policy handle. Open a policy on it. */
3371 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3372 return NT_STATUS_INVALID_HANDLE;
3374 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3378 sid_to_string(alias_sid_str, &alias_sid);
3379 DEBUG(10, ("sid is %s\n", alias_sid_str));
3381 if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
3382 DEBUG(10, ("adding member on Server SID\n"));
3383 if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3384 return NT_STATUS_NO_SUCH_ALIAS;
3387 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
3388 DEBUG(10, ("adding member on BUILTIN SID\n"));
3389 if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3390 return NT_STATUS_NO_SUCH_ALIAS;
3393 return NT_STATUS_NO_SUCH_ALIAS;
3396 ret = pdb_init_sam(&sam_user);
3397 if (!NT_STATUS_IS_OK(ret))
3400 check = pdb_getsampwsid(sam_user, &q_u->sid.sid);
3402 if (check != True) {
3403 pdb_free_sam(&sam_user);
3404 return NT_STATUS_NO_SUCH_USER;
3407 uid = pdb_get_uid(sam_user);
3409 pdb_free_sam(&sam_user);
3410 return NT_STATUS_NO_SUCH_USER;
3413 pdb_free_sam(&sam_user);
3415 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3416 return NT_STATUS_NO_SUCH_USER;
3419 if ((grp=getgrgid(map.gid)) == NULL) {
3421 return NT_STATUS_NO_SUCH_ALIAS;
3424 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3425 fstrcpy(grp_name, grp->gr_name);
3427 /* if the user is already in the group */
3428 if(user_in_group_list(pwd->pw_name, grp_name)) {
3430 return NT_STATUS_MEMBER_IN_ALIAS;
3434 * ok, the group exist, the user exist, the user is not in the group,
3435 * we can (finally) add it to the group !
3437 smb_add_user_group(grp_name, pwd->pw_name);
3439 /* check if the user has been added then ... */
3440 if(!user_in_group_list(pwd->pw_name, grp_name)) {
3442 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3446 return NT_STATUS_OK;
3449 /*********************************************************************
3451 *********************************************************************/
3453 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3456 fstring alias_sid_str;
3460 SAM_ACCOUNT *sam_pass=NULL;
3463 /* Find the policy handle. Open a policy on it. */
3464 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3465 return NT_STATUS_INVALID_HANDLE;
3467 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3471 sid_to_string(alias_sid_str, &alias_sid);
3472 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
3474 if (!sid_check_is_in_our_domain(&alias_sid) &&
3475 !sid_check_is_in_builtin(&alias_sid)) {
3476 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3477 return NT_STATUS_NO_SUCH_ALIAS;
3480 if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3481 return NT_STATUS_NO_SUCH_ALIAS;
3483 if ((grp=getgrgid(map.gid)) == NULL)
3484 return NT_STATUS_NO_SUCH_ALIAS;
3486 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3487 fstrcpy(grp_name, grp->gr_name);
3489 /* check if the user exists before trying to remove it from the group */
3490 pdb_init_sam(&sam_pass);
3491 if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
3492 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3493 pdb_free_sam(&sam_pass);
3494 return NT_STATUS_NO_SUCH_USER;
3497 /* if the user is not in the group */
3498 if(!user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
3499 pdb_free_sam(&sam_pass);
3500 return NT_STATUS_MEMBER_IN_ALIAS;
3503 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3505 /* check if the user has been removed then ... */
3506 if(user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
3507 pdb_free_sam(&sam_pass);
3508 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3511 pdb_free_sam(&sam_pass);
3512 return NT_STATUS_OK;
3515 /*********************************************************************
3517 *********************************************************************/
3519 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3523 fstring group_sid_str;
3530 SAM_ACCOUNT *sam_user=NULL;
3534 /* Find the policy handle. Open a policy on it. */
3535 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3536 return NT_STATUS_INVALID_HANDLE;
3538 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3542 sid_to_string(group_sid_str, &group_sid);
3543 DEBUG(10, ("sid is %s\n", group_sid_str));
3545 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3546 return NT_STATUS_NO_SUCH_GROUP;
3548 DEBUG(10, ("lookup on Domain SID\n"));
3550 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3551 return NT_STATUS_NO_SUCH_GROUP;
3553 sid_copy(&user_sid, get_global_sam_sid());
3554 sid_append_rid(&user_sid, q_u->rid);
3556 ret = pdb_init_sam(&sam_user);
3557 if (!NT_STATUS_IS_OK(ret))
3560 check = pdb_getsampwsid(sam_user, &user_sid);
3562 if (check != True) {
3563 pdb_free_sam(&sam_user);
3564 return NT_STATUS_NO_SUCH_USER;
3567 uid = pdb_get_uid(sam_user);
3569 pdb_free_sam(&sam_user);
3570 return NT_STATUS_NO_SUCH_USER;
3573 pdb_free_sam(&sam_user);
3575 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3576 return NT_STATUS_NO_SUCH_USER;
3579 if ((grp=getgrgid(map.gid)) == NULL) {
3581 return NT_STATUS_NO_SUCH_GROUP;
3584 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3585 fstrcpy(grp_name, grp->gr_name);
3587 /* if the user is already in the group */
3588 if(user_in_group_list(pwd->pw_name, grp_name)) {
3590 return NT_STATUS_MEMBER_IN_GROUP;
3594 * ok, the group exist, the user exist, the user is not in the group,
3596 * we can (finally) add it to the group !
3599 smb_add_user_group(grp_name, pwd->pw_name);
3601 /* check if the user has been added then ... */
3602 if(!user_in_group_list(pwd->pw_name, grp_name)) {
3604 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3608 return NT_STATUS_OK;
3611 /*********************************************************************
3613 *********************************************************************/
3615 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3619 SAM_ACCOUNT *sam_pass=NULL;
3626 * delete the group member named q_u->rid
3627 * who is a member of the sid associated with the handle
3628 * the rid is a user's rid as the group is a domain group.
3631 /* Find the policy handle. Open a policy on it. */
3632 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3633 return NT_STATUS_INVALID_HANDLE;
3635 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3639 if (!sid_check_is_in_our_domain(&group_sid))
3640 return NT_STATUS_NO_SUCH_GROUP;
3642 sid_copy(&user_sid, get_global_sam_sid());
3643 sid_append_rid(&user_sid, q_u->rid);
3645 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3646 return NT_STATUS_NO_SUCH_GROUP;
3648 if ((grp=getgrgid(map.gid)) == NULL)
3649 return NT_STATUS_NO_SUCH_GROUP;
3651 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3652 fstrcpy(grp_name, grp->gr_name);
3654 /* check if the user exists before trying to remove it from the group */
3655 pdb_init_sam(&sam_pass);
3656 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3657 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3658 pdb_free_sam(&sam_pass);
3659 return NT_STATUS_NO_SUCH_USER;
3662 /* if the user is not in the group */
3663 if (!user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
3664 pdb_free_sam(&sam_pass);
3665 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3668 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3670 /* check if the user has been removed then ... */
3671 if (user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
3672 pdb_free_sam(&sam_pass);
3673 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3676 pdb_free_sam(&sam_pass);
3677 return NT_STATUS_OK;
3681 /****************************************************************************
3682 Delete a UNIX user on demand.
3683 ****************************************************************************/
3685 static int smb_delete_user(const char *unix_user)
3690 pstrcpy(del_script, lp_deluser_script());
3693 all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3694 ret = smbrun(del_script,NULL);
3695 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3699 /*********************************************************************
3700 _samr_delete_dom_user
3701 *********************************************************************/
3703 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3706 SAM_ACCOUNT *sam_pass=NULL;
3709 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3711 /* Find the policy handle. Open a policy on it. */
3712 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3713 return NT_STATUS_INVALID_HANDLE;
3715 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3719 if (!sid_check_is_in_our_domain(&user_sid))
3720 return NT_STATUS_CANNOT_DELETE;
3722 /* check if the user exists before trying to delete */
3723 pdb_init_sam(&sam_pass);
3724 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3725 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3726 pdb_free_sam(&sam_pass);
3727 return NT_STATUS_NO_SUCH_USER;
3730 /* delete the unix side */
3732 * note: we don't check if the delete really happened
3733 * as the script is not necessary present
3734 * and maybe the sysadmin doesn't want to delete the unix side
3736 smb_delete_user(pdb_get_username(sam_pass));
3738 /* and delete the samba side */
3739 if (!pdb_delete_sam_account(sam_pass)) {
3740 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3741 pdb_free_sam(&sam_pass);
3742 return NT_STATUS_CANNOT_DELETE;
3745 pdb_free_sam(&sam_pass);
3747 if (!close_policy_hnd(p, &q_u->user_pol))
3748 return NT_STATUS_OBJECT_NAME_INVALID;
3750 return NT_STATUS_OK;
3753 /*********************************************************************
3754 _samr_delete_dom_group
3755 *********************************************************************/
3757 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3762 fstring group_sid_str;
3768 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3770 /* Find the policy handle. Open a policy on it. */
3771 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3772 return NT_STATUS_INVALID_HANDLE;
3774 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3778 sid_copy(&dom_sid, &group_sid);
3779 sid_to_string(group_sid_str, &dom_sid);
3780 sid_split_rid(&dom_sid, &group_rid);
3782 DEBUG(10, ("sid is %s\n", group_sid_str));
3784 /* we check if it's our SID before deleting */
3785 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3786 return NT_STATUS_NO_SUCH_GROUP;
3788 DEBUG(10, ("lookup on Domain SID\n"));
3790 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3791 return NT_STATUS_NO_SUCH_GROUP;
3795 /* check if group really exists */
3796 if ( (grp=getgrgid(gid)) == NULL)
3797 return NT_STATUS_NO_SUCH_GROUP;
3799 /* we can delete the UNIX group */
3800 smb_delete_group(grp->gr_name);
3802 /* check if the group has been successfully deleted */
3803 if ( (grp=getgrgid(gid)) != NULL)
3804 return NT_STATUS_ACCESS_DENIED;
3806 if(!pdb_delete_group_mapping_entry(group_sid))
3807 return NT_STATUS_ACCESS_DENIED;
3809 if (!close_policy_hnd(p, &q_u->group_pol))
3810 return NT_STATUS_OBJECT_NAME_INVALID;
3812 return NT_STATUS_OK;
3815 /*********************************************************************
3816 _samr_delete_dom_alias
3817 *********************************************************************/
3819 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3824 fstring alias_sid_str;
3830 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3832 /* Find the policy handle. Open a policy on it. */
3833 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3834 return NT_STATUS_INVALID_HANDLE;
3836 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3840 sid_copy(&dom_sid, &alias_sid);
3841 sid_to_string(alias_sid_str, &dom_sid);
3842 sid_split_rid(&dom_sid, &alias_rid);
3844 DEBUG(10, ("sid is %s\n", alias_sid_str));
3846 /* we check if it's our SID before deleting */
3847 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3848 return NT_STATUS_NO_SUCH_ALIAS;
3850 DEBUG(10, ("lookup on Local SID\n"));
3852 if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3853 return NT_STATUS_NO_SUCH_ALIAS;
3857 /* check if group really exists */
3858 if ( (grp=getgrgid(gid)) == NULL)
3859 return NT_STATUS_NO_SUCH_ALIAS;
3861 /* we can delete the UNIX group */
3862 smb_delete_group(grp->gr_name);
3864 /* check if the group has been successfully deleted */
3865 if ( (grp=getgrgid(gid)) != NULL)
3866 return NT_STATUS_ACCESS_DENIED;
3868 /* don't check if we removed it as it could be an un-mapped group */
3869 pdb_delete_group_mapping_entry(alias_sid);
3871 if (!close_policy_hnd(p, &q_u->alias_pol))
3872 return NT_STATUS_OBJECT_NAME_INVALID;
3874 return NT_STATUS_OK;
3877 /*********************************************************************
3878 _samr_create_dom_group
3879 *********************************************************************/
3881 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3888 struct samr_info *info;
3889 PRIVILEGE_SET priv_set;
3893 init_privilege(&priv_set);
3895 /* Find the policy handle. Open a policy on it. */
3896 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3897 return NT_STATUS_INVALID_HANDLE;
3899 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3903 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3904 return NT_STATUS_ACCESS_DENIED;
3906 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3908 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3910 /* check if group already exist */
3911 if ((grp=getgrnam(name)) != NULL)
3912 return NT_STATUS_GROUP_EXISTS;
3914 /* we can create the UNIX group */
3915 if (smb_create_group(name, &gid) != 0)
3916 return NT_STATUS_ACCESS_DENIED;
3918 /* check if the group has been successfully created */
3919 if ((grp=getgrgid(gid)) == NULL)
3920 return NT_STATUS_ACCESS_DENIED;
3922 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3924 /* add the group to the mapping table */
3925 sid_copy(&info_sid, get_global_sam_sid());
3926 sid_append_rid(&info_sid, r_u->rid);
3927 sid_to_string(sid_string, &info_sid);
3929 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
3930 return NT_STATUS_ACCESS_DENIED;
3932 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3933 return NT_STATUS_NO_MEMORY;
3935 /* get a (unique) handle. open a policy on it. */
3936 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3937 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3939 return NT_STATUS_OK;
3942 /*********************************************************************
3943 _samr_create_dom_alias
3944 *********************************************************************/
3946 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3953 struct samr_info *info;
3954 PRIVILEGE_SET priv_set;
3958 init_privilege(&priv_set);
3960 /* Find the policy handle. Open a policy on it. */
3961 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
3962 return NT_STATUS_INVALID_HANDLE;
3964 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3968 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3969 return NT_STATUS_ACCESS_DENIED;
3971 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3973 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3975 /* check if group already exists */
3976 if ( (grp=getgrnam(name)) != NULL)
3977 return NT_STATUS_GROUP_EXISTS;
3979 /* we can create the UNIX group */
3980 if (smb_create_group(name, &gid) != 0)
3981 return NT_STATUS_ACCESS_DENIED;
3983 /* check if the group has been successfully created */
3984 if ((grp=getgrgid(gid)) == NULL)
3985 return NT_STATUS_ACCESS_DENIED;
3987 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3989 sid_copy(&info_sid, get_global_sam_sid());
3990 sid_append_rid(&info_sid, r_u->rid);
3991 sid_to_string(sid_string, &info_sid);
3993 /* add the group to the mapping table */
3994 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
3995 return NT_STATUS_ACCESS_DENIED;
3997 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3998 return NT_STATUS_NO_MEMORY;
4000 /* get a (unique) handle. open a policy on it. */
4001 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4002 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4004 return NT_STATUS_OK;
4007 /*********************************************************************
4008 _samr_query_groupinfo
4010 sends the name/comment pair of a domain group
4011 level 1 send also the number of users of that group
4012 *********************************************************************/
4014 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4020 GROUP_INFO_CTR *ctr;
4023 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4024 return NT_STATUS_INVALID_HANDLE;
4026 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4030 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
4031 return NT_STATUS_INVALID_HANDLE;
4033 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
4035 return NT_STATUS_NO_MEMORY;
4037 switch (q_u->switch_level) {
4039 ctr->switch_value1 = 1;
4040 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
4041 return NT_STATUS_NO_SUCH_GROUP;
4042 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
4046 ctr->switch_value1 = 3;
4047 init_samr_group_info3(&ctr->group.info3);
4050 ctr->switch_value1 = 4;
4051 init_samr_group_info4(&ctr->group.info4, map.comment);
4054 return NT_STATUS_INVALID_INFO_CLASS;
4057 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4059 return NT_STATUS_OK;
4062 /*********************************************************************
4065 update a domain group's comment.
4066 *********************************************************************/
4068 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4072 GROUP_INFO_CTR *ctr;
4075 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4076 return NT_STATUS_INVALID_HANDLE;
4078 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4082 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
4083 return NT_STATUS_NO_SUCH_GROUP;
4087 switch (ctr->switch_value1) {
4089 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4092 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4095 free_privilege(&map.priv_set);
4096 return NT_STATUS_INVALID_INFO_CLASS;
4099 if(!pdb_update_group_mapping_entry(&map)) {
4100 free_privilege(&map.priv_set);
4101 return NT_STATUS_NO_SUCH_GROUP;
4104 free_privilege(&map.priv_set);
4106 return NT_STATUS_OK;
4109 /*********************************************************************
4112 update an alias's comment.
4113 *********************************************************************/
4115 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4119 ALIAS_INFO_CTR *ctr;
4122 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4123 return NT_STATUS_INVALID_HANDLE;
4125 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4129 if (!get_local_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
4130 return NT_STATUS_NO_SUCH_GROUP;
4134 switch (ctr->switch_value1) {
4136 unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
4139 free_privilege(&map.priv_set);
4140 return NT_STATUS_INVALID_INFO_CLASS;
4143 if(!pdb_update_group_mapping_entry(&map)) {
4144 free_privilege(&map.priv_set);
4145 return NT_STATUS_NO_SUCH_GROUP;
4148 free_privilege(&map.priv_set);
4150 return NT_STATUS_OK;
4153 /*********************************************************************
4154 _samr_get_dom_pwinfo
4155 *********************************************************************/
4157 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4159 /* Perform access check. Since this rpc does not require a
4160 policy handle it will not be caught by the access checks on
4161 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4163 if (!pipe_access_check(p)) {
4164 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4165 r_u->status = NT_STATUS_ACCESS_DENIED;
4169 /* Actually, returning zeros here works quite well :-). */
4171 return NT_STATUS_OK;
4174 /*********************************************************************
4176 *********************************************************************/
4178 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4183 struct samr_info *info;
4184 SEC_DESC *psd = NULL;
4191 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4192 return NT_STATUS_INVALID_HANDLE;
4194 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4198 /*check if access can be granted as requested by client. */
4199 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4200 se_map_generic(&des_access,&grp_generic_mapping);
4201 if (!NT_STATUS_IS_OK(status =
4202 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4203 des_access, &acc_granted, "_samr_open_group"))) {
4208 /* this should not be hard-coded like this */
4209 if (!sid_equal(&sid, get_global_sam_sid()))
4210 return NT_STATUS_ACCESS_DENIED;
4212 sid_copy(&info_sid, get_global_sam_sid());
4213 sid_append_rid(&info_sid, q_u->rid_group);
4214 sid_to_string(sid_string, &info_sid);
4216 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4217 return NT_STATUS_NO_MEMORY;
4219 info->acc_granted = acc_granted;
4221 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4223 /* check if that group really exists */
4224 if (!get_domain_group_from_sid(info->sid, &map, MAPPING_WITHOUT_PRIV))
4225 return NT_STATUS_NO_SUCH_GROUP;
4227 /* get a (unique) handle. open a policy on it. */
4228 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4229 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4231 return NT_STATUS_OK;
4234 /*********************************************************************
4236 *********************************************************************/
4238 NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
4240 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
4241 return NT_STATUS_NOT_IMPLEMENTED;
4244 /*******************************************************************
4246 ********************************************************************/
4248 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4250 struct samr_info *info = NULL;
4252 uint32 min_pass_len,pass_hist,flag;
4253 time_t u_expire, u_min_age;
4254 NTTIME nt_expire, nt_min_age;
4256 time_t u_lock_duration, u_reset_time;
4257 NTTIME nt_lock_duration, nt_reset_time;
4263 uint32 num_users=0, num_groups=0, num_aliases=0;
4265 uint32 account_policy_temp;
4267 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4268 return NT_STATUS_NO_MEMORY;
4272 r_u->status = NT_STATUS_OK;
4274 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4276 /* find the policy handle. open a policy on it. */
4277 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4278 return NT_STATUS_INVALID_HANDLE;
4280 switch (q_u->switch_value) {
4282 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4283 min_pass_len = account_policy_temp;
4285 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4286 pass_hist = account_policy_temp;
4288 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4289 flag = account_policy_temp;
4291 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4292 u_expire = account_policy_temp;
4294 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4295 u_min_age = account_policy_temp;
4297 unix_to_nt_time_abs(&nt_expire, u_expire);
4298 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4300 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4301 flag, nt_expire, nt_min_age);
4305 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4307 if (!NT_STATUS_IS_OK(r_u->status)) {
4308 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4311 num_users=info->disp_info.num_user_account;
4314 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4315 if (NT_STATUS_IS_ERR(r_u->status)) {
4316 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4319 num_groups=info->disp_info.num_group_account;
4322 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4323 init_unk_info2(&ctr->info.inf2, global_myworkgroup, global_myname, (uint32) time(NULL),
4324 num_users, num_groups, num_aliases);
4327 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4328 u_logout = account_policy_temp;
4330 unix_to_nt_time_abs(&nt_logout, u_logout);
4332 init_unk_info3(&ctr->info.inf3, nt_logout);
4335 init_unk_info5(&ctr->info.inf5, global_myname);
4338 init_unk_info6(&ctr->info.inf6);
4341 init_unk_info7(&ctr->info.inf7);
4344 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4345 u_lock_duration = account_policy_temp;
4347 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4348 u_reset_time = account_policy_temp;
4350 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4351 lockout = account_policy_temp;
4353 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4354 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4356 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4359 return NT_STATUS_INVALID_INFO_CLASS;
4362 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4364 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4369 /*******************************************************************
4371 ********************************************************************/
4373 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4375 time_t u_expire, u_min_age;
4377 time_t u_lock_duration, u_reset_time;
4379 r_u->status = NT_STATUS_OK;
4381 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4383 /* find the policy handle. open a policy on it. */
4384 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4385 return NT_STATUS_INVALID_HANDLE;
4387 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4389 switch (q_u->switch_value) {
4391 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4392 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4394 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4395 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4396 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4397 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4398 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4403 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4404 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4413 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4414 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count);
4416 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4417 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4418 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4421 return NT_STATUS_INVALID_INFO_CLASS;
4424 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4426 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));