2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2002,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Anthony Liguori 2002,
11 * Copyright (C) Jim McDonough 2002.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 * This is the implementation of the SAMR code.
35 #define DBGC_CLASS DBGC_RPC_SRV
37 extern DOM_SID global_sid_Builtin;
39 extern rid_name domain_group_rids[];
40 extern rid_name domain_alias_rids[];
41 extern rid_name builtin_alias_rids[];
44 typedef struct _disp_info {
46 uint32 num_user_account;
47 DISP_USER_INFO *disp_user_info;
49 uint32 num_group_account;
50 DISP_GROUP_INFO *disp_group_info;
54 /* for use by the \PIPE\samr policy */
56 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
65 struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
66 struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
67 struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
68 struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
69 struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
71 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
73 /*******************************************************************
74 Checks if access to an object should be granted, and returns that
75 level of access for further checks.
76 ********************************************************************/
78 NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_token, uint32 des_access,
79 uint32 *acc_granted, const char *debug)
81 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
83 if (!se_access_check(psd, nt_user_token, des_access, acc_granted, &status)) {
84 if (geteuid() == sec_initial_uid()) {
85 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n",
87 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
88 status = NT_STATUS_OK;
91 DEBUG(2,("%s: ACCESS DENIED (requested: %#010x)\n",
98 /*******************************************************************
99 Checks if access to a function can be granted
100 ********************************************************************/
102 NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
104 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
105 debug, acc_granted, acc_required));
106 if ((acc_granted & acc_required) != acc_required) {
107 if (geteuid() == sec_initial_uid()) {
108 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
109 debug, acc_granted, acc_required));
110 DEBUGADD(4,("but overwritten by euid == 0\n"));
113 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
114 debug, acc_granted, acc_required));
115 return NT_STATUS_ACCESS_DENIED;
121 /*******************************************************************
122 Create a samr_info struct.
123 ********************************************************************/
125 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
127 struct samr_info *info;
132 sid_to_string(sid_str, psid);
134 fstrcpy(sid_str,"(NULL)");
137 mem_ctx = talloc_init_named("samr_info for domain sid %s", sid_str);
139 if ((info = (struct samr_info *)talloc(mem_ctx, sizeof(struct samr_info))) == NULL)
143 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
145 sid_copy( &info->sid, psid);
147 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
149 info->mem_ctx = mem_ctx;
154 /*******************************************************************
155 Function to free the per handle data.
156 ********************************************************************/
157 static void free_samr_users(struct samr_info *info)
161 if (info->disp_info.user_dbloaded){
162 for (i=0; i<info->disp_info.num_user_account; i++) {
163 /* Not really a free, actually a 'clear' */
164 pdb_free_sam(&info->disp_info.disp_user_info[i].sam);
167 info->disp_info.user_dbloaded=False;
168 info->disp_info.num_user_account=0;
172 /*******************************************************************
173 Function to free the per handle data.
174 ********************************************************************/
175 static void free_samr_db(struct samr_info *info)
177 /* Groups are talloced */
179 free_samr_users(info);
181 info->disp_info.group_dbloaded=False;
182 info->disp_info.num_group_account=0;
186 static void free_samr_info(void *ptr)
188 struct samr_info *info=(struct samr_info *) ptr;
191 talloc_destroy(info->mem_ctx);
194 /*******************************************************************
195 Ensure password info is never given out. Paranioa... JRA.
196 ********************************************************************/
198 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
204 /* These now zero out the old password */
206 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
207 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
211 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL all_machines)
213 SAM_ACCOUNT *pwd = NULL;
214 DISP_USER_INFO *pwd_array = NULL;
215 NTSTATUS nt_status = NT_STATUS_OK;
216 TALLOC_CTX *mem_ctx = info->mem_ctx;
218 DEBUG(10,("load_sampwd_entries\n"));
220 /* if the snapshoot is already loaded, return */
221 if ((info->disp_info.user_dbloaded==True)
222 && (info->acb_mask == acb_mask)
223 && (info->all_machines == all_machines)) {
224 DEBUG(10,("load_sampwd_entries: already in memory\n"));
228 free_samr_users(info);
230 if (!pdb_setsampwent(False)) {
231 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
232 return NT_STATUS_ACCESS_DENIED;
235 for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd)))
236 && pdb_getsampwent(pwd) == True; pwd=NULL) {
239 if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST)
240 || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
241 DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
246 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
248 DEBUG(5,(" acb_mask %x reject\n", acb_mask));
253 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
254 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
256 DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
257 pwd_array=(DISP_USER_INFO *)talloc_realloc(mem_ctx, info->disp_info.disp_user_info,
258 (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(DISP_USER_INFO));
261 return NT_STATUS_NO_MEMORY;
263 info->disp_info.disp_user_info=pwd_array;
266 /* link the SAM_ACCOUNT to the array */
267 info->disp_info.disp_user_info[info->disp_info.num_user_account].sam=pwd;
269 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
271 info->disp_info.num_user_account++;
276 /* the snapshoot is in memory, we're ready to enumerate fast */
278 info->acb_mask = acb_mask;
279 info->all_machines = all_machines;
280 info->disp_info.user_dbloaded=True;
282 DEBUG(10,("load_sampwd_entries: done\n"));
287 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
290 DISP_GROUP_INFO *grp_array = NULL;
291 uint32 group_entries = 0;
293 TALLOC_CTX *mem_ctx = info->mem_ctx;
295 DEBUG(10,("load_group_domain_entries\n"));
297 /* if the snapshoot is already loaded, return */
298 if (info->disp_info.group_dbloaded==True) {
299 DEBUG(10,("load_group_domain_entries: already in memory\n"));
303 if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV)) {
304 DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
305 return NT_STATUS_NO_MEMORY;
308 info->disp_info.num_group_account=group_entries;
310 grp_array=(DISP_GROUP_INFO *)talloc(mem_ctx, info->disp_info.num_group_account*sizeof(DISP_GROUP_INFO));
312 if (group_entries!=0 && grp_array==NULL) {
313 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
315 return NT_STATUS_NO_MEMORY;
318 info->disp_info.disp_group_info=grp_array;
320 for (i=0; i<group_entries; i++) {
322 grp_array[i].grp=(DOMAIN_GRP *)talloc(mem_ctx, sizeof(DOMAIN_GRP));
324 fstrcpy(grp_array[i].grp->name, map[i].nt_name);
325 fstrcpy(grp_array[i].grp->comment, map[i].comment);
326 sid_split_rid(&map[i].sid, &grp_array[i].grp->rid);
327 grp_array[i].grp->attr=SID_NAME_DOM_GRP;
332 /* the snapshoot is in memory, we're ready to enumerate fast */
334 info->disp_info.group_dbloaded=True;
336 DEBUG(10,("load_group_domain_entries: done\n"));
342 /*******************************************************************
344 ********************************************************************/
346 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
348 r_u->status = NT_STATUS_OK;
350 /* close the policy handle */
351 if (!close_policy_hnd(p, &q_u->pol))
352 return NT_STATUS_OBJECT_NAME_INVALID;
354 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
359 /*******************************************************************
360 samr_reply_open_domain
361 ********************************************************************/
363 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
365 struct samr_info *info;
366 SEC_DESC *psd = NULL;
368 uint32 des_access = q_u->flags;
372 r_u->status = NT_STATUS_OK;
374 /* find the connection policy handle. */
375 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
376 return NT_STATUS_INVALID_HANDLE;
378 if (!NT_STATUS_IS_OK(status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN,"_samr_open_domain"))) {
382 /*check if access can be granted as requested by client. */
383 samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
384 se_map_generic(&des_access,&dom_generic_mapping);
386 if (!NT_STATUS_IS_OK(status =
387 access_check_samr_object(psd, p->pipe_user.nt_user_token,
388 des_access, &acc_granted, "_samr_open_domain"))) {
392 /* associate the domain SID with the (unique) handle. */
393 if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
394 return NT_STATUS_NO_MEMORY;
395 info->acc_granted = acc_granted;
397 /* get a (unique) handle. open a policy on it. */
398 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
399 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
401 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
406 /*******************************************************************
407 _samr_get_usrdom_pwinfo
408 ********************************************************************/
410 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
412 struct samr_info *info = NULL;
414 r_u->status = NT_STATUS_OK;
416 /* find the policy handle. open a policy on it. */
417 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
418 return NT_STATUS_INVALID_HANDLE;
420 if (!sid_check_is_in_our_domain(&info->sid))
421 return NT_STATUS_OBJECT_TYPE_MISMATCH;
423 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
425 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
428 * NT sometimes return NT_STATUS_ACCESS_DENIED
429 * I don't know yet why.
435 /*******************************************************************
437 ********************************************************************/
439 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
441 extern DOM_SID global_sid_World;
450 sid_copy(&adm_sid, &global_sid_Builtin);
451 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
453 sid_copy(&act_sid, &global_sid_Builtin);
454 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
456 /*basic access for every one*/
457 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
458 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
460 /*full access for builtin aliases Administrators and Account Operators*/
461 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS);
462 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
463 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
465 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
466 return NT_STATUS_NO_MEMORY;
468 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
469 return NT_STATUS_NO_MEMORY;
474 /*******************************************************************
476 ********************************************************************/
478 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
480 extern DOM_SID global_sid_World;
489 sid_copy(&adm_sid, &global_sid_Builtin);
490 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
492 sid_copy(&act_sid, &global_sid_Builtin);
493 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
495 /*basic access for every one*/
496 init_sec_access(&mask, GENERIC_RIGHTS_USER_EXECUTE | GENERIC_RIGHTS_USER_READ);
497 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
499 /*full access for builtin aliases Administrators and Account Operators*/
500 init_sec_access(&mask, GENERIC_RIGHTS_USER_ALL_ACCESS);
501 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
502 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
504 /*extended access for the user*/
505 init_sec_access(&mask,READ_CONTROL_ACCESS | SA_RIGHT_USER_CHANGE_PASSWORD | SA_RIGHT_USER_SET_LOC_COM);
506 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
508 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
509 return NT_STATUS_NO_MEMORY;
511 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
512 return NT_STATUS_NO_MEMORY;
517 /*******************************************************************
519 ********************************************************************/
521 static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
523 extern DOM_SID global_sid_World;
532 sid_copy(&adm_sid, &global_sid_Builtin);
533 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
535 sid_copy(&act_sid, &global_sid_Builtin);
536 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
538 /*basic access for every one*/
539 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
540 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
542 /*full access for builtin aliases Administrators and Account Operators*/
543 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_ALL_ACCESS);
544 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
545 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
547 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
548 return NT_STATUS_NO_MEMORY;
550 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
551 return NT_STATUS_NO_MEMORY;
556 /*******************************************************************
558 ********************************************************************/
560 static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
562 extern DOM_SID global_sid_World;
571 sid_copy(&adm_sid, &global_sid_Builtin);
572 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
574 sid_copy(&act_sid, &global_sid_Builtin);
575 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
577 /*basic access for every one*/
578 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
579 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
581 /*full access for builtin aliases Administrators and Account Operators*/
582 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_ALL_ACCESS);
583 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
584 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
586 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
587 return NT_STATUS_NO_MEMORY;
589 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
590 return NT_STATUS_NO_MEMORY;
595 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
597 struct samr_info *info = NULL;
599 /* find the policy handle. open a policy on it. */
600 if (!find_policy_by_hnd(p, pol, (void **)&info))
607 *acc_granted = info->acc_granted;
611 /*******************************************************************
613 ********************************************************************/
615 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
617 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
618 return NT_STATUS_NOT_IMPLEMENTED;
622 /*******************************************************************
624 ********************************************************************/
626 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
630 SEC_DESC * psd = NULL;
634 r_u->status = NT_STATUS_OK;
637 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
638 return NT_STATUS_INVALID_HANDLE;
642 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
644 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
646 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
647 if (pol_sid.sid_rev_num == 0)
649 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
650 r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
652 else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */
655 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
656 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
658 else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */
660 /* TODO: Builtin probably needs a different SD with restricted write access*/
661 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
662 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
664 else if (sid_check_is_in_our_domain(&pol_sid) ||
665 sid_check_is_in_builtin(&pol_sid))
667 /* TODO: different SDs have to be generated for aliases groups and users.
668 Currently all three get a default user SD */
669 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
670 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
672 else return NT_STATUS_OBJECT_TYPE_MISMATCH;
674 if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
675 return NT_STATUS_NO_MEMORY;
677 if (NT_STATUS_IS_OK(r_u->status))
683 /*******************************************************************
684 makes a SAM_ENTRY / UNISTR2* structure from a user list.
685 ********************************************************************/
687 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
688 uint32 num_entries, uint32 start_idx, DISP_USER_INFO *disp_user_info,
694 SAM_ACCOUNT *pwd = NULL;
695 UNISTR2 uni_temp_name;
696 const char *temp_name;
697 const DOM_SID *user_sid;
699 fstring user_sid_string;
700 fstring domain_sid_string;
705 if (num_entries == 0)
708 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_entries);
710 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_entries);
712 if (sam == NULL || uni_name == NULL) {
713 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
714 return NT_STATUS_NO_MEMORY;
717 for (i = 0; i < num_entries; i++) {
718 pwd = disp_user_info[i+start_idx].sam;
719 temp_name = pdb_get_username(pwd);
720 init_unistr2(&uni_temp_name, temp_name, strlen(temp_name)+1);
721 user_sid = pdb_get_user_sid(pwd);
723 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
724 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
725 "the domain sid %s. Failing operation.\n",
727 sid_to_string(user_sid_string, user_sid),
728 sid_to_string(domain_sid_string, domain_sid)));
729 return NT_STATUS_UNSUCCESSFUL;
732 init_sam_entry(&sam[i], uni_temp_name.uni_str_len, user_rid);
733 copy_unistr2(&uni_name[i], &uni_temp_name);
737 *uni_name_pp = uni_name;
741 /*******************************************************************
742 samr_reply_enum_dom_users
743 ********************************************************************/
745 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
746 SAMR_R_ENUM_DOM_USERS *r_u)
748 struct samr_info *info = NULL;
749 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
751 uint32 enum_context=q_u->start_idx;
752 uint32 max_size=q_u->max_size;
754 enum remote_arch_types ra_type = get_remote_arch();
755 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
756 uint32 max_entries = max_sam_entries;
759 r_u->status = NT_STATUS_OK;
761 /* find the policy handle. open a policy on it. */
762 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
763 return NT_STATUS_INVALID_HANDLE;
765 domain_sid = info->sid;
767 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
768 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
769 "_samr_enum_dom_users"))) {
773 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
776 r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
779 if (!NT_STATUS_IS_OK(r_u->status))
782 num_account = info->disp_info.num_user_account;
784 if (enum_context > num_account) {
785 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
789 /* verify we won't overflow */
790 if (max_entries > num_account-enum_context) {
791 max_entries = num_account-enum_context;
792 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
795 /* calculate the size and limit on the number of entries we will return */
796 temp_size=max_entries*struct_size;
798 if (temp_size>max_size) {
799 max_entries=MIN((max_size/struct_size),max_entries);;
800 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
804 * Note from JRA. total_entries is not being used here. Currently if there is a
805 * large user base then it looks like NT will enumerate until get_sampwd_entries
806 * returns False due to num_entries being zero. This will cause an access denied
807 * return. I don't think this is right and needs further investigation. Note that
808 * this is also the same in the TNG code (I don't think that has been tested with
809 * a very large user list as MAX_SAM_ENTRIES is set to 600).
811 * I also think that one of the 'num_entries' return parameters is probably
812 * the "max entries" parameter - but in the TNG code they're all currently set to the same
813 * value (again I think this is wrong).
816 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
817 max_entries, enum_context,
818 info->disp_info.disp_user_info,
821 if (!NT_STATUS_IS_OK(r_u->status))
824 if (enum_context+max_entries < num_account)
825 r_u->status = STATUS_MORE_ENTRIES;
827 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
829 init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
831 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
836 /*******************************************************************
837 makes a SAM_ENTRY / UNISTR2* structure from a group list.
838 ********************************************************************/
840 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
841 uint32 num_sam_entries, DOMAIN_GRP *grp)
850 if (num_sam_entries == 0)
853 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
855 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
857 if (sam == NULL || uni_name == NULL) {
858 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
862 for (i = 0; i < num_sam_entries; i++) {
864 * JRA. I think this should include the null. TNG does not.
866 int len = strlen(grp[i].name)+1;
868 init_sam_entry(&sam[i], len, grp[i].rid);
869 init_unistr2(&uni_name[i], grp[i].name, len);
873 *uni_name_pp = uni_name;
876 /*******************************************************************
877 Get the group entries - similar to get_sampwd_entries().
878 ********************************************************************/
880 static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
881 uint32 *p_num_entries, uint32 max_entries)
884 uint32 num_entries = 0;
887 GROUP_MAP *map = NULL;
889 sid_to_string(sid_str, sid);
890 DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str));
894 /* well-known aliases */
895 if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
897 pdb_enum_group_mapping(SID_NAME_WKN_GRP, &map, (int *)&num_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
899 if (num_entries != 0) {
900 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
902 return NT_STATUS_NO_MEMORY;
904 for(i=0; i<num_entries && i<max_entries; i++) {
905 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
906 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
912 } else if (sid_equal(sid, get_global_sam_sid()) && !lp_hide_local_users()) {
913 struct sys_grent *glist;
914 struct sys_grent *grp;
916 gid_t winbind_gid_low, winbind_gid_high;
917 BOOL winbind_groups_exist = lp_winbind_gid(&winbind_gid_low, &winbind_gid_high);
920 /* we return the UNIX groups here. This seems to be the right */
921 /* thing to do, since NT member servers return their local */
922 /* groups in the same situation. */
924 /* use getgrent_list() to retrieve the list of groups to avoid
925 * problems with getgrent possible infinite loop by internal
926 * libc grent structures overwrites by called functions */
927 grp = glist = getgrent_list();
929 return NT_STATUS_NO_MEMORY;
931 for (; (num_entries < max_entries) && (grp != NULL); grp = grp->next) {
934 if(!pdb_getgrgid(&smap, grp->gr_gid, MAPPING_WITHOUT_PRIV))
937 if (smap.sid_name_use!=SID_NAME_ALIAS) {
941 sid_split_rid(&smap.sid, &trid);
943 if (!sid_equal(sid, &smap.sid))
946 /* Don't return winbind groups as they are not local! */
947 if (winbind_groups_exist && (grp->gr_gid >= winbind_gid_low)&&(grp->gr_gid <= winbind_gid_high)) {
948 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
952 /* Don't return user private groups... */
954 if ((pw = Get_Pwnam(smap.nt_name)) != 0) {
955 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
959 for( i = 0; i < num_entries; i++)
960 if ( (*d_grp)[i].rid == trid )
963 if ( i < num_entries ) {
964 continue; /* rid was there, dup! */
967 /* JRA - added this for large group db enumeration... */
970 /* skip the requested number of entries.
971 not very efficient, but hey...
977 *d_grp=talloc_realloc(ctx,*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
980 return NT_STATUS_NO_MEMORY;
983 fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
984 (*d_grp)[num_entries].rid = trid;
986 DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries, trid));
992 *p_num_entries = num_entries;
994 DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries));
996 if (num_entries >= max_entries)
997 return STATUS_MORE_ENTRIES;
1001 /*******************************************************************
1002 Get the group entries - similar to get_sampwd_entries().
1003 ********************************************************************/
1005 static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
1006 uint32 *p_num_entries, uint32 max_entries)
1008 GROUP_MAP *map=NULL;
1010 uint32 group_entries = 0;
1011 uint32 num_entries = 0;
1015 pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
1017 num_entries=group_entries-start_idx;
1019 /* limit the number of entries */
1020 if (num_entries>max_entries) {
1021 DEBUG(5,("Limiting to %d entries\n", max_entries));
1022 num_entries=max_entries;
1025 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
1026 if (num_entries!=0 && *d_grp==NULL){
1028 return NT_STATUS_NO_MEMORY;
1031 for (i=0; i<num_entries; i++) {
1032 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
1033 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
1034 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
1035 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
1040 *p_num_entries = num_entries;
1042 return NT_STATUS_OK;
1045 /*******************************************************************
1046 samr_reply_enum_dom_groups
1047 ********************************************************************/
1049 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
1051 DOMAIN_GRP *grp=NULL;
1056 r_u->status = NT_STATUS_OK;
1058 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1059 return NT_STATUS_INVALID_HANDLE;
1061 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
1065 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1067 /* the domain group array is being allocated in the function below */
1068 if (!NT_STATUS_IS_OK(r_u->status = get_group_domain_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES))) {
1072 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1074 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
1076 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1082 /*******************************************************************
1083 samr_reply_enum_dom_aliases
1084 ********************************************************************/
1086 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1088 DOMAIN_GRP *grp=NULL;
1089 uint32 num_entries = 0;
1095 r_u->status = NT_STATUS_OK;
1097 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1098 return NT_STATUS_INVALID_HANDLE;
1100 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1104 sid_to_string(sid_str, &sid);
1105 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1107 status = get_group_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1108 &num_entries, MAX_SAM_ENTRIES);
1109 if (NT_STATUS_IS_ERR(status)) return status;
1111 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1115 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1117 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1122 /*******************************************************************
1123 samr_reply_query_dispinfo
1124 ********************************************************************/
1125 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1126 SAMR_R_QUERY_DISPINFO *r_u)
1128 struct samr_info *info = NULL;
1129 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1131 uint32 max_entries=q_u->max_entries;
1132 uint32 enum_context=q_u->start_idx;
1133 uint32 max_size=q_u->max_size;
1135 SAM_DISPINFO_CTR *ctr;
1136 uint32 temp_size=0, total_data_size=0;
1138 uint32 num_account = 0;
1139 enum remote_arch_types ra_type = get_remote_arch();
1140 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1143 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1144 r_u->status = NT_STATUS_OK;
1146 /* find the policy handle. open a policy on it. */
1147 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1148 return NT_STATUS_INVALID_HANDLE;
1150 domain_sid = info->sid;
1153 * calculate how many entries we will return.
1155 * - the number of entries the client asked
1156 * - our limit on that
1157 * - the starting point (enumeration context)
1158 * - the buffer size the client will accept
1162 * We are a lot more like W2K. Instead of reading the SAM
1163 * each time to find the records we need to send back,
1164 * we read it once and link that copy to the sam handle.
1165 * For large user list (over the MAX_SAM_ENTRIES)
1166 * it's a definitive win.
1167 * second point to notice: between enumerations
1168 * our sam is now the same as it's a snapshoot.
1169 * third point: got rid of the static SAM_USER_21 struct
1170 * no more intermediate.
1171 * con: it uses much more memory, as a full copy is stored
1174 * If you want to change it, think twice and think
1175 * of the second point , that's really important.
1180 /* Get what we need from the password database */
1181 switch (q_u->switch_level) {
1183 /* When playing with usrmgr, this is necessary
1184 if you want immediate refresh after editing
1185 a user. I would like to do this after the
1186 setuserinfo2, but we do not have access to
1187 the domain handle in that call, only to the
1188 user handle. Where else does this hurt?
1192 /* We cannot do this here - it kills performace. JRA. */
1193 free_samr_users(info);
1198 /* Level 2 is for all machines, otherwise only 'normal' users */
1199 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1201 if (!NT_STATUS_IS_OK(r_u->status)) {
1202 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1205 num_account = info->disp_info.num_user_account;
1209 r_u->status = load_group_domain_entries(info, &info->sid);
1210 if (!NT_STATUS_IS_OK(r_u->status))
1212 num_account = info->disp_info.num_group_account;
1215 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1216 return NT_STATUS_INVALID_INFO_CLASS;
1219 /* first limit the number of entries we will return */
1220 if(max_entries > max_sam_entries) {
1221 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1222 max_entries = max_sam_entries;
1225 if (enum_context > num_account) {
1226 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1227 return NT_STATUS_NO_MORE_ENTRIES;
1230 /* verify we won't overflow */
1231 if (max_entries > num_account-enum_context) {
1232 max_entries = num_account-enum_context;
1233 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1236 /* calculate the size and limit on the number of entries we will return */
1237 temp_size=max_entries*struct_size;
1239 if (temp_size>max_size) {
1240 max_entries=MIN((max_size/struct_size),max_entries);;
1241 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1244 if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1245 return NT_STATUS_NO_MEMORY;
1249 /* Now create reply structure */
1250 switch (q_u->switch_level) {
1253 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
1254 return NT_STATUS_NO_MEMORY;
1256 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1257 info->disp_info.disp_user_info, &domain_sid);
1258 if (!NT_STATUS_IS_OK(disp_ret))
1263 if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1264 return NT_STATUS_NO_MEMORY;
1266 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1267 info->disp_info.disp_user_info, &domain_sid);
1268 if (!NT_STATUS_IS_OK(disp_ret))
1273 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1274 return NT_STATUS_NO_MEMORY;
1276 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1277 if (!NT_STATUS_IS_OK(disp_ret))
1282 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1283 return NT_STATUS_NO_MEMORY;
1285 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1286 if (!NT_STATUS_IS_OK(disp_ret))
1291 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1292 return NT_STATUS_NO_MEMORY;
1294 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1295 if (!NT_STATUS_IS_OK(disp_ret))
1300 ctr->sam.info = NULL;
1301 return NT_STATUS_INVALID_INFO_CLASS;
1304 /* calculate the total size */
1305 total_data_size=num_account*struct_size;
1307 if (enum_context+max_entries < num_account)
1308 r_u->status = STATUS_MORE_ENTRIES;
1310 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1312 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1318 /*******************************************************************
1319 samr_reply_query_aliasinfo
1320 ********************************************************************/
1322 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1328 r_u->status = NT_STATUS_OK;
1330 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1332 /* find the policy handle. open a policy on it. */
1333 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1334 return NT_STATUS_INVALID_HANDLE;
1335 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1339 if (!sid_check_is_in_our_domain(&sid) &&
1340 !sid_check_is_in_builtin(&sid))
1341 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1343 if (!pdb_getgrsid(&map, sid, MAPPING_WITHOUT_PRIV))
1344 return NT_STATUS_NO_SUCH_ALIAS;
1346 switch (q_u->switch_level) {
1349 r_u->ctr.switch_value1 = 1;
1350 init_samr_alias_info1(&r_u->ctr.alias.info1, map.nt_name, 1, map.comment);
1354 r_u->ctr.switch_value1 = 3;
1355 init_samr_alias_info3(&r_u->ctr.alias.info3, map.comment);
1358 return NT_STATUS_INVALID_INFO_CLASS;
1361 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1367 /*******************************************************************
1368 samr_reply_lookup_ids
1369 ********************************************************************/
1371 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1373 uint32 rid[MAX_SAM_ENTRIES];
1374 int num_rids = q_u->num_sids1;
1376 r_u->status = NT_STATUS_OK;
1378 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1380 if (num_rids > MAX_SAM_ENTRIES) {
1381 num_rids = MAX_SAM_ENTRIES;
1382 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1387 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1389 for (i = 0; i < num_rids && status == 0; i++)
1391 struct sam_passwd *sam_pass;
1395 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1396 q_u->uni_user_name[i].uni_str_len));
1398 /* find the user account */
1400 sam_pass = get_smb21pwd_entry(user_name, 0);
1403 if (sam_pass == NULL)
1405 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1410 rid[i] = sam_pass->user_rid;
1416 rid[0] = BUILTIN_ALIAS_RID_USERS;
1418 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1420 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1426 /*******************************************************************
1428 ********************************************************************/
1430 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1432 uint32 rid[MAX_SAM_ENTRIES];
1434 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1435 enum SID_NAME_USE local_type;
1437 int num_rids = q_u->num_names2;
1442 r_u->status = NT_STATUS_OK;
1444 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1449 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1450 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1454 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, 0, "_samr_lookup_names"))) { /* Don't know the acc_bits yet */
1458 if (num_rids > MAX_SAM_ENTRIES) {
1459 num_rids = MAX_SAM_ENTRIES;
1460 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1463 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1465 become_root(); /* local_lookup_name can require root privs */
1467 for (i = 0; i < num_rids; i++) {
1471 r_u->status = NT_STATUS_NONE_MAPPED;
1473 rid [i] = 0xffffffff;
1474 type[i] = SID_NAME_UNKNOWN;
1476 rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1479 * we are only looking for a name
1480 * the SID we get back can be outside
1481 * the scope of the pol_sid
1483 * in clear: it prevents to reply to domain\group: yes
1484 * when only builtin\group exists.
1486 * a cleaner code is to add the sid of the domain we're looking in
1487 * to the local_lookup_name function.
1489 if(local_lookup_name(name, &sid, &local_type)) {
1490 sid_split_rid(&sid, &local_rid);
1492 if (sid_equal(&sid, &pol_sid)) {
1495 r_u->status = NT_STATUS_OK;
1502 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1504 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1509 /*******************************************************************
1510 _samr_chgpasswd_user
1511 ********************************************************************/
1513 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1518 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1520 r_u->status = NT_STATUS_OK;
1522 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1523 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1525 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1528 * Pass the user through the NT -> unix user mapping
1532 (void)map_username(user_name);
1535 * UNIX username case mangling not required, pass_oem_change
1536 * is case insensitive.
1539 if (!pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1540 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1541 r_u->status = NT_STATUS_WRONG_PASSWORD;
1543 init_samr_r_chgpasswd_user(r_u, r_u->status);
1545 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1550 /*******************************************************************
1551 makes a SAMR_R_LOOKUP_RIDS structure.
1552 ********************************************************************/
1554 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1555 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1558 UNIHDR *hdr_name=NULL;
1559 UNISTR2 *uni_name=NULL;
1561 *pp_uni_name = NULL;
1562 *pp_hdr_name = NULL;
1564 if (num_names != 0) {
1565 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1566 if (hdr_name == NULL)
1569 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1570 if (uni_name == NULL)
1574 for (i = 0; i < num_names; i++) {
1575 int len = names[i] != NULL ? strlen(names[i]) : 0;
1576 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1577 init_uni_hdr(&hdr_name[i], len);
1578 init_unistr2(&uni_name[i], names[i], len);
1581 *pp_uni_name = uni_name;
1582 *pp_hdr_name = hdr_name;
1587 /*******************************************************************
1589 ********************************************************************/
1591 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1593 fstring group_names[MAX_SAM_ENTRIES];
1594 uint32 *group_attrs = NULL;
1595 UNIHDR *hdr_name = NULL;
1596 UNISTR2 *uni_name = NULL;
1598 int num_rids = q_u->num_rids1;
1602 r_u->status = NT_STATUS_OK;
1604 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1606 /* find the policy handle. open a policy on it. */
1607 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1608 return NT_STATUS_INVALID_HANDLE;
1610 if (num_rids > MAX_SAM_ENTRIES) {
1611 num_rids = MAX_SAM_ENTRIES;
1612 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1616 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1617 return NT_STATUS_NO_MEMORY;
1620 r_u->status = NT_STATUS_NONE_MAPPED;
1622 become_root(); /* lookup_sid can require root privs */
1624 for (i = 0; i < num_rids; i++) {
1628 enum SID_NAME_USE type;
1630 group_attrs[i] = SID_NAME_UNKNOWN;
1631 *group_names[i] = '\0';
1633 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1634 sid_copy(&sid, &pol_sid);
1635 sid_append_rid(&sid, q_u->rid[i]);
1637 if (lookup_sid(&sid, domname, tmpname, &type)) {
1638 r_u->status = NT_STATUS_OK;
1639 group_attrs[i] = (uint32)type;
1640 fstrcpy(group_names[i],tmpname);
1641 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1648 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1649 return NT_STATUS_NO_MEMORY;
1651 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1653 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1658 /*******************************************************************
1659 _api_samr_open_user. Safe - gives out no passwd info.
1660 ********************************************************************/
1662 NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1664 SAM_ACCOUNT *sampass=NULL;
1666 POLICY_HND domain_pol = q_u->domain_pol;
1667 POLICY_HND *user_pol = &r_u->user_pol;
1668 struct samr_info *info = NULL;
1669 SEC_DESC *psd = NULL;
1671 uint32 des_access = q_u->access_mask;
1676 r_u->status = NT_STATUS_OK;
1678 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1679 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1680 return NT_STATUS_INVALID_HANDLE;
1682 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1686 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1687 if (!NT_STATUS_IS_OK(nt_status)) {
1691 /* append the user's RID to it */
1692 if (!sid_append_rid(&sid, q_u->user_rid))
1693 return NT_STATUS_NO_SUCH_USER;
1695 /* check if access can be granted as requested by client. */
1696 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1697 se_map_generic(&des_access, &usr_generic_mapping);
1698 if (!NT_STATUS_IS_OK(nt_status =
1699 access_check_samr_object(psd, p->pipe_user.nt_user_token,
1700 des_access, &acc_granted, "_samr_open_user"))) {
1705 ret=pdb_getsampwsid(sampass, &sid);
1708 /* check that the SID exists in our domain. */
1710 return NT_STATUS_NO_SUCH_USER;
1713 pdb_free_sam(&sampass);
1715 /* associate the user's SID and access bits with the new handle. */
1716 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1717 return NT_STATUS_NO_MEMORY;
1718 info->acc_granted = acc_granted;
1720 /* get a (unique) handle. open a policy on it. */
1721 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1722 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1727 /*************************************************************************
1728 get_user_info_10. Safe. Only gives out acb bits.
1729 *************************************************************************/
1731 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1733 SAM_ACCOUNT *smbpass=NULL;
1737 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1739 if (!NT_STATUS_IS_OK(nt_status)) {
1744 ret = pdb_getsampwsid(smbpass, user_sid);
1748 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1749 return NT_STATUS_NO_SUCH_USER;
1752 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1755 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1757 pdb_free_sam(&smbpass);
1759 return NT_STATUS_OK;
1762 /*************************************************************************
1763 get_user_info_12. OK - this is the killer as it gives out password info.
1764 Ensure that this is only allowed on an encrypted connection with a root
1766 *************************************************************************/
1768 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1770 SAM_ACCOUNT *smbpass=NULL;
1774 if (!p->ntlmssp_auth_validated)
1775 return NT_STATUS_ACCESS_DENIED;
1777 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1778 return NT_STATUS_ACCESS_DENIED;
1781 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1784 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1786 if (!NT_STATUS_IS_OK(nt_status)) {
1790 ret = pdb_getsampwsid(smbpass, user_sid);
1793 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1794 pdb_free_sam(&smbpass);
1795 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1798 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1800 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1801 pdb_free_sam(&smbpass);
1802 return NT_STATUS_ACCOUNT_DISABLED;
1806 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1808 pdb_free_sam(&smbpass);
1810 return NT_STATUS_OK;
1813 /*************************************************************************
1815 *************************************************************************/
1817 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1819 SAM_ACCOUNT *sampass=NULL;
1822 pdb_init_sam_talloc(mem_ctx, &sampass);
1825 ret = pdb_getsampwsid(sampass, user_sid);
1829 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1830 return NT_STATUS_NO_SUCH_USER;
1833 samr_clear_sam_passwd(sampass);
1835 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1838 init_sam_user_info20A(id20, sampass);
1840 pdb_free_sam(&sampass);
1842 return NT_STATUS_OK;
1845 /*************************************************************************
1847 *************************************************************************/
1849 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1850 DOM_SID *user_sid, DOM_SID *domain_sid)
1852 SAM_ACCOUNT *sampass=NULL;
1856 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1857 if (!NT_STATUS_IS_OK(nt_status)) {
1862 ret = pdb_getsampwsid(sampass, user_sid);
1866 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1867 return NT_STATUS_NO_SUCH_USER;
1870 samr_clear_sam_passwd(sampass);
1872 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1875 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1877 pdb_free_sam(&sampass);
1879 return NT_STATUS_OK;
1882 /*******************************************************************
1883 _samr_query_userinfo
1884 ********************************************************************/
1886 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1888 SAM_USERINFO_CTR *ctr;
1889 struct samr_info *info = NULL;
1893 r_u->status=NT_STATUS_OK;
1895 /* search for the handle */
1896 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1897 return NT_STATUS_INVALID_HANDLE;
1899 domain_sid = info->sid;
1901 sid_split_rid(&domain_sid, &rid);
1903 if (!sid_check_is_in_our_domain(&info->sid))
1904 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1906 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1908 ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1910 return NT_STATUS_NO_MEMORY;
1914 /* ok! user info levels (lots: see MSDEV help), off we go... */
1915 ctr->switch_value = q_u->switch_value;
1917 switch (q_u->switch_value) {
1919 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1920 if (ctr->info.id10 == NULL)
1921 return NT_STATUS_NO_MEMORY;
1923 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1928 /* whoops - got this wrong. i think. or don't understand what's happening. */
1932 info = (void *)&id11;
1934 expire.low = 0xffffffff;
1935 expire.high = 0x7fffffff;
1937 ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1942 ZERO_STRUCTP(ctr->info.id11);
1943 init_sam_user_info11(ctr->info.id11, &expire,
1944 "BROOKFIELDS$", /* name */
1945 0x03ef, /* user rid */
1946 0x201, /* group rid */
1947 0x0080); /* acb info */
1954 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1955 if (ctr->info.id12 == NULL)
1956 return NT_STATUS_NO_MEMORY;
1958 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1963 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1964 if (ctr->info.id20 == NULL)
1965 return NT_STATUS_NO_MEMORY;
1966 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1971 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1972 if (ctr->info.id21 == NULL)
1973 return NT_STATUS_NO_MEMORY;
1974 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1975 &info->sid, &domain_sid)))
1980 return NT_STATUS_INVALID_INFO_CLASS;
1983 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1985 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1990 /*******************************************************************
1991 samr_reply_query_usergroups
1992 ********************************************************************/
1994 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1996 SAM_ACCOUNT *sam_pass=NULL;
1998 DOM_GID *gids = NULL;
2004 * from the SID in the request:
2005 * we should send back the list of DOMAIN GROUPS
2006 * the user is a member of
2008 * and only the DOMAIN GROUPS
2009 * no ALIASES !!! neither aliases of the domain
2010 * nor aliases of the builtin SID
2015 r_u->status = NT_STATUS_OK;
2017 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2019 /* find the policy handle. open a policy on it. */
2020 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
2021 return NT_STATUS_INVALID_HANDLE;
2023 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
2027 if (!sid_check_is_in_our_domain(&sid))
2028 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2030 pdb_init_sam(&sam_pass);
2033 ret = pdb_getsampwsid(sam_pass, &sid);
2037 pdb_free_sam(&sam_pass);
2038 return NT_STATUS_NO_SUCH_USER;
2041 if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
2042 pdb_free_sam(&sam_pass);
2043 return NT_STATUS_NO_SUCH_GROUP;
2046 /* construct the response. lkclXXXX: gids are not copied! */
2047 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
2049 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2051 pdb_free_sam(&sam_pass);
2056 /*******************************************************************
2057 _samr_query_dom_info
2058 ********************************************************************/
2060 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2062 struct samr_info *info = NULL;
2064 uint32 min_pass_len,pass_hist,flag;
2065 time_t u_expire, u_min_age;
2066 NTTIME nt_expire, nt_min_age;
2068 time_t u_lock_duration, u_reset_time;
2069 NTTIME nt_lock_duration, nt_reset_time;
2075 uint32 account_policy_temp;
2077 uint32 num_users=0, num_groups=0, num_aliases=0;
2079 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
2080 return NT_STATUS_NO_MEMORY;
2084 r_u->status = NT_STATUS_OK;
2086 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2088 /* find the policy handle. open a policy on it. */
2089 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2090 return NT_STATUS_INVALID_HANDLE;
2092 switch (q_u->switch_value) {
2095 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2096 min_pass_len = account_policy_temp;
2098 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2099 pass_hist = account_policy_temp;
2101 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2102 flag = account_policy_temp;
2104 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2105 u_expire = account_policy_temp;
2107 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2108 u_min_age = account_policy_temp;
2110 unix_to_nt_time_abs(&nt_expire, u_expire);
2111 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2113 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2114 flag, nt_expire, nt_min_age);
2118 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2120 if (!NT_STATUS_IS_OK(r_u->status)) {
2121 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2124 num_users=info->disp_info.num_user_account;
2127 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2128 if (!NT_STATUS_IS_OK(r_u->status)) {
2129 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2132 num_groups=info->disp_info.num_group_account;
2135 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2136 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
2137 num_users, num_groups, num_aliases);
2140 account_policy_get(AP_TIME_TO_LOGOUT, (int *)&u_logout);
2141 unix_to_nt_time_abs(&nt_logout, u_logout);
2143 init_unk_info3(&ctr->info.inf3, nt_logout);
2146 init_unk_info5(&ctr->info.inf5, global_myname());
2149 init_unk_info6(&ctr->info.inf6);
2152 init_unk_info7(&ctr->info.inf7);
2155 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2156 u_lock_duration = account_policy_temp;
2158 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2159 u_reset_time = account_policy_temp;
2161 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2162 lockout = account_policy_temp;
2164 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2165 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2167 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2170 return NT_STATUS_INVALID_INFO_CLASS;
2173 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2175 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2180 /*******************************************************************
2181 _api_samr_create_user
2182 Create an account, can be either a normal user or a machine.
2183 This funcion will need to be updated for bdc/domain trusts.
2184 ********************************************************************/
2186 NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2188 SAM_ACCOUNT *sam_pass=NULL;
2192 POLICY_HND dom_pol = q_u->domain_pol;
2193 UNISTR2 user_account = q_u->uni_name;
2194 uint16 acb_info = q_u->acb_info;
2195 POLICY_HND *user_pol = &r_u->user_pol;
2196 struct samr_info *info = NULL;
2205 /* Get the domain SID stored in the domain policy */
2206 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2207 return NT_STATUS_INVALID_HANDLE;
2209 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2213 /* find the account: tell the caller if it exists.
2214 lkclXXXX i have *no* idea if this is a problem or not
2215 or even if you are supposed to construct a different
2216 reply if the account already exists...
2219 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2222 pdb_init_sam(&sam_pass);
2225 ret = pdb_getsampwnam(sam_pass, account);
2228 /* this account exists: say so */
2229 pdb_free_sam(&sam_pass);
2230 return NT_STATUS_USER_EXISTS;
2233 pdb_free_sam(&sam_pass);
2236 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2237 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2238 * that only people with write access to the smbpasswd file will be able
2239 * to create a user. JRA.
2243 * add the user in the /etc/passwd file or the unix authority system.
2244 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2245 * a) local_password_change() checks for us if the /etc/passwd account really exists
2246 * b) smb_create_user() would return an error if the account already exists
2247 * and as it could return an error also if it can't create the account, it would be tricky.
2249 * So we go the easy way, only check after if the account exists.
2250 * JFM (2/3/2001), to clear any possible bad understanding (-:
2252 * We now have seperate script paramaters for adding users/machines so we
2253 * now have some sainity-checking to match.
2256 DEBUG(10,("checking account %s at pos %d for $ termination\n",account, strlen(account)-1));
2258 if ((acb_info & ACB_WSTRUST) && (account[strlen(account)-1] == '$')) {
2259 pstrcpy(add_script, lp_addmachine_script());
2260 } else if ((!(acb_info & ACB_WSTRUST)) && (account[strlen(account)-1] != '$')) {
2261 pstrcpy(add_script, lp_adduser_script());
2263 DEBUG(0, ("_api_samr_create_user: mismatch between trust flags and $ termination\n"));
2264 pdb_free_sam(&sam_pass);
2265 return NT_STATUS_UNSUCCESSFUL;
2270 * we can't check both the ending $ and the acb_info.
2272 * UserManager creates trust accounts (ending in $,
2273 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2276 if (account[strlen(account)-1] == '$')
2277 pstrcpy(add_script, lp_addmachine_script());
2279 pstrcpy(add_script, lp_adduser_script());
2283 all_string_sub(add_script, "%u", account, sizeof(account));
2284 add_ret = smbrun(add_script,NULL);
2285 DEBUG(3,("_api_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2288 pw = getpwnam_alloc(account);
2291 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sam_pass, pw))) {
2295 passwd_free(&pw); /* done with this now */
2297 DEBUG(3,("attempting to create non-unix account %s\n", account));
2299 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sam_pass))) {
2303 if (!pdb_set_username(sam_pass, account, PDB_CHANGED)) {
2304 pdb_free_sam(&sam_pass);
2305 return NT_STATUS_NO_MEMORY;
2309 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2311 if (!pdb_add_sam_account(sam_pass)) {
2312 pdb_free_sam(&sam_pass);
2313 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2315 return NT_STATUS_ACCESS_DENIED;
2318 pdb_reset_sam(sam_pass);
2320 if (!pdb_getsampwnam(sam_pass, account)) {
2321 pdb_free_sam(&sam_pass);
2322 DEBUG(0, ("could not find user/computer %s just added to passdb?!?\n",
2324 return NT_STATUS_ACCESS_DENIED;
2327 /* Get the user's SID */
2328 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2330 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2331 se_map_generic(&des_access, &usr_generic_mapping);
2332 if (!NT_STATUS_IS_OK(nt_status =
2333 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2334 des_access, &acc_granted, "_samr_create_user"))) {
2338 /* associate the user's SID with the new handle. */
2339 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2340 pdb_free_sam(&sam_pass);
2341 return NT_STATUS_NO_MEMORY;
2346 info->acc_granted = acc_granted;
2348 /* get a (unique) handle. open a policy on it. */
2349 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2350 pdb_free_sam(&sam_pass);
2351 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2354 r_u->user_rid=pdb_get_user_rid(sam_pass);
2356 r_u->access_granted = acc_granted;
2358 pdb_free_sam(&sam_pass);
2360 return NT_STATUS_OK;
2363 /*******************************************************************
2364 samr_reply_connect_anon
2365 ********************************************************************/
2367 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2369 struct samr_info *info = NULL;
2373 if (!pipe_access_check(p)) {
2374 DEBUG(3, ("access denied to samr_connect_anon\n"));
2375 r_u->status = NT_STATUS_ACCESS_DENIED;
2379 /* set up the SAMR connect_anon response */
2381 r_u->status = NT_STATUS_OK;
2383 /* associate the user's SID with the new handle. */
2384 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2385 return NT_STATUS_NO_MEMORY;
2387 info->status = q_u->unknown_0;
2389 /* get a (unique) handle. open a policy on it. */
2390 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2391 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2396 /*******************************************************************
2398 ********************************************************************/
2400 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2402 struct samr_info *info = NULL;
2403 SEC_DESC *psd = NULL;
2405 uint32 des_access = q_u->access_mask;
2410 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2414 if (!pipe_access_check(p)) {
2415 DEBUG(3, ("access denied to samr_connect\n"));
2416 r_u->status = NT_STATUS_ACCESS_DENIED;
2420 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2421 se_map_generic(&des_access, &sam_generic_mapping);
2422 if (!NT_STATUS_IS_OK(nt_status =
2423 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2424 des_access, &acc_granted, "_samr_connect"))) {
2428 r_u->status = NT_STATUS_OK;
2430 /* associate the user's SID and access granted with the new handle. */
2431 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2432 return NT_STATUS_NO_MEMORY;
2434 info->acc_granted = acc_granted;
2435 info->status = q_u->access_mask;
2437 /* get a (unique) handle. open a policy on it. */
2438 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2439 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2441 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2446 /*******************************************************************
2448 ********************************************************************/
2450 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2452 struct samr_info *info = NULL;
2453 SEC_DESC *psd = NULL;
2455 uint32 des_access = q_u->access_mask;
2460 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2464 if (!pipe_access_check(p)) {
2465 DEBUG(3, ("access denied to samr_connect4\n"));
2466 r_u->status = NT_STATUS_ACCESS_DENIED;
2470 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2471 se_map_generic(&des_access, &sam_generic_mapping);
2472 if (!NT_STATUS_IS_OK(nt_status =
2473 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2474 des_access, &acc_granted, "_samr_connect"))) {
2478 r_u->status = NT_STATUS_OK;
2480 /* associate the user's SID and access granted with the new handle. */
2481 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2482 return NT_STATUS_NO_MEMORY;
2484 info->acc_granted = acc_granted;
2485 info->status = q_u->access_mask;
2487 /* get a (unique) handle. open a policy on it. */
2488 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2489 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2491 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2496 /**********************************************************************
2497 api_samr_lookup_domain
2498 **********************************************************************/
2500 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2502 struct samr_info *info;
2503 fstring domain_name;
2506 r_u->status = NT_STATUS_OK;
2508 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2509 return NT_STATUS_INVALID_HANDLE;
2511 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain"))) {
2515 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2519 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2520 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2523 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2525 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2530 /******************************************************************
2531 makes a SAMR_R_ENUM_DOMAINS structure.
2532 ********************************************************************/
2534 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2535 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2541 DEBUG(5, ("make_enum_domains\n"));
2544 *pp_uni_name = NULL;
2546 if (num_sam_entries == 0)
2549 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2550 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2552 if (sam == NULL || uni_name == NULL)
2555 for (i = 0; i < num_sam_entries; i++) {
2556 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
2558 init_sam_entry(&sam[i], len, 0);
2559 init_unistr2(&uni_name[i], doms[i], len);
2563 *pp_uni_name = uni_name;
2568 /**********************************************************************
2569 api_samr_enum_domains
2570 **********************************************************************/
2572 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2574 struct samr_info *info;
2575 uint32 num_entries = 2;
2579 r_u->status = NT_STATUS_OK;
2581 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2582 return NT_STATUS_INVALID_HANDLE;
2584 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2588 switch (lp_server_role()) {
2589 case ROLE_DOMAIN_PDC:
2590 case ROLE_DOMAIN_BDC:
2591 name = lp_workgroup();
2594 name = global_myname();
2597 fstrcpy(dom[0],name);
2599 fstrcpy(dom[1],"Builtin");
2601 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2602 return NT_STATUS_NO_MEMORY;
2604 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2609 /*******************************************************************
2611 ********************************************************************/
2613 NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2616 POLICY_HND domain_pol = q_u->dom_pol;
2617 uint32 alias_rid = q_u->rid_alias;
2618 POLICY_HND *alias_pol = &r_u->pol;
2619 struct samr_info *info = NULL;
2620 SEC_DESC *psd = NULL;
2622 uint32 des_access = q_u->access_mask;
2626 r_u->status = NT_STATUS_OK;
2628 /* find the domain policy and get the SID / access bits stored in the domain policy */
2629 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2630 return NT_STATUS_INVALID_HANDLE;
2632 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2636 /* append the alias' RID to it */
2637 if (!sid_append_rid(&sid, alias_rid))
2638 return NT_STATUS_NO_SUCH_USER;
2640 /*check if access can be granted as requested by client. */
2641 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2642 se_map_generic(&des_access,&ali_generic_mapping);
2643 if (!NT_STATUS_IS_OK(status =
2644 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2645 des_access, &acc_granted, "_samr_open_alias"))) {
2650 * we should check if the rid really exist !!!
2654 /* associate the user's SID with the new handle. */
2655 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2656 return NT_STATUS_NO_MEMORY;
2658 info->acc_granted = acc_granted;
2660 /* get a (unique) handle. open a policy on it. */
2661 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2662 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2667 /*******************************************************************
2669 ********************************************************************/
2671 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2673 SAM_ACCOUNT *pwd =NULL;
2678 ret = pdb_getsampwsid(pwd, sid);
2686 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2691 /* FIX ME: check if the value is really changed --metze */
2692 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2697 if(!pdb_update_sam_account(pwd)) {
2707 /*******************************************************************
2709 ********************************************************************/
2711 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2713 SAM_ACCOUNT *pwd = NULL;
2717 if(!pdb_getsampwsid(pwd, sid)) {
2723 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2728 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2732 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2736 if (!pdb_set_pass_changed_now (pwd)) {
2741 if(!pdb_update_sam_account(pwd)) {
2750 /*******************************************************************
2752 ********************************************************************/
2754 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2756 SAM_ACCOUNT *pwd = NULL;
2759 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2765 if (!pdb_getsampwsid(pwd, sid)) {
2770 copy_id21_to_sam_passwd(pwd, id21);
2773 * The funny part about the previous two calls is
2774 * that pwd still has the password hashes from the
2775 * passdb entry. These have not been updated from
2776 * id21. I don't know if they need to be set. --jerry
2779 /* write the change out */
2780 if(!pdb_update_sam_account(pwd)) {
2790 /*******************************************************************
2792 ********************************************************************/
2794 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2796 SAM_ACCOUNT *pwd = NULL;
2797 pstring plaintext_buf;
2802 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2808 if (!pdb_getsampwsid(pwd, sid)) {
2813 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2814 pdb_get_username(pwd)));
2816 acct_ctrl = pdb_get_acct_ctrl(pwd);
2818 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
2823 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2828 copy_id23_to_sam_passwd(pwd, id23);
2830 /* if it's a trust account, don't update /etc/passwd */
2831 if ( (!IS_SAM_UNIX_USER(pwd)) ||
2832 ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2833 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2834 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2835 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2837 /* update the UNIX password */
2838 if (lp_unix_password_sync() )
2839 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2845 ZERO_STRUCT(plaintext_buf);
2847 if(!pdb_update_sam_account(pwd)) {
2857 /*******************************************************************
2859 ********************************************************************/
2861 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2863 SAM_ACCOUNT *pwd = NULL;
2865 pstring plaintext_buf;
2870 if (!pdb_getsampwsid(pwd, sid)) {
2875 DEBUG(5, ("Attempting administrator password change for user %s\n",
2876 pdb_get_username(pwd)));
2878 acct_ctrl = pdb_get_acct_ctrl(pwd);
2880 ZERO_STRUCT(plaintext_buf);
2882 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) {
2887 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2892 /* if it's a trust account, don't update /etc/passwd */
2893 if ( (!IS_SAM_UNIX_USER(pwd)) ||
2894 ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2895 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2896 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2897 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2899 /* update the UNIX password */
2900 if (lp_unix_password_sync()) {
2901 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2908 ZERO_STRUCT(plaintext_buf);
2910 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2912 /* update the SAMBA password */
2913 if(!pdb_update_sam_account(pwd)) {
2923 /*******************************************************************
2924 samr_reply_set_userinfo
2925 ********************************************************************/
2927 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2930 POLICY_HND *pol = &q_u->pol;
2931 uint16 switch_value = q_u->switch_value;
2932 SAM_USERINFO_CTR *ctr = q_u->ctr;
2934 uint32 acc_required;
2936 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2938 r_u->status = NT_STATUS_OK;
2940 /* find the policy handle. open a policy on it. */
2941 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2942 return NT_STATUS_INVALID_HANDLE;
2944 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
2945 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2949 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
2952 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2953 return NT_STATUS_INVALID_INFO_CLASS;
2956 /* ok! user info levels (lots: see MSDEV help), off we go... */
2957 switch (switch_value) {
2959 if (!set_user_info_12(ctr->info.id12, &sid))
2960 return NT_STATUS_ACCESS_DENIED;
2964 SamOEMhash(ctr->info.id24->pass, p->session_key, 516);
2966 dump_data(100, (char *)ctr->info.id24->pass, 516);
2968 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
2969 return NT_STATUS_ACCESS_DENIED;
2975 * Currently we don't really know how to unmarshall
2976 * the level 25 struct, and the password encryption
2977 * is different. This is a placeholder for when we
2978 * do understand it. In the meantime just return INVALID
2979 * info level and W2K SP2 drops down to level 23... JRA.
2982 SamOEMhash(ctr->info.id25->pass, p->session_key, 532);
2984 dump_data(100, (char *)ctr->info.id25->pass, 532);
2986 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
2987 return NT_STATUS_ACCESS_DENIED;
2990 return NT_STATUS_INVALID_INFO_CLASS;
2993 SamOEMhash(ctr->info.id23->pass, p->session_key, 516);
2995 dump_data(100, (char *)ctr->info.id23->pass, 516);
2997 if (!set_user_info_23(ctr->info.id23, &sid))
2998 return NT_STATUS_ACCESS_DENIED;
3002 return NT_STATUS_INVALID_INFO_CLASS;
3008 /*******************************************************************
3009 samr_reply_set_userinfo2
3010 ********************************************************************/
3012 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3015 SAM_USERINFO_CTR *ctr = q_u->ctr;
3016 POLICY_HND *pol = &q_u->pol;
3017 uint16 switch_value = q_u->switch_value;
3019 uint32 acc_required;
3021 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3023 r_u->status = NT_STATUS_OK;
3025 /* find the policy handle. open a policy on it. */
3026 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3027 return NT_STATUS_INVALID_HANDLE;
3029 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3030 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3034 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3037 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3038 return NT_STATUS_INVALID_INFO_CLASS;
3041 switch_value=ctr->switch_value;
3043 /* ok! user info levels (lots: see MSDEV help), off we go... */
3044 switch (switch_value) {
3046 if (!set_user_info_21(ctr->info.id21, &sid))
3047 return NT_STATUS_ACCESS_DENIED;
3050 if (!set_user_info_10(ctr->info.id10, &sid))
3051 return NT_STATUS_ACCESS_DENIED;
3054 /* Used by AS/U JRA. */
3055 if (!set_user_info_12(ctr->info.id12, &sid))
3056 return NT_STATUS_ACCESS_DENIED;
3059 return NT_STATUS_INVALID_INFO_CLASS;
3065 /*********************************************************************
3066 _samr_query_aliasmem
3067 *********************************************************************/
3069 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3071 int num_groups = 0, tmp_num_groups=0;
3072 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3073 struct samr_info *info = NULL;
3079 /* until i see a real useraliases query, we fack one up */
3081 /* I have seen one, JFM 2/12/2001 */
3083 * Explanation of what this call does:
3084 * for all the SID given in the request:
3085 * return a list of alias (local groups)
3086 * that have those SID as members.
3088 * and that's the alias in the domain specified
3089 * in the policy_handle
3091 * if the policy handle is on an incorrect sid
3092 * for example a user's sid
3093 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3096 r_u->status = NT_STATUS_OK;
3098 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3100 /* find the policy handle. open a policy on it. */
3101 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3102 return NT_STATUS_INVALID_HANDLE;
3104 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3105 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3107 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3108 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3109 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3110 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3114 if (!sid_check_is_domain(&info->sid) &&
3115 !sid_check_is_builtin(&info->sid))
3116 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3119 for (i=0; i<q_u->num_sids1; i++) {
3121 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3124 * if there is an error, we just continue as
3125 * it can be an unfound user or group
3127 if (!NT_STATUS_IS_OK(r_u->status)) {
3128 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3132 if (tmp_num_groups==0) {
3133 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3137 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3138 if (new_rids==NULL) {
3139 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3140 return NT_STATUS_NO_MEMORY;
3144 for (j=0; j<tmp_num_groups; j++)
3145 rids[j+num_groups]=tmp_rids[j];
3147 safe_free(tmp_rids);
3149 num_groups+=tmp_num_groups;
3152 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3153 return NT_STATUS_OK;
3156 /*********************************************************************
3157 _samr_query_aliasmem
3158 *********************************************************************/
3160 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3172 fstring alias_sid_str;
3175 SAM_ACCOUNT *sam_user = NULL;
3179 /* find the policy handle. open a policy on it. */
3180 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3181 return NT_STATUS_INVALID_HANDLE;
3183 if (!NT_STATUS_IS_OK(r_u->status =
3184 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3188 sid_copy(&als_sid, &alias_sid);
3189 sid_to_string(alias_sid_str, &alias_sid);
3190 sid_split_rid(&alias_sid, &alias_rid);
3192 DEBUG(10, ("sid is %s\n", alias_sid_str));
3194 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
3195 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3196 if(!get_builtin_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
3197 return NT_STATUS_NO_SUCH_ALIAS;
3199 if (sid_equal(&alias_sid, get_global_sam_sid())) {
3200 DEBUG(10, ("lookup on Server SID\n"));
3201 if(!get_local_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
3202 return NT_STATUS_NO_SUCH_ALIAS;
3206 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3207 return NT_STATUS_NO_SUCH_ALIAS;
3209 DEBUG(10, ("sid is %s\n", alias_sid_str));
3210 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
3211 if (num_uids!=0 && sid == NULL)
3212 return NT_STATUS_NO_MEMORY;
3214 for (i = 0; i < num_uids; i++) {
3215 struct passwd *pass;
3218 sid_copy(&temp_sid, get_global_sam_sid());
3220 pass = getpwuid_alloc(uid[i]);
3221 if (!pass) continue;
3223 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3229 check = pdb_getsampwnam(sam_user, pass->pw_name);
3232 if (check != True) {
3233 pdb_free_sam(&sam_user);
3238 rid = pdb_get_user_rid(sam_user);
3240 pdb_free_sam(&sam_user);
3245 pdb_free_sam(&sam_user);
3248 sid_append_rid(&temp_sid, rid);
3250 init_dom_sid2(&sid[i], &temp_sid);
3253 DEBUG(10, ("sid is %s\n", alias_sid_str));
3254 init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
3256 return NT_STATUS_OK;
3259 /*********************************************************************
3260 _samr_query_groupmem
3261 *********************************************************************/
3263 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3269 fstring group_sid_str;
3277 SAM_ACCOUNT *sam_user = NULL;
3281 /* find the policy handle. open a policy on it. */
3282 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3283 return NT_STATUS_INVALID_HANDLE;
3285 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3289 /* todo: change to use sid_compare_front */
3291 sid_split_rid(&group_sid, &group_rid);
3292 sid_to_string(group_sid_str, &group_sid);
3293 DEBUG(10, ("sid is %s\n", group_sid_str));
3295 /* can we get a query for an SID outside our domain ? */
3296 if (!sid_equal(&group_sid, get_global_sam_sid()))
3297 return NT_STATUS_NO_SUCH_GROUP;
3299 sid_append_rid(&group_sid, group_rid);
3300 DEBUG(10, ("lookup on Domain SID\n"));
3302 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3303 return NT_STATUS_NO_SUCH_GROUP;
3305 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3306 return NT_STATUS_NO_SUCH_GROUP;
3308 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3309 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3311 if (num_uids!=0 && (rid==NULL || attr==NULL))
3312 return NT_STATUS_NO_MEMORY;
3314 for (i=0; i<num_uids; i++) {
3315 struct passwd *pass;
3318 pass = getpwuid_alloc(uid[i]);
3319 if (!pass) continue;
3321 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3327 check = pdb_getsampwnam(sam_user, pass->pw_name);
3330 if (check != True) {
3331 pdb_free_sam(&sam_user);
3336 urid = pdb_get_user_rid(sam_user);
3338 pdb_free_sam(&sam_user);
3343 pdb_free_sam(&sam_user);
3347 attr[i] = SID_NAME_USER;
3350 init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
3352 return NT_STATUS_OK;
3355 /*********************************************************************
3357 *********************************************************************/
3359 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3362 fstring alias_sid_str;
3369 SAM_ACCOUNT *sam_user = NULL;
3373 /* Find the policy handle. Open a policy on it. */
3374 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3375 return NT_STATUS_INVALID_HANDLE;
3377 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3381 sid_to_string(alias_sid_str, &alias_sid);
3382 DEBUG(10, ("sid is %s\n", alias_sid_str));
3384 if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
3385 DEBUG(10, ("adding member on Server SID\n"));
3386 if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3387 return NT_STATUS_NO_SUCH_ALIAS;
3390 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
3391 DEBUG(10, ("adding member on BUILTIN SID\n"));
3392 if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3393 return NT_STATUS_NO_SUCH_ALIAS;
3396 return NT_STATUS_NO_SUCH_ALIAS;
3399 ret = pdb_init_sam(&sam_user);
3400 if (!NT_STATUS_IS_OK(ret))
3403 check = pdb_getsampwsid(sam_user, &q_u->sid.sid);
3405 if (check != True) {
3406 pdb_free_sam(&sam_user);
3407 return NT_STATUS_NO_SUCH_USER;
3410 uid = pdb_get_uid(sam_user);
3412 pdb_free_sam(&sam_user);
3413 return NT_STATUS_NO_SUCH_USER;
3416 pdb_free_sam(&sam_user);
3418 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3419 return NT_STATUS_NO_SUCH_USER;
3422 if ((grp=getgrgid(map.gid)) == NULL) {
3424 return NT_STATUS_NO_SUCH_ALIAS;
3427 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3428 fstrcpy(grp_name, grp->gr_name);
3430 /* if the user is already in the group */
3431 if(user_in_group_list(pwd->pw_name, grp_name)) {
3433 return NT_STATUS_MEMBER_IN_ALIAS;
3437 * ok, the group exist, the user exist, the user is not in the group,
3438 * we can (finally) add it to the group !
3440 smb_add_user_group(grp_name, pwd->pw_name);
3442 /* check if the user has been added then ... */
3443 if(!user_in_group_list(pwd->pw_name, grp_name)) {
3445 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3449 return NT_STATUS_OK;
3452 /*********************************************************************
3454 *********************************************************************/
3456 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3459 fstring alias_sid_str;
3463 SAM_ACCOUNT *sam_pass=NULL;
3466 /* Find the policy handle. Open a policy on it. */
3467 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3468 return NT_STATUS_INVALID_HANDLE;
3470 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3474 sid_to_string(alias_sid_str, &alias_sid);
3475 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
3477 if (!sid_check_is_in_our_domain(&alias_sid) &&
3478 !sid_check_is_in_builtin(&alias_sid)) {
3479 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3480 return NT_STATUS_NO_SUCH_ALIAS;
3483 if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3484 return NT_STATUS_NO_SUCH_ALIAS;
3486 if ((grp=getgrgid(map.gid)) == NULL)
3487 return NT_STATUS_NO_SUCH_ALIAS;
3489 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3490 fstrcpy(grp_name, grp->gr_name);
3492 /* check if the user exists before trying to remove it from the group */
3493 pdb_init_sam(&sam_pass);
3494 if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
3495 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3496 pdb_free_sam(&sam_pass);
3497 return NT_STATUS_NO_SUCH_USER;
3500 /* if the user is not in the group */
3501 if(!user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
3502 pdb_free_sam(&sam_pass);
3503 return NT_STATUS_MEMBER_IN_ALIAS;
3506 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3508 /* check if the user has been removed then ... */
3509 if(user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
3510 pdb_free_sam(&sam_pass);
3511 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3514 pdb_free_sam(&sam_pass);
3515 return NT_STATUS_OK;
3518 /*********************************************************************
3520 *********************************************************************/
3522 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3526 fstring group_sid_str;
3533 SAM_ACCOUNT *sam_user=NULL;
3537 /* Find the policy handle. Open a policy on it. */
3538 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3539 return NT_STATUS_INVALID_HANDLE;
3541 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3545 sid_to_string(group_sid_str, &group_sid);
3546 DEBUG(10, ("sid is %s\n", group_sid_str));
3548 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3549 return NT_STATUS_NO_SUCH_GROUP;
3551 DEBUG(10, ("lookup on Domain SID\n"));
3553 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3554 return NT_STATUS_NO_SUCH_GROUP;
3556 sid_copy(&user_sid, get_global_sam_sid());
3557 sid_append_rid(&user_sid, q_u->rid);
3559 ret = pdb_init_sam(&sam_user);
3560 if (!NT_STATUS_IS_OK(ret))
3563 check = pdb_getsampwsid(sam_user, &user_sid);
3565 if (check != True) {
3566 pdb_free_sam(&sam_user);
3567 return NT_STATUS_NO_SUCH_USER;
3570 uid = pdb_get_uid(sam_user);
3572 pdb_free_sam(&sam_user);
3573 return NT_STATUS_NO_SUCH_USER;
3576 pdb_free_sam(&sam_user);
3578 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3579 return NT_STATUS_NO_SUCH_USER;
3582 if ((grp=getgrgid(map.gid)) == NULL) {
3584 return NT_STATUS_NO_SUCH_GROUP;
3587 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3588 fstrcpy(grp_name, grp->gr_name);
3590 /* if the user is already in the group */
3591 if(user_in_group_list(pwd->pw_name, grp_name)) {
3593 return NT_STATUS_MEMBER_IN_GROUP;
3597 * ok, the group exist, the user exist, the user is not in the group,
3599 * we can (finally) add it to the group !
3602 smb_add_user_group(grp_name, pwd->pw_name);
3604 /* check if the user has been added then ... */
3605 if(!user_in_group_list(pwd->pw_name, grp_name)) {
3607 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3611 return NT_STATUS_OK;
3614 /*********************************************************************
3616 *********************************************************************/
3618 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3622 SAM_ACCOUNT *sam_pass=NULL;
3629 * delete the group member named q_u->rid
3630 * who is a member of the sid associated with the handle
3631 * the rid is a user's rid as the group is a domain group.
3634 /* Find the policy handle. Open a policy on it. */
3635 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3636 return NT_STATUS_INVALID_HANDLE;
3638 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3642 if (!sid_check_is_in_our_domain(&group_sid))
3643 return NT_STATUS_NO_SUCH_GROUP;
3645 sid_copy(&user_sid, get_global_sam_sid());
3646 sid_append_rid(&user_sid, q_u->rid);
3648 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3649 return NT_STATUS_NO_SUCH_GROUP;
3651 if ((grp=getgrgid(map.gid)) == NULL)
3652 return NT_STATUS_NO_SUCH_GROUP;
3654 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3655 fstrcpy(grp_name, grp->gr_name);
3657 /* check if the user exists before trying to remove it from the group */
3658 pdb_init_sam(&sam_pass);
3659 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3660 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3661 pdb_free_sam(&sam_pass);
3662 return NT_STATUS_NO_SUCH_USER;
3665 /* if the user is not in the group */
3666 if (!user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
3667 pdb_free_sam(&sam_pass);
3668 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3671 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3673 /* check if the user has been removed then ... */
3674 if (user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
3675 pdb_free_sam(&sam_pass);
3676 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3679 pdb_free_sam(&sam_pass);
3680 return NT_STATUS_OK;
3684 /****************************************************************************
3685 Delete a UNIX user on demand.
3686 ****************************************************************************/
3688 static int smb_delete_user(const char *unix_user)
3693 pstrcpy(del_script, lp_deluser_script());
3696 all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3697 ret = smbrun(del_script,NULL);
3698 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3702 /*********************************************************************
3703 _samr_delete_dom_user
3704 *********************************************************************/
3706 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3709 SAM_ACCOUNT *sam_pass=NULL;
3712 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3714 /* Find the policy handle. Open a policy on it. */
3715 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3716 return NT_STATUS_INVALID_HANDLE;
3718 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3722 if (!sid_check_is_in_our_domain(&user_sid))
3723 return NT_STATUS_CANNOT_DELETE;
3725 /* check if the user exists before trying to delete */
3726 pdb_init_sam(&sam_pass);
3727 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3728 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3729 pdb_free_sam(&sam_pass);
3730 return NT_STATUS_NO_SUCH_USER;
3733 /* delete the unix side */
3735 * note: we don't check if the delete really happened
3736 * as the script is not necessary present
3737 * and maybe the sysadmin doesn't want to delete the unix side
3739 smb_delete_user(pdb_get_username(sam_pass));
3741 /* and delete the samba side */
3742 if (!pdb_delete_sam_account(sam_pass)) {
3743 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3744 pdb_free_sam(&sam_pass);
3745 return NT_STATUS_CANNOT_DELETE;
3748 pdb_free_sam(&sam_pass);
3750 if (!close_policy_hnd(p, &q_u->user_pol))
3751 return NT_STATUS_OBJECT_NAME_INVALID;
3753 return NT_STATUS_OK;
3756 /*********************************************************************
3757 _samr_delete_dom_group
3758 *********************************************************************/
3760 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3765 fstring group_sid_str;
3771 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3773 /* Find the policy handle. Open a policy on it. */
3774 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3775 return NT_STATUS_INVALID_HANDLE;
3777 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3781 sid_copy(&dom_sid, &group_sid);
3782 sid_to_string(group_sid_str, &dom_sid);
3783 sid_split_rid(&dom_sid, &group_rid);
3785 DEBUG(10, ("sid is %s\n", group_sid_str));
3787 /* we check if it's our SID before deleting */
3788 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3789 return NT_STATUS_NO_SUCH_GROUP;
3791 DEBUG(10, ("lookup on Domain SID\n"));
3793 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3794 return NT_STATUS_NO_SUCH_GROUP;
3798 /* check if group really exists */
3799 if ( (grp=getgrgid(gid)) == NULL)
3800 return NT_STATUS_NO_SUCH_GROUP;
3802 /* we can delete the UNIX group */
3803 smb_delete_group(grp->gr_name);
3805 /* check if the group has been successfully deleted */
3806 if ( (grp=getgrgid(gid)) != NULL)
3807 return NT_STATUS_ACCESS_DENIED;
3809 if(!pdb_delete_group_mapping_entry(group_sid))
3810 return NT_STATUS_ACCESS_DENIED;
3812 if (!close_policy_hnd(p, &q_u->group_pol))
3813 return NT_STATUS_OBJECT_NAME_INVALID;
3815 return NT_STATUS_OK;
3818 /*********************************************************************
3819 _samr_delete_dom_alias
3820 *********************************************************************/
3822 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3827 fstring alias_sid_str;
3833 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3835 /* Find the policy handle. Open a policy on it. */
3836 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3837 return NT_STATUS_INVALID_HANDLE;
3839 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3843 sid_copy(&dom_sid, &alias_sid);
3844 sid_to_string(alias_sid_str, &dom_sid);
3845 sid_split_rid(&dom_sid, &alias_rid);
3847 DEBUG(10, ("sid is %s\n", alias_sid_str));
3849 /* we check if it's our SID before deleting */
3850 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3851 return NT_STATUS_NO_SUCH_ALIAS;
3853 DEBUG(10, ("lookup on Local SID\n"));
3855 if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3856 return NT_STATUS_NO_SUCH_ALIAS;
3860 /* check if group really exists */
3861 if ( (grp=getgrgid(gid)) == NULL)
3862 return NT_STATUS_NO_SUCH_ALIAS;
3864 /* we can delete the UNIX group */
3865 smb_delete_group(grp->gr_name);
3867 /* check if the group has been successfully deleted */
3868 if ( (grp=getgrgid(gid)) != NULL)
3869 return NT_STATUS_ACCESS_DENIED;
3871 /* don't check if we removed it as it could be an un-mapped group */
3872 pdb_delete_group_mapping_entry(alias_sid);
3874 if (!close_policy_hnd(p, &q_u->alias_pol))
3875 return NT_STATUS_OBJECT_NAME_INVALID;
3877 return NT_STATUS_OK;
3880 /*********************************************************************
3881 _samr_create_dom_group
3882 *********************************************************************/
3884 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3891 struct samr_info *info;
3892 PRIVILEGE_SET priv_set;
3896 init_privilege(&priv_set);
3898 /* Find the policy handle. Open a policy on it. */
3899 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3900 return NT_STATUS_INVALID_HANDLE;
3902 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3906 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3907 return NT_STATUS_ACCESS_DENIED;
3909 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3911 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3913 /* check if group already exist */
3914 if ((grp=getgrnam(name)) != NULL)
3915 return NT_STATUS_GROUP_EXISTS;
3917 /* we can create the UNIX group */
3918 if (smb_create_group(name, &gid) != 0)
3919 return NT_STATUS_ACCESS_DENIED;
3921 /* check if the group has been successfully created */
3922 if ((grp=getgrgid(gid)) == NULL)
3923 return NT_STATUS_ACCESS_DENIED;
3925 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3927 /* add the group to the mapping table */
3928 sid_copy(&info_sid, get_global_sam_sid());
3929 sid_append_rid(&info_sid, r_u->rid);
3930 sid_to_string(sid_string, &info_sid);
3932 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
3933 return NT_STATUS_ACCESS_DENIED;
3935 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3936 return NT_STATUS_NO_MEMORY;
3938 /* get a (unique) handle. open a policy on it. */
3939 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3940 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3942 return NT_STATUS_OK;
3945 /*********************************************************************
3946 _samr_create_dom_alias
3947 *********************************************************************/
3949 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3956 struct samr_info *info;
3957 PRIVILEGE_SET priv_set;
3961 init_privilege(&priv_set);
3963 /* Find the policy handle. Open a policy on it. */
3964 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
3965 return NT_STATUS_INVALID_HANDLE;
3967 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3971 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3972 return NT_STATUS_ACCESS_DENIED;
3974 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3976 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3978 /* check if group already exists */
3979 if ( (grp=getgrnam(name)) != NULL)
3980 return NT_STATUS_GROUP_EXISTS;
3982 /* we can create the UNIX group */
3983 if (smb_create_group(name, &gid) != 0)
3984 return NT_STATUS_ACCESS_DENIED;
3986 /* check if the group has been successfully created */
3987 if ((grp=getgrgid(gid)) == NULL)
3988 return NT_STATUS_ACCESS_DENIED;
3990 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3992 sid_copy(&info_sid, get_global_sam_sid());
3993 sid_append_rid(&info_sid, r_u->rid);
3994 sid_to_string(sid_string, &info_sid);
3996 /* add the group to the mapping table */
3997 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
3998 return NT_STATUS_ACCESS_DENIED;
4000 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4001 return NT_STATUS_NO_MEMORY;
4003 /* get a (unique) handle. open a policy on it. */
4004 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4005 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4007 return NT_STATUS_OK;
4010 /*********************************************************************
4011 _samr_query_groupinfo
4013 sends the name/comment pair of a domain group
4014 level 1 send also the number of users of that group
4015 *********************************************************************/
4017 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4023 GROUP_INFO_CTR *ctr;
4026 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4027 return NT_STATUS_INVALID_HANDLE;
4029 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4033 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
4034 return NT_STATUS_INVALID_HANDLE;
4036 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
4038 return NT_STATUS_NO_MEMORY;
4040 switch (q_u->switch_level) {
4042 ctr->switch_value1 = 1;
4043 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
4044 return NT_STATUS_NO_SUCH_GROUP;
4045 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
4049 ctr->switch_value1 = 3;
4050 init_samr_group_info3(&ctr->group.info3);
4053 ctr->switch_value1 = 4;
4054 init_samr_group_info4(&ctr->group.info4, map.comment);
4057 return NT_STATUS_INVALID_INFO_CLASS;
4060 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4062 return NT_STATUS_OK;
4065 /*********************************************************************
4068 update a domain group's comment.
4069 *********************************************************************/
4071 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4075 GROUP_INFO_CTR *ctr;
4078 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4079 return NT_STATUS_INVALID_HANDLE;
4081 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4085 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
4086 return NT_STATUS_NO_SUCH_GROUP;
4090 switch (ctr->switch_value1) {
4092 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4095 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4098 free_privilege(&map.priv_set);
4099 return NT_STATUS_INVALID_INFO_CLASS;
4102 if(!pdb_update_group_mapping_entry(&map)) {
4103 free_privilege(&map.priv_set);
4104 return NT_STATUS_NO_SUCH_GROUP;
4107 free_privilege(&map.priv_set);
4109 return NT_STATUS_OK;
4112 /*********************************************************************
4115 update an alias's comment.
4116 *********************************************************************/
4118 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4122 ALIAS_INFO_CTR *ctr;
4125 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4126 return NT_STATUS_INVALID_HANDLE;
4128 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4132 if (!get_local_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
4133 return NT_STATUS_NO_SUCH_GROUP;
4137 switch (ctr->switch_value1) {
4139 unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
4142 free_privilege(&map.priv_set);
4143 return NT_STATUS_INVALID_INFO_CLASS;
4146 if(!pdb_update_group_mapping_entry(&map)) {
4147 free_privilege(&map.priv_set);
4148 return NT_STATUS_NO_SUCH_GROUP;
4151 free_privilege(&map.priv_set);
4153 return NT_STATUS_OK;
4156 /*********************************************************************
4157 _samr_get_dom_pwinfo
4158 *********************************************************************/
4160 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4162 /* Perform access check. Since this rpc does not require a
4163 policy handle it will not be caught by the access checks on
4164 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4166 if (!pipe_access_check(p)) {
4167 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4168 r_u->status = NT_STATUS_ACCESS_DENIED;
4172 /* Actually, returning zeros here works quite well :-). */
4174 return NT_STATUS_OK;
4177 /*********************************************************************
4179 *********************************************************************/
4181 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4186 struct samr_info *info;
4187 SEC_DESC *psd = NULL;
4194 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4195 return NT_STATUS_INVALID_HANDLE;
4197 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4201 /*check if access can be granted as requested by client. */
4202 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4203 se_map_generic(&des_access,&grp_generic_mapping);
4204 if (!NT_STATUS_IS_OK(status =
4205 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4206 des_access, &acc_granted, "_samr_open_group"))) {
4211 /* this should not be hard-coded like this */
4212 if (!sid_equal(&sid, get_global_sam_sid()))
4213 return NT_STATUS_ACCESS_DENIED;
4215 sid_copy(&info_sid, get_global_sam_sid());
4216 sid_append_rid(&info_sid, q_u->rid_group);
4217 sid_to_string(sid_string, &info_sid);
4219 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4220 return NT_STATUS_NO_MEMORY;
4222 info->acc_granted = acc_granted;
4224 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4226 /* check if that group really exists */
4227 if (!get_domain_group_from_sid(info->sid, &map, MAPPING_WITHOUT_PRIV))
4228 return NT_STATUS_NO_SUCH_GROUP;
4230 /* get a (unique) handle. open a policy on it. */
4231 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4232 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4234 return NT_STATUS_OK;
4237 /*********************************************************************
4239 *********************************************************************/
4241 NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
4243 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
4244 return NT_STATUS_NOT_IMPLEMENTED;
4247 /*******************************************************************
4249 ********************************************************************/
4251 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4253 struct samr_info *info = NULL;
4255 uint32 min_pass_len,pass_hist,flag;
4256 time_t u_expire, u_min_age;
4257 NTTIME nt_expire, nt_min_age;
4259 time_t u_lock_duration, u_reset_time;
4260 NTTIME nt_lock_duration, nt_reset_time;
4266 uint32 num_users=0, num_groups=0, num_aliases=0;
4268 uint32 account_policy_temp;
4270 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4271 return NT_STATUS_NO_MEMORY;
4275 r_u->status = NT_STATUS_OK;
4277 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4279 /* find the policy handle. open a policy on it. */
4280 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4281 return NT_STATUS_INVALID_HANDLE;
4283 switch (q_u->switch_value) {
4285 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4286 min_pass_len = account_policy_temp;
4288 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4289 pass_hist = account_policy_temp;
4291 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4292 flag = account_policy_temp;
4294 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4295 u_expire = account_policy_temp;
4297 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4298 u_min_age = account_policy_temp;
4300 unix_to_nt_time_abs(&nt_expire, u_expire);
4301 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4303 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4304 flag, nt_expire, nt_min_age);
4308 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4310 if (!NT_STATUS_IS_OK(r_u->status)) {
4311 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4314 num_users=info->disp_info.num_user_account;
4317 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4318 if (NT_STATUS_IS_ERR(r_u->status)) {
4319 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4322 num_groups=info->disp_info.num_group_account;
4325 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4326 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
4327 num_users, num_groups, num_aliases);
4330 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4331 u_logout = account_policy_temp;
4333 unix_to_nt_time_abs(&nt_logout, u_logout);
4335 init_unk_info3(&ctr->info.inf3, nt_logout);
4338 init_unk_info5(&ctr->info.inf5, global_myname());
4341 init_unk_info6(&ctr->info.inf6);
4344 init_unk_info7(&ctr->info.inf7);
4347 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4348 u_lock_duration = account_policy_temp;
4350 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4351 u_reset_time = account_policy_temp;
4353 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4354 lockout = account_policy_temp;
4356 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4357 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4359 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4362 return NT_STATUS_INVALID_INFO_CLASS;
4365 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4367 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4372 /*******************************************************************
4374 ********************************************************************/
4376 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4378 time_t u_expire, u_min_age;
4380 time_t u_lock_duration, u_reset_time;
4382 r_u->status = NT_STATUS_OK;
4384 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4386 /* find the policy handle. open a policy on it. */
4387 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4388 return NT_STATUS_INVALID_HANDLE;
4390 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4392 switch (q_u->switch_value) {
4394 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4395 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4397 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4398 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4399 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4400 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4401 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4406 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4407 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4416 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4417 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count);
4419 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4420 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4421 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4424 return NT_STATUS_INVALID_INFO_CLASS;
4427 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4429 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));