2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2002,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Anthony Liguori 2002,
11 * Copyright (C) Jim McDonough 2002.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 * This is the implementation of the SAMR code.
35 #define DBGC_CLASS DBGC_RPC_SRV
37 extern fstring global_myworkgroup;
38 extern pstring global_myname;
39 extern DOM_SID global_sid_Builtin;
41 extern rid_name domain_group_rids[];
42 extern rid_name domain_alias_rids[];
43 extern rid_name builtin_alias_rids[];
46 typedef struct _disp_info {
48 uint32 num_user_account;
49 DISP_USER_INFO *disp_user_info;
51 uint32 num_group_account;
52 DISP_GROUP_INFO *disp_group_info;
56 /* for use by the \PIPE\samr policy */
58 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
67 struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
68 struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
69 struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
70 struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
71 struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
73 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
75 /*******************************************************************
76 Checks if access to an object should be granted, and returns that
77 level of access for further checks.
78 ********************************************************************/
80 NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_token, uint32 des_access,
81 uint32 *acc_granted, const char *debug)
83 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
85 if (!se_access_check(psd, nt_user_token, des_access, acc_granted, &status)) {
86 if (geteuid() == sec_initial_uid()) {
87 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n",
89 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
90 status = NT_STATUS_OK;
93 DEBUG(2,("%s: ACCESS DENIED (requested: %#010x)\n",
100 /*******************************************************************
101 Checks if access to a function can be granted
102 ********************************************************************/
104 NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
106 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
107 debug, acc_granted, acc_required));
108 if ((acc_granted & acc_required) != acc_required) {
109 if (geteuid() == sec_initial_uid()) {
110 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
111 debug, acc_granted, acc_required));
112 DEBUGADD(4,("but overwritten by euid == 0\n"));
115 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
116 debug, acc_granted, acc_required));
117 return NT_STATUS_ACCESS_DENIED;
123 /*******************************************************************
124 Create a samr_info struct.
125 ********************************************************************/
127 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
129 struct samr_info *info;
134 sid_to_string(sid_str, psid);
136 fstrcpy(sid_str,"(NULL)");
139 mem_ctx = talloc_init_named("samr_info for domain sid %s", sid_str);
141 if ((info = (struct samr_info *)talloc(mem_ctx, sizeof(struct samr_info))) == NULL)
145 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
147 sid_copy( &info->sid, psid);
149 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
151 info->mem_ctx = mem_ctx;
156 /*******************************************************************
157 Function to free the per handle data.
158 ********************************************************************/
159 static void free_samr_users(struct samr_info *info)
163 if (info->disp_info.user_dbloaded){
164 for (i=0; i<info->disp_info.num_user_account; i++) {
165 /* Not really a free, actually a 'clear' */
166 pdb_free_sam(&info->disp_info.disp_user_info[i].sam);
169 info->disp_info.user_dbloaded=False;
170 info->disp_info.num_user_account=0;
174 /*******************************************************************
175 Function to free the per handle data.
176 ********************************************************************/
177 static void free_samr_db(struct samr_info *info)
179 /* Groups are talloced */
181 free_samr_users(info);
183 info->disp_info.group_dbloaded=False;
184 info->disp_info.num_group_account=0;
188 static void free_samr_info(void *ptr)
190 struct samr_info *info=(struct samr_info *) ptr;
193 talloc_destroy(info->mem_ctx);
196 /*******************************************************************
197 Ensure password info is never given out. Paranioa... JRA.
198 ********************************************************************/
200 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
206 /* These now zero out the old password */
208 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
209 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
213 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL all_machines)
215 SAM_ACCOUNT *pwd = NULL;
216 DISP_USER_INFO *pwd_array = NULL;
217 NTSTATUS nt_status = NT_STATUS_OK;
218 TALLOC_CTX *mem_ctx = info->mem_ctx;
220 DEBUG(10,("load_sampwd_entries\n"));
222 /* if the snapshoot is already loaded, return */
223 if ((info->disp_info.user_dbloaded==True)
224 && (info->acb_mask == acb_mask)
225 && (info->all_machines == all_machines)) {
226 DEBUG(10,("load_sampwd_entries: already in memory\n"));
230 free_samr_users(info);
232 if (!pdb_setsampwent(False)) {
233 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
234 return NT_STATUS_ACCESS_DENIED;
237 for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd)))
238 && pdb_getsampwent(pwd) == True; pwd=NULL) {
241 if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST)
242 || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
243 DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
248 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
250 DEBUG(5,(" acb_mask %x reject\n", acb_mask));
255 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
256 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
258 DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
259 pwd_array=(DISP_USER_INFO *)talloc_realloc(mem_ctx, info->disp_info.disp_user_info,
260 (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(DISP_USER_INFO));
263 return NT_STATUS_NO_MEMORY;
265 info->disp_info.disp_user_info=pwd_array;
268 /* link the SAM_ACCOUNT to the array */
269 info->disp_info.disp_user_info[info->disp_info.num_user_account].sam=pwd;
271 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
273 info->disp_info.num_user_account++;
278 /* the snapshoot is in memory, we're ready to enumerate fast */
280 info->acb_mask = acb_mask;
281 info->all_machines = all_machines;
282 info->disp_info.user_dbloaded=True;
284 DEBUG(10,("load_sampwd_entries: done\n"));
289 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
292 DISP_GROUP_INFO *grp_array = NULL;
293 uint32 group_entries = 0;
295 TALLOC_CTX *mem_ctx = info->mem_ctx;
297 DEBUG(10,("load_group_domain_entries\n"));
299 /* if the snapshoot is already loaded, return */
300 if (info->disp_info.group_dbloaded==True) {
301 DEBUG(10,("load_group_domain_entries: already in memory\n"));
305 if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV)) {
306 DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
307 return NT_STATUS_NO_MEMORY;
310 info->disp_info.num_group_account=group_entries;
312 grp_array=(DISP_GROUP_INFO *)talloc(mem_ctx, info->disp_info.num_group_account*sizeof(DISP_GROUP_INFO));
314 if (group_entries!=0 && grp_array==NULL) {
315 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
317 return NT_STATUS_NO_MEMORY;
320 info->disp_info.disp_group_info=grp_array;
322 for (i=0; i<group_entries; i++) {
324 grp_array[i].grp=(DOMAIN_GRP *)talloc(mem_ctx, sizeof(DOMAIN_GRP));
326 fstrcpy(grp_array[i].grp->name, map[i].nt_name);
327 fstrcpy(grp_array[i].grp->comment, map[i].comment);
328 sid_split_rid(&map[i].sid, &grp_array[i].grp->rid);
329 grp_array[i].grp->attr=SID_NAME_DOM_GRP;
334 /* the snapshoot is in memory, we're ready to enumerate fast */
336 info->disp_info.group_dbloaded=True;
338 DEBUG(10,("load_group_domain_entries: done\n"));
344 /*******************************************************************
346 ********************************************************************/
348 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
350 r_u->status = NT_STATUS_OK;
352 /* close the policy handle */
353 if (!close_policy_hnd(p, &q_u->pol))
354 return NT_STATUS_OBJECT_NAME_INVALID;
356 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
361 /*******************************************************************
362 samr_reply_open_domain
363 ********************************************************************/
365 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
367 struct samr_info *info;
368 SEC_DESC *psd = NULL;
370 uint32 des_access = q_u->flags;
374 r_u->status = NT_STATUS_OK;
376 /* find the connection policy handle. */
377 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
378 return NT_STATUS_INVALID_HANDLE;
380 if (!NT_STATUS_IS_OK(status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN,"_samr_open_domain"))) {
384 /*check if access can be granted as requested by client. */
385 samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
386 se_map_generic(&des_access,&dom_generic_mapping);
388 if (!NT_STATUS_IS_OK(status =
389 access_check_samr_object(psd, p->pipe_user.nt_user_token,
390 des_access, &acc_granted, "_samr_open_domain"))) {
394 /* associate the domain SID with the (unique) handle. */
395 if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
396 return NT_STATUS_NO_MEMORY;
397 info->acc_granted = acc_granted;
399 /* get a (unique) handle. open a policy on it. */
400 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
401 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
403 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
408 /*******************************************************************
409 _samr_get_usrdom_pwinfo
410 ********************************************************************/
412 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
414 struct samr_info *info = NULL;
416 r_u->status = NT_STATUS_OK;
418 /* find the policy handle. open a policy on it. */
419 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
420 return NT_STATUS_INVALID_HANDLE;
422 if (!sid_check_is_in_our_domain(&info->sid))
423 return NT_STATUS_OBJECT_TYPE_MISMATCH;
425 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
427 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
430 * NT sometimes return NT_STATUS_ACCESS_DENIED
431 * I don't know yet why.
437 /*******************************************************************
439 ********************************************************************/
441 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
443 extern DOM_SID global_sid_World;
452 sid_copy(&adm_sid, &global_sid_Builtin);
453 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
455 sid_copy(&act_sid, &global_sid_Builtin);
456 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
458 /*basic access for every one*/
459 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
460 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
462 /*full access for builtin aliases Administrators and Account Operators*/
463 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS);
464 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
465 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
467 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
468 return NT_STATUS_NO_MEMORY;
470 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
471 return NT_STATUS_NO_MEMORY;
476 /*******************************************************************
478 ********************************************************************/
480 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
482 extern DOM_SID global_sid_World;
491 sid_copy(&adm_sid, &global_sid_Builtin);
492 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
494 sid_copy(&act_sid, &global_sid_Builtin);
495 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
497 /*basic access for every one*/
498 init_sec_access(&mask, GENERIC_RIGHTS_USER_EXECUTE | GENERIC_RIGHTS_USER_READ);
499 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
501 /*full access for builtin aliases Administrators and Account Operators*/
502 init_sec_access(&mask, GENERIC_RIGHTS_USER_ALL_ACCESS);
503 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
504 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
506 /*extended access for the user*/
507 init_sec_access(&mask,READ_CONTROL_ACCESS | SA_RIGHT_USER_CHANGE_PASSWORD | SA_RIGHT_USER_SET_LOC_COM);
508 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
510 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
511 return NT_STATUS_NO_MEMORY;
513 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
514 return NT_STATUS_NO_MEMORY;
519 /*******************************************************************
521 ********************************************************************/
523 static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
525 extern DOM_SID global_sid_World;
534 sid_copy(&adm_sid, &global_sid_Builtin);
535 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
537 sid_copy(&act_sid, &global_sid_Builtin);
538 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
540 /*basic access for every one*/
541 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
542 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
544 /*full access for builtin aliases Administrators and Account Operators*/
545 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_ALL_ACCESS);
546 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
547 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
549 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
550 return NT_STATUS_NO_MEMORY;
552 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
553 return NT_STATUS_NO_MEMORY;
558 /*******************************************************************
560 ********************************************************************/
562 static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
564 extern DOM_SID global_sid_World;
573 sid_copy(&adm_sid, &global_sid_Builtin);
574 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
576 sid_copy(&act_sid, &global_sid_Builtin);
577 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
579 /*basic access for every one*/
580 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
581 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
583 /*full access for builtin aliases Administrators and Account Operators*/
584 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_ALL_ACCESS);
585 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
586 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
588 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
589 return NT_STATUS_NO_MEMORY;
591 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
592 return NT_STATUS_NO_MEMORY;
597 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
599 struct samr_info *info = NULL;
601 /* find the policy handle. open a policy on it. */
602 if (!find_policy_by_hnd(p, pol, (void **)&info))
609 *acc_granted = info->acc_granted;
613 /*******************************************************************
615 ********************************************************************/
617 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
619 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
620 return NT_STATUS_NOT_IMPLEMENTED;
624 /*******************************************************************
626 ********************************************************************/
628 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
632 SEC_DESC * psd = NULL;
636 r_u->status = NT_STATUS_OK;
639 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
640 return NT_STATUS_INVALID_HANDLE;
644 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
646 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
648 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
649 if (pol_sid.sid_rev_num == 0)
651 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
652 r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
654 else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */
657 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
658 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
660 else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */
662 /* TODO: Builtin probably needs a different SD with restricted write access*/
663 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
664 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
666 else if (sid_check_is_in_our_domain(&pol_sid) ||
667 sid_check_is_in_builtin(&pol_sid))
669 /* TODO: different SDs have to be generated for aliases groups and users.
670 Currently all three get a default user SD */
671 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
672 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
674 else return NT_STATUS_OBJECT_TYPE_MISMATCH;
676 if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
677 return NT_STATUS_NO_MEMORY;
679 if (NT_STATUS_IS_OK(r_u->status))
685 /*******************************************************************
686 makes a SAM_ENTRY / UNISTR2* structure from a user list.
687 ********************************************************************/
689 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
690 uint32 num_entries, uint32 start_idx, DISP_USER_INFO *disp_user_info,
696 SAM_ACCOUNT *pwd = NULL;
697 UNISTR2 uni_temp_name;
698 const char *temp_name;
699 const DOM_SID *user_sid;
701 fstring user_sid_string;
702 fstring domain_sid_string;
707 if (num_entries == 0)
710 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_entries);
712 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_entries);
714 if (sam == NULL || uni_name == NULL) {
715 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
716 return NT_STATUS_NO_MEMORY;
719 for (i = 0; i < num_entries; i++) {
720 pwd = disp_user_info[i+start_idx].sam;
721 temp_name = pdb_get_username(pwd);
722 init_unistr2(&uni_temp_name, temp_name, strlen(temp_name)+1);
723 user_sid = pdb_get_user_sid(pwd);
725 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
726 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
727 "the domain sid %s. Failing operation.\n",
729 sid_to_string(user_sid_string, user_sid),
730 sid_to_string(domain_sid_string, domain_sid)));
731 return NT_STATUS_UNSUCCESSFUL;
734 init_sam_entry(&sam[i], uni_temp_name.uni_str_len, user_rid);
735 copy_unistr2(&uni_name[i], &uni_temp_name);
739 *uni_name_pp = uni_name;
743 /*******************************************************************
744 samr_reply_enum_dom_users
745 ********************************************************************/
747 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
748 SAMR_R_ENUM_DOM_USERS *r_u)
750 struct samr_info *info = NULL;
751 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
753 uint32 enum_context=q_u->start_idx;
754 uint32 max_size=q_u->max_size;
756 enum remote_arch_types ra_type = get_remote_arch();
757 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
758 uint32 max_entries = max_sam_entries;
761 r_u->status = NT_STATUS_OK;
763 /* find the policy handle. open a policy on it. */
764 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
765 return NT_STATUS_INVALID_HANDLE;
767 domain_sid = info->sid;
769 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
770 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
771 "_samr_enum_dom_users"))) {
775 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
778 r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
781 if (!NT_STATUS_IS_OK(r_u->status))
784 num_account = info->disp_info.num_user_account;
786 if (enum_context > num_account) {
787 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
791 /* verify we won't overflow */
792 if (max_entries > num_account-enum_context) {
793 max_entries = num_account-enum_context;
794 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
797 /* calculate the size and limit on the number of entries we will return */
798 temp_size=max_entries*struct_size;
800 if (temp_size>max_size) {
801 max_entries=MIN((max_size/struct_size),max_entries);;
802 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
806 * Note from JRA. total_entries is not being used here. Currently if there is a
807 * large user base then it looks like NT will enumerate until get_sampwd_entries
808 * returns False due to num_entries being zero. This will cause an access denied
809 * return. I don't think this is right and needs further investigation. Note that
810 * this is also the same in the TNG code (I don't think that has been tested with
811 * a very large user list as MAX_SAM_ENTRIES is set to 600).
813 * I also think that one of the 'num_entries' return parameters is probably
814 * the "max entries" parameter - but in the TNG code they're all currently set to the same
815 * value (again I think this is wrong).
818 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
819 max_entries, enum_context,
820 info->disp_info.disp_user_info,
823 if (!NT_STATUS_IS_OK(r_u->status))
826 if (enum_context+max_entries < num_account)
827 r_u->status = STATUS_MORE_ENTRIES;
829 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
831 init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
833 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
838 /*******************************************************************
839 makes a SAM_ENTRY / UNISTR2* structure from a group list.
840 ********************************************************************/
842 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
843 uint32 num_sam_entries, DOMAIN_GRP *grp)
852 if (num_sam_entries == 0)
855 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
857 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
859 if (sam == NULL || uni_name == NULL) {
860 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
864 for (i = 0; i < num_sam_entries; i++) {
866 * JRA. I think this should include the null. TNG does not.
868 int len = strlen(grp[i].name)+1;
870 init_sam_entry(&sam[i], len, grp[i].rid);
871 init_unistr2(&uni_name[i], grp[i].name, len);
875 *uni_name_pp = uni_name;
878 /*******************************************************************
879 Get the group entries - similar to get_sampwd_entries().
880 ********************************************************************/
882 static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
883 uint32 *p_num_entries, uint32 max_entries)
886 uint32 num_entries = 0;
889 GROUP_MAP *map = NULL;
891 sid_to_string(sid_str, sid);
892 DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str));
896 /* well-known aliases */
897 if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
899 pdb_enum_group_mapping(SID_NAME_WKN_GRP, &map, (int *)&num_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
901 if (num_entries != 0) {
902 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
904 return NT_STATUS_NO_MEMORY;
906 for(i=0; i<num_entries && i<max_entries; i++) {
907 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
908 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
914 } else if (sid_equal(sid, get_global_sam_sid()) && !lp_hide_local_users()) {
915 struct sys_grent *glist;
916 struct sys_grent *grp;
918 gid_t winbind_gid_low, winbind_gid_high;
919 BOOL winbind_groups_exist = lp_winbind_gid(&winbind_gid_low, &winbind_gid_high);
922 /* we return the UNIX groups here. This seems to be the right */
923 /* thing to do, since NT member servers return their local */
924 /* groups in the same situation. */
926 /* use getgrent_list() to retrieve the list of groups to avoid
927 * problems with getgrent possible infinite loop by internal
928 * libc grent structures overwrites by called functions */
929 grp = glist = getgrent_list();
931 return NT_STATUS_NO_MEMORY;
933 for (; (num_entries < max_entries) && (grp != NULL); grp = grp->next) {
936 if(!pdb_getgrgid(&smap, grp->gr_gid, MAPPING_WITHOUT_PRIV))
939 if (smap.sid_name_use!=SID_NAME_ALIAS) {
943 sid_split_rid(&smap.sid, &trid);
945 if (!sid_equal(sid, &smap.sid))
948 /* Don't return winbind groups as they are not local! */
949 if (winbind_groups_exist && (grp->gr_gid >= winbind_gid_low)&&(grp->gr_gid <= winbind_gid_high)) {
950 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
954 /* Don't return user private groups... */
956 if ((pw = Get_Pwnam(smap.nt_name)) != 0) {
957 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
961 for( i = 0; i < num_entries; i++)
962 if ( (*d_grp)[i].rid == trid )
965 if ( i < num_entries ) {
966 continue; /* rid was there, dup! */
969 /* JRA - added this for large group db enumeration... */
972 /* skip the requested number of entries.
973 not very efficient, but hey...
979 *d_grp=talloc_realloc(ctx,*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
982 return NT_STATUS_NO_MEMORY;
985 fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
986 (*d_grp)[num_entries].rid = trid;
988 DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries, trid));
994 *p_num_entries = num_entries;
996 DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries));
998 if (num_entries >= max_entries)
999 return STATUS_MORE_ENTRIES;
1000 return NT_STATUS_OK;
1003 /*******************************************************************
1004 Get the group entries - similar to get_sampwd_entries().
1005 ********************************************************************/
1007 static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
1008 uint32 *p_num_entries, uint32 max_entries)
1010 GROUP_MAP *map=NULL;
1012 uint32 group_entries = 0;
1013 uint32 num_entries = 0;
1017 pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
1019 num_entries=group_entries-start_idx;
1021 /* limit the number of entries */
1022 if (num_entries>max_entries) {
1023 DEBUG(5,("Limiting to %d entries\n", max_entries));
1024 num_entries=max_entries;
1027 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
1028 if (num_entries!=0 && *d_grp==NULL){
1030 return NT_STATUS_NO_MEMORY;
1033 for (i=0; i<num_entries; i++) {
1034 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
1035 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
1036 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
1037 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
1042 *p_num_entries = num_entries;
1044 return NT_STATUS_OK;
1047 /*******************************************************************
1048 samr_reply_enum_dom_groups
1049 ********************************************************************/
1051 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
1053 DOMAIN_GRP *grp=NULL;
1058 r_u->status = NT_STATUS_OK;
1060 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1061 return NT_STATUS_INVALID_HANDLE;
1063 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
1067 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1069 /* the domain group array is being allocated in the function below */
1070 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))) {
1074 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1076 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
1078 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1084 /*******************************************************************
1085 samr_reply_enum_dom_aliases
1086 ********************************************************************/
1088 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1090 DOMAIN_GRP *grp=NULL;
1091 uint32 num_entries = 0;
1097 r_u->status = NT_STATUS_OK;
1099 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1100 return NT_STATUS_INVALID_HANDLE;
1102 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1106 sid_to_string(sid_str, &sid);
1107 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1109 status = get_group_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1110 &num_entries, MAX_SAM_ENTRIES);
1111 if (NT_STATUS_IS_ERR(status)) return status;
1113 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1117 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1119 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1124 /*******************************************************************
1125 samr_reply_query_dispinfo
1126 ********************************************************************/
1127 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1128 SAMR_R_QUERY_DISPINFO *r_u)
1130 struct samr_info *info = NULL;
1131 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1133 uint32 max_entries=q_u->max_entries;
1134 uint32 enum_context=q_u->start_idx;
1135 uint32 max_size=q_u->max_size;
1137 SAM_DISPINFO_CTR *ctr;
1138 uint32 temp_size=0, total_data_size=0;
1140 uint32 num_account = 0;
1141 enum remote_arch_types ra_type = get_remote_arch();
1142 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1145 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1146 r_u->status = NT_STATUS_OK;
1148 /* find the policy handle. open a policy on it. */
1149 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1150 return NT_STATUS_INVALID_HANDLE;
1152 domain_sid = info->sid;
1155 * calculate how many entries we will return.
1157 * - the number of entries the client asked
1158 * - our limit on that
1159 * - the starting point (enumeration context)
1160 * - the buffer size the client will accept
1164 * We are a lot more like W2K. Instead of reading the SAM
1165 * each time to find the records we need to send back,
1166 * we read it once and link that copy to the sam handle.
1167 * For large user list (over the MAX_SAM_ENTRIES)
1168 * it's a definitive win.
1169 * second point to notice: between enumerations
1170 * our sam is now the same as it's a snapshoot.
1171 * third point: got rid of the static SAM_USER_21 struct
1172 * no more intermediate.
1173 * con: it uses much more memory, as a full copy is stored
1176 * If you want to change it, think twice and think
1177 * of the second point , that's really important.
1182 /* Get what we need from the password database */
1183 switch (q_u->switch_level) {
1185 /* When playing with usrmgr, this is necessary
1186 if you want immediate refresh after editing
1187 a user. I would like to do this after the
1188 setuserinfo2, but we do not have access to
1189 the domain handle in that call, only to the
1190 user handle. Where else does this hurt?
1194 /* We cannot do this here - it kills performace. JRA. */
1195 free_samr_users(info);
1200 /* Level 2 is for all machines, otherwise only 'normal' users */
1201 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1203 if (!NT_STATUS_IS_OK(r_u->status)) {
1204 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1207 num_account = info->disp_info.num_user_account;
1211 r_u->status = load_group_domain_entries(info, &info->sid);
1212 if (!NT_STATUS_IS_OK(r_u->status))
1214 num_account = info->disp_info.num_group_account;
1217 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1218 return NT_STATUS_INVALID_INFO_CLASS;
1221 /* first limit the number of entries we will return */
1222 if(max_entries > max_sam_entries) {
1223 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1224 max_entries = max_sam_entries;
1227 if (enum_context > num_account) {
1228 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1229 return NT_STATUS_NO_MORE_ENTRIES;
1232 /* verify we won't overflow */
1233 if (max_entries > num_account-enum_context) {
1234 max_entries = num_account-enum_context;
1235 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1238 /* calculate the size and limit on the number of entries we will return */
1239 temp_size=max_entries*struct_size;
1241 if (temp_size>max_size) {
1242 max_entries=MIN((max_size/struct_size),max_entries);;
1243 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1246 if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1247 return NT_STATUS_NO_MEMORY;
1251 /* Now create reply structure */
1252 switch (q_u->switch_level) {
1255 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
1256 return NT_STATUS_NO_MEMORY;
1258 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1259 info->disp_info.disp_user_info, &domain_sid);
1260 if (!NT_STATUS_IS_OK(disp_ret))
1265 if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1266 return NT_STATUS_NO_MEMORY;
1268 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1269 info->disp_info.disp_user_info, &domain_sid);
1270 if (!NT_STATUS_IS_OK(disp_ret))
1275 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1276 return NT_STATUS_NO_MEMORY;
1278 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1279 if (!NT_STATUS_IS_OK(disp_ret))
1284 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1285 return NT_STATUS_NO_MEMORY;
1287 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1288 if (!NT_STATUS_IS_OK(disp_ret))
1293 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1294 return NT_STATUS_NO_MEMORY;
1296 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1297 if (!NT_STATUS_IS_OK(disp_ret))
1302 ctr->sam.info = NULL;
1303 return NT_STATUS_INVALID_INFO_CLASS;
1306 /* calculate the total size */
1307 total_data_size=num_account*struct_size;
1309 if (enum_context+max_entries < num_account)
1310 r_u->status = STATUS_MORE_ENTRIES;
1312 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1314 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1320 /*******************************************************************
1321 samr_reply_query_aliasinfo
1322 ********************************************************************/
1324 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1330 r_u->status = NT_STATUS_OK;
1332 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1334 /* find the policy handle. open a policy on it. */
1335 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1336 return NT_STATUS_INVALID_HANDLE;
1337 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1341 if (!sid_check_is_in_our_domain(&sid) &&
1342 !sid_check_is_in_builtin(&sid))
1343 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1345 if (!pdb_getgrsid(&map, sid, MAPPING_WITHOUT_PRIV))
1346 return NT_STATUS_NO_SUCH_ALIAS;
1348 switch (q_u->switch_level) {
1351 r_u->ctr.switch_value1 = 1;
1352 init_samr_alias_info1(&r_u->ctr.alias.info1, map.nt_name, 1, map.comment);
1356 r_u->ctr.switch_value1 = 3;
1357 init_samr_alias_info3(&r_u->ctr.alias.info3, map.comment);
1360 return NT_STATUS_INVALID_INFO_CLASS;
1363 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1369 /*******************************************************************
1370 samr_reply_lookup_ids
1371 ********************************************************************/
1373 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1375 uint32 rid[MAX_SAM_ENTRIES];
1376 int num_rids = q_u->num_sids1;
1378 r_u->status = NT_STATUS_OK;
1380 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1382 if (num_rids > MAX_SAM_ENTRIES) {
1383 num_rids = MAX_SAM_ENTRIES;
1384 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1389 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1391 for (i = 0; i < num_rids && status == 0; i++)
1393 struct sam_passwd *sam_pass;
1397 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1398 q_u->uni_user_name[i].uni_str_len));
1400 /* find the user account */
1402 sam_pass = get_smb21pwd_entry(user_name, 0);
1405 if (sam_pass == NULL)
1407 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1412 rid[i] = sam_pass->user_rid;
1418 rid[0] = BUILTIN_ALIAS_RID_USERS;
1420 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1422 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1428 /*******************************************************************
1430 ********************************************************************/
1432 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1434 uint32 rid[MAX_SAM_ENTRIES];
1436 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1437 enum SID_NAME_USE local_type;
1439 int num_rids = q_u->num_names2;
1444 r_u->status = NT_STATUS_OK;
1446 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1451 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1452 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1456 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 */
1460 if (num_rids > MAX_SAM_ENTRIES) {
1461 num_rids = MAX_SAM_ENTRIES;
1462 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1465 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1467 become_root(); /* local_lookup_name can require root privs */
1469 for (i = 0; i < num_rids; i++) {
1473 r_u->status = NT_STATUS_NONE_MAPPED;
1475 rid [i] = 0xffffffff;
1476 type[i] = SID_NAME_UNKNOWN;
1478 rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1481 * we are only looking for a name
1482 * the SID we get back can be outside
1483 * the scope of the pol_sid
1485 * in clear: it prevents to reply to domain\group: yes
1486 * when only builtin\group exists.
1488 * a cleaner code is to add the sid of the domain we're looking in
1489 * to the local_lookup_name function.
1491 if(local_lookup_name(name, &sid, &local_type)) {
1492 sid_split_rid(&sid, &local_rid);
1494 if (sid_equal(&sid, &pol_sid)) {
1497 r_u->status = NT_STATUS_OK;
1504 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1506 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1511 /*******************************************************************
1512 _samr_chgpasswd_user
1513 ********************************************************************/
1515 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1520 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1522 r_u->status = NT_STATUS_OK;
1524 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1525 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1527 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1530 * Pass the user through the NT -> unix user mapping
1534 (void)map_username(user_name);
1537 * UNIX username case mangling not required, pass_oem_change
1538 * is case insensitive.
1541 if (!pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1542 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1543 r_u->status = NT_STATUS_WRONG_PASSWORD;
1545 init_samr_r_chgpasswd_user(r_u, r_u->status);
1547 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1552 /*******************************************************************
1553 makes a SAMR_R_LOOKUP_RIDS structure.
1554 ********************************************************************/
1556 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1557 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1560 UNIHDR *hdr_name=NULL;
1561 UNISTR2 *uni_name=NULL;
1563 *pp_uni_name = NULL;
1564 *pp_hdr_name = NULL;
1566 if (num_names != 0) {
1567 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1568 if (hdr_name == NULL)
1571 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1572 if (uni_name == NULL)
1576 for (i = 0; i < num_names; i++) {
1577 int len = names[i] != NULL ? strlen(names[i]) : 0;
1578 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1579 init_uni_hdr(&hdr_name[i], len);
1580 init_unistr2(&uni_name[i], names[i], len);
1583 *pp_uni_name = uni_name;
1584 *pp_hdr_name = hdr_name;
1589 /*******************************************************************
1591 ********************************************************************/
1593 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1595 fstring group_names[MAX_SAM_ENTRIES];
1596 uint32 *group_attrs = NULL;
1597 UNIHDR *hdr_name = NULL;
1598 UNISTR2 *uni_name = NULL;
1600 int num_rids = q_u->num_rids1;
1604 r_u->status = NT_STATUS_OK;
1606 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1608 /* find the policy handle. open a policy on it. */
1609 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1610 return NT_STATUS_INVALID_HANDLE;
1612 if (num_rids > MAX_SAM_ENTRIES) {
1613 num_rids = MAX_SAM_ENTRIES;
1614 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1618 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1619 return NT_STATUS_NO_MEMORY;
1622 r_u->status = NT_STATUS_NONE_MAPPED;
1624 become_root(); /* lookup_sid can require root privs */
1626 for (i = 0; i < num_rids; i++) {
1630 enum SID_NAME_USE type;
1632 group_attrs[i] = SID_NAME_UNKNOWN;
1633 *group_names[i] = '\0';
1635 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1636 sid_copy(&sid, &pol_sid);
1637 sid_append_rid(&sid, q_u->rid[i]);
1639 if (lookup_sid(&sid, domname, tmpname, &type)) {
1640 r_u->status = NT_STATUS_OK;
1641 group_attrs[i] = (uint32)type;
1642 fstrcpy(group_names[i],tmpname);
1643 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1650 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1651 return NT_STATUS_NO_MEMORY;
1653 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1655 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1660 /*******************************************************************
1661 _api_samr_open_user. Safe - gives out no passwd info.
1662 ********************************************************************/
1664 NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1666 SAM_ACCOUNT *sampass=NULL;
1668 POLICY_HND domain_pol = q_u->domain_pol;
1669 POLICY_HND *user_pol = &r_u->user_pol;
1670 struct samr_info *info = NULL;
1671 SEC_DESC *psd = NULL;
1673 uint32 des_access = q_u->access_mask;
1678 r_u->status = NT_STATUS_OK;
1680 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1681 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1682 return NT_STATUS_INVALID_HANDLE;
1684 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1688 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1689 if (!NT_STATUS_IS_OK(nt_status)) {
1693 /* append the user's RID to it */
1694 if (!sid_append_rid(&sid, q_u->user_rid))
1695 return NT_STATUS_NO_SUCH_USER;
1697 /* check if access can be granted as requested by client. */
1698 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1699 se_map_generic(&des_access, &usr_generic_mapping);
1700 if (!NT_STATUS_IS_OK(nt_status =
1701 access_check_samr_object(psd, p->pipe_user.nt_user_token,
1702 des_access, &acc_granted, "_samr_open_user"))) {
1707 ret=pdb_getsampwsid(sampass, &sid);
1710 /* check that the SID exists in our domain. */
1712 return NT_STATUS_NO_SUCH_USER;
1715 pdb_free_sam(&sampass);
1717 /* associate the user's SID and access bits with the new handle. */
1718 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1719 return NT_STATUS_NO_MEMORY;
1720 info->acc_granted = acc_granted;
1722 /* get a (unique) handle. open a policy on it. */
1723 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1724 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1729 /*************************************************************************
1730 get_user_info_10. Safe. Only gives out acb bits.
1731 *************************************************************************/
1733 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1735 SAM_ACCOUNT *smbpass=NULL;
1739 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1741 if (!NT_STATUS_IS_OK(nt_status)) {
1746 ret = pdb_getsampwsid(smbpass, user_sid);
1750 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1751 return NT_STATUS_NO_SUCH_USER;
1754 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1757 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1759 pdb_free_sam(&smbpass);
1761 return NT_STATUS_OK;
1764 /*************************************************************************
1765 get_user_info_12. OK - this is the killer as it gives out password info.
1766 Ensure that this is only allowed on an encrypted connection with a root
1768 *************************************************************************/
1770 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1772 SAM_ACCOUNT *smbpass=NULL;
1776 if (!p->ntlmssp_auth_validated)
1777 return NT_STATUS_ACCESS_DENIED;
1779 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1780 return NT_STATUS_ACCESS_DENIED;
1783 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1786 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1788 if (!NT_STATUS_IS_OK(nt_status)) {
1792 ret = pdb_getsampwsid(smbpass, user_sid);
1795 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1796 pdb_free_sam(&smbpass);
1797 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1800 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1802 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1803 pdb_free_sam(&smbpass);
1804 return NT_STATUS_ACCOUNT_DISABLED;
1808 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1810 pdb_free_sam(&smbpass);
1812 return NT_STATUS_OK;
1815 /*************************************************************************
1817 *************************************************************************/
1819 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1821 SAM_ACCOUNT *sampass=NULL;
1824 pdb_init_sam_talloc(mem_ctx, &sampass);
1827 ret = pdb_getsampwsid(sampass, user_sid);
1831 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1832 return NT_STATUS_NO_SUCH_USER;
1835 samr_clear_sam_passwd(sampass);
1837 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1840 init_sam_user_info20A(id20, sampass);
1842 pdb_free_sam(&sampass);
1844 return NT_STATUS_OK;
1847 /*************************************************************************
1849 *************************************************************************/
1851 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1852 DOM_SID *user_sid, DOM_SID *domain_sid)
1854 SAM_ACCOUNT *sampass=NULL;
1858 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1859 if (!NT_STATUS_IS_OK(nt_status)) {
1864 ret = pdb_getsampwsid(sampass, user_sid);
1868 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1869 return NT_STATUS_NO_SUCH_USER;
1872 samr_clear_sam_passwd(sampass);
1874 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1877 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1879 pdb_free_sam(&sampass);
1881 return NT_STATUS_OK;
1884 /*******************************************************************
1885 _samr_query_userinfo
1886 ********************************************************************/
1888 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1890 SAM_USERINFO_CTR *ctr;
1891 struct samr_info *info = NULL;
1895 r_u->status=NT_STATUS_OK;
1897 /* search for the handle */
1898 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1899 return NT_STATUS_INVALID_HANDLE;
1901 domain_sid = info->sid;
1903 sid_split_rid(&domain_sid, &rid);
1905 if (!sid_check_is_in_our_domain(&info->sid))
1906 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1908 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1910 ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1912 return NT_STATUS_NO_MEMORY;
1916 /* ok! user info levels (lots: see MSDEV help), off we go... */
1917 ctr->switch_value = q_u->switch_value;
1919 switch (q_u->switch_value) {
1921 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1922 if (ctr->info.id10 == NULL)
1923 return NT_STATUS_NO_MEMORY;
1925 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1930 /* whoops - got this wrong. i think. or don't understand what's happening. */
1934 info = (void *)&id11;
1936 expire.low = 0xffffffff;
1937 expire.high = 0x7fffffff;
1939 ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1944 ZERO_STRUCTP(ctr->info.id11);
1945 init_sam_user_info11(ctr->info.id11, &expire,
1946 "BROOKFIELDS$", /* name */
1947 0x03ef, /* user rid */
1948 0x201, /* group rid */
1949 0x0080); /* acb info */
1956 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1957 if (ctr->info.id12 == NULL)
1958 return NT_STATUS_NO_MEMORY;
1960 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1965 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1966 if (ctr->info.id20 == NULL)
1967 return NT_STATUS_NO_MEMORY;
1968 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1973 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1974 if (ctr->info.id21 == NULL)
1975 return NT_STATUS_NO_MEMORY;
1976 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1977 &info->sid, &domain_sid)))
1982 return NT_STATUS_INVALID_INFO_CLASS;
1985 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1987 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1992 /*******************************************************************
1993 samr_reply_query_usergroups
1994 ********************************************************************/
1996 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1998 SAM_ACCOUNT *sam_pass=NULL;
2000 DOM_GID *gids = NULL;
2006 * from the SID in the request:
2007 * we should send back the list of DOMAIN GROUPS
2008 * the user is a member of
2010 * and only the DOMAIN GROUPS
2011 * no ALIASES !!! neither aliases of the domain
2012 * nor aliases of the builtin SID
2017 r_u->status = NT_STATUS_OK;
2019 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2021 /* find the policy handle. open a policy on it. */
2022 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
2023 return NT_STATUS_INVALID_HANDLE;
2025 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
2029 if (!sid_check_is_in_our_domain(&sid))
2030 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2032 pdb_init_sam(&sam_pass);
2035 ret = pdb_getsampwsid(sam_pass, &sid);
2039 pdb_free_sam(&sam_pass);
2040 return NT_STATUS_NO_SUCH_USER;
2043 if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
2044 pdb_free_sam(&sam_pass);
2045 return NT_STATUS_NO_SUCH_GROUP;
2048 /* construct the response. lkclXXXX: gids are not copied! */
2049 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
2051 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2053 pdb_free_sam(&sam_pass);
2058 /*******************************************************************
2059 _samr_query_dom_info
2060 ********************************************************************/
2062 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2064 struct samr_info *info = NULL;
2066 uint32 min_pass_len,pass_hist,flag;
2067 time_t u_expire, u_min_age;
2068 NTTIME nt_expire, nt_min_age;
2070 time_t u_lock_duration, u_reset_time;
2071 NTTIME nt_lock_duration, nt_reset_time;
2077 uint32 account_policy_temp;
2079 uint32 num_users=0, num_groups=0, num_aliases=0;
2081 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
2082 return NT_STATUS_NO_MEMORY;
2086 r_u->status = NT_STATUS_OK;
2088 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2090 /* find the policy handle. open a policy on it. */
2091 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2092 return NT_STATUS_INVALID_HANDLE;
2094 switch (q_u->switch_value) {
2097 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2098 min_pass_len = account_policy_temp;
2100 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2101 pass_hist = account_policy_temp;
2103 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2104 flag = account_policy_temp;
2106 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2107 u_expire = account_policy_temp;
2109 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2110 u_min_age = account_policy_temp;
2112 unix_to_nt_time_abs(&nt_expire, u_expire);
2113 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2115 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2116 flag, nt_expire, nt_min_age);
2120 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2122 if (!NT_STATUS_IS_OK(r_u->status)) {
2123 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2126 num_users=info->disp_info.num_user_account;
2129 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2130 if (!NT_STATUS_IS_OK(r_u->status)) {
2131 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2134 num_groups=info->disp_info.num_group_account;
2137 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2138 init_unk_info2(&ctr->info.inf2, global_myworkgroup, global_myname, (uint32) time(NULL),
2139 num_users, num_groups, num_aliases);
2142 account_policy_get(AP_TIME_TO_LOGOUT, (int *)&u_logout);
2143 unix_to_nt_time_abs(&nt_logout, u_logout);
2145 init_unk_info3(&ctr->info.inf3, nt_logout);
2148 init_unk_info5(&ctr->info.inf5, global_myname);
2151 init_unk_info6(&ctr->info.inf6);
2154 init_unk_info7(&ctr->info.inf7);
2157 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2158 u_lock_duration = account_policy_temp;
2160 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2161 u_reset_time = account_policy_temp;
2163 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2164 lockout = account_policy_temp;
2166 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2167 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2169 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2172 return NT_STATUS_INVALID_INFO_CLASS;
2175 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2177 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2182 /*******************************************************************
2183 _api_samr_create_user
2184 Create an account, can be either a normal user or a machine.
2185 This funcion will need to be updated for bdc/domain trusts.
2186 ********************************************************************/
2188 NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2190 SAM_ACCOUNT *sam_pass=NULL;
2194 POLICY_HND dom_pol = q_u->domain_pol;
2195 UNISTR2 user_account = q_u->uni_name;
2196 uint16 acb_info = q_u->acb_info;
2197 POLICY_HND *user_pol = &r_u->user_pol;
2198 struct samr_info *info = NULL;
2207 /* Get the domain SID stored in the domain policy */
2208 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2209 return NT_STATUS_INVALID_HANDLE;
2211 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2215 /* find the account: tell the caller if it exists.
2216 lkclXXXX i have *no* idea if this is a problem or not
2217 or even if you are supposed to construct a different
2218 reply if the account already exists...
2221 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2224 pdb_init_sam(&sam_pass);
2227 ret = pdb_getsampwnam(sam_pass, account);
2230 /* this account exists: say so */
2231 pdb_free_sam(&sam_pass);
2232 return NT_STATUS_USER_EXISTS;
2235 pdb_free_sam(&sam_pass);
2238 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2239 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2240 * that only people with write access to the smbpasswd file will be able
2241 * to create a user. JRA.
2245 * add the user in the /etc/passwd file or the unix authority system.
2246 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2247 * a) local_password_change() checks for us if the /etc/passwd account really exists
2248 * b) smb_create_user() would return an error if the account already exists
2249 * and as it could return an error also if it can't create the account, it would be tricky.
2251 * So we go the easy way, only check after if the account exists.
2252 * JFM (2/3/2001), to clear any possible bad understanding (-:
2254 * We now have seperate script paramaters for adding users/machines so we
2255 * now have some sainity-checking to match.
2258 DEBUG(10,("checking account %s at pos %d for $ termination\n",account, strlen(account)-1));
2260 if ((acb_info & ACB_WSTRUST) && (account[strlen(account)-1] == '$')) {
2261 pstrcpy(add_script, lp_addmachine_script());
2262 } else if ((!(acb_info & ACB_WSTRUST)) && (account[strlen(account)-1] != '$')) {
2263 pstrcpy(add_script, lp_adduser_script());
2265 DEBUG(0, ("_api_samr_create_user: mismatch between trust flags and $ termination\n"));
2266 pdb_free_sam(&sam_pass);
2267 return NT_STATUS_UNSUCCESSFUL;
2272 * we can't check both the ending $ and the acb_info.
2274 * UserManager creates trust accounts (ending in $,
2275 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2278 if (account[strlen(account)-1] == '$')
2279 pstrcpy(add_script, lp_addmachine_script());
2281 pstrcpy(add_script, lp_adduser_script());
2285 all_string_sub(add_script, "%u", account, sizeof(account));
2286 add_ret = smbrun(add_script,NULL);
2287 DEBUG(3,("_api_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2290 pw = getpwnam_alloc(account);
2293 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sam_pass, pw))) {
2297 passwd_free(&pw); /* done with this now */
2299 DEBUG(3,("attempting to create non-unix account %s\n", account));
2301 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sam_pass))) {
2305 if (!pdb_set_username(sam_pass, account, PDB_CHANGED)) {
2306 pdb_free_sam(&sam_pass);
2307 return NT_STATUS_NO_MEMORY;
2311 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2313 if (!pdb_add_sam_account(sam_pass)) {
2314 pdb_free_sam(&sam_pass);
2315 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2317 return NT_STATUS_ACCESS_DENIED;
2320 pdb_reset_sam(sam_pass);
2322 if (!pdb_getsampwnam(sam_pass, account)) {
2323 pdb_free_sam(&sam_pass);
2324 DEBUG(0, ("could not find user/computer %s just added to passdb?!?\n",
2326 return NT_STATUS_ACCESS_DENIED;
2329 /* Get the user's SID */
2330 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2332 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2333 se_map_generic(&des_access, &usr_generic_mapping);
2334 if (!NT_STATUS_IS_OK(nt_status =
2335 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2336 des_access, &acc_granted, "_samr_create_user"))) {
2340 /* associate the user's SID with the new handle. */
2341 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2342 pdb_free_sam(&sam_pass);
2343 return NT_STATUS_NO_MEMORY;
2348 info->acc_granted = acc_granted;
2350 /* get a (unique) handle. open a policy on it. */
2351 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2352 pdb_free_sam(&sam_pass);
2353 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2356 r_u->user_rid=pdb_get_user_rid(sam_pass);
2358 r_u->access_granted = acc_granted;
2360 pdb_free_sam(&sam_pass);
2362 return NT_STATUS_OK;
2365 /*******************************************************************
2366 samr_reply_connect_anon
2367 ********************************************************************/
2369 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2371 struct samr_info *info = NULL;
2375 if (!pipe_access_check(p)) {
2376 DEBUG(3, ("access denied to samr_connect_anon\n"));
2377 r_u->status = NT_STATUS_ACCESS_DENIED;
2381 /* set up the SAMR connect_anon response */
2383 r_u->status = NT_STATUS_OK;
2385 /* associate the user's SID with the new handle. */
2386 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2387 return NT_STATUS_NO_MEMORY;
2389 info->status = q_u->unknown_0;
2391 /* get a (unique) handle. open a policy on it. */
2392 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2393 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2398 /*******************************************************************
2400 ********************************************************************/
2402 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2404 struct samr_info *info = NULL;
2405 SEC_DESC *psd = NULL;
2407 uint32 des_access = q_u->access_mask;
2412 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2416 if (!pipe_access_check(p)) {
2417 DEBUG(3, ("access denied to samr_connect\n"));
2418 r_u->status = NT_STATUS_ACCESS_DENIED;
2422 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2423 se_map_generic(&des_access, &sam_generic_mapping);
2424 if (!NT_STATUS_IS_OK(nt_status =
2425 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2426 des_access, &acc_granted, "_samr_connect"))) {
2430 r_u->status = NT_STATUS_OK;
2432 /* associate the user's SID and access granted with the new handle. */
2433 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2434 return NT_STATUS_NO_MEMORY;
2436 info->acc_granted = acc_granted;
2437 info->status = q_u->access_mask;
2439 /* get a (unique) handle. open a policy on it. */
2440 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2441 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2443 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2448 /*******************************************************************
2450 ********************************************************************/
2452 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2454 struct samr_info *info = NULL;
2455 SEC_DESC *psd = NULL;
2457 uint32 des_access = q_u->access_mask;
2462 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2466 if (!pipe_access_check(p)) {
2467 DEBUG(3, ("access denied to samr_connect4\n"));
2468 r_u->status = NT_STATUS_ACCESS_DENIED;
2472 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2473 se_map_generic(&des_access, &sam_generic_mapping);
2474 if (!NT_STATUS_IS_OK(nt_status =
2475 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2476 des_access, &acc_granted, "_samr_connect"))) {
2480 r_u->status = NT_STATUS_OK;
2482 /* associate the user's SID and access granted with the new handle. */
2483 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2484 return NT_STATUS_NO_MEMORY;
2486 info->acc_granted = acc_granted;
2487 info->status = q_u->access_mask;
2489 /* get a (unique) handle. open a policy on it. */
2490 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2491 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2493 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2498 /**********************************************************************
2499 api_samr_lookup_domain
2500 **********************************************************************/
2502 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2504 struct samr_info *info;
2505 fstring domain_name;
2508 r_u->status = NT_STATUS_OK;
2510 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2511 return NT_STATUS_INVALID_HANDLE;
2513 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain"))) {
2517 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2521 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2522 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2525 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2527 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2532 /******************************************************************
2533 makes a SAMR_R_ENUM_DOMAINS structure.
2534 ********************************************************************/
2536 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2537 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2543 DEBUG(5, ("make_enum_domains\n"));
2546 *pp_uni_name = NULL;
2548 if (num_sam_entries == 0)
2551 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2552 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2554 if (sam == NULL || uni_name == NULL)
2557 for (i = 0; i < num_sam_entries; i++) {
2558 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
2560 init_sam_entry(&sam[i], len, 0);
2561 init_unistr2(&uni_name[i], doms[i], len);
2565 *pp_uni_name = uni_name;
2570 /**********************************************************************
2571 api_samr_enum_domains
2572 **********************************************************************/
2574 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2576 struct samr_info *info;
2577 uint32 num_entries = 2;
2581 r_u->status = NT_STATUS_OK;
2583 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2584 return NT_STATUS_INVALID_HANDLE;
2586 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2590 switch (lp_server_role()) {
2591 case ROLE_DOMAIN_PDC:
2592 case ROLE_DOMAIN_BDC:
2593 name = global_myworkgroup;
2596 name = global_myname;
2599 fstrcpy(dom[0],name);
2601 fstrcpy(dom[1],"Builtin");
2603 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2604 return NT_STATUS_NO_MEMORY;
2606 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2611 /*******************************************************************
2613 ********************************************************************/
2615 NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2618 POLICY_HND domain_pol = q_u->dom_pol;
2619 uint32 alias_rid = q_u->rid_alias;
2620 POLICY_HND *alias_pol = &r_u->pol;
2621 struct samr_info *info = NULL;
2622 SEC_DESC *psd = NULL;
2624 uint32 des_access = q_u->access_mask;
2628 r_u->status = NT_STATUS_OK;
2630 /* find the domain policy and get the SID / access bits stored in the domain policy */
2631 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2632 return NT_STATUS_INVALID_HANDLE;
2634 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2638 /* append the alias' RID to it */
2639 if (!sid_append_rid(&sid, alias_rid))
2640 return NT_STATUS_NO_SUCH_USER;
2642 /*check if access can be granted as requested by client. */
2643 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2644 se_map_generic(&des_access,&ali_generic_mapping);
2645 if (!NT_STATUS_IS_OK(status =
2646 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2647 des_access, &acc_granted, "_samr_open_alias"))) {
2652 * we should check if the rid really exist !!!
2656 /* associate the user's SID with the new handle. */
2657 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2658 return NT_STATUS_NO_MEMORY;
2660 info->acc_granted = acc_granted;
2662 /* get a (unique) handle. open a policy on it. */
2663 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2664 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2669 /*******************************************************************
2671 ********************************************************************/
2673 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2675 SAM_ACCOUNT *pwd =NULL;
2680 ret = pdb_getsampwsid(pwd, sid);
2688 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2693 /* FIX ME: check if the value is really changed --metze */
2694 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2699 if(!pdb_update_sam_account(pwd)) {
2709 /*******************************************************************
2711 ********************************************************************/
2713 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2715 SAM_ACCOUNT *pwd = NULL;
2719 if(!pdb_getsampwsid(pwd, sid)) {
2725 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2730 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2734 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2738 if (!pdb_set_pass_changed_now (pwd)) {
2743 if(!pdb_update_sam_account(pwd)) {
2752 /*******************************************************************
2754 ********************************************************************/
2756 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2758 SAM_ACCOUNT *pwd = NULL;
2761 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2767 if (!pdb_getsampwsid(pwd, sid)) {
2772 copy_id21_to_sam_passwd(pwd, id21);
2775 * The funny part about the previous two calls is
2776 * that pwd still has the password hashes from the
2777 * passdb entry. These have not been updated from
2778 * id21. I don't know if they need to be set. --jerry
2781 /* write the change out */
2782 if(!pdb_update_sam_account(pwd)) {
2792 /*******************************************************************
2794 ********************************************************************/
2796 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2798 SAM_ACCOUNT *pwd = NULL;
2799 pstring plaintext_buf;
2804 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2810 if (!pdb_getsampwsid(pwd, sid)) {
2815 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2816 pdb_get_username(pwd)));
2818 acct_ctrl = pdb_get_acct_ctrl(pwd);
2820 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
2825 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2830 copy_id23_to_sam_passwd(pwd, id23);
2832 /* if it's a trust account, don't update /etc/passwd */
2833 if ( (!IS_SAM_UNIX_USER(pwd)) ||
2834 ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2835 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2836 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2837 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2839 /* update the UNIX password */
2840 if (lp_unix_password_sync() )
2841 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2847 ZERO_STRUCT(plaintext_buf);
2849 if(!pdb_update_sam_account(pwd)) {
2859 /*******************************************************************
2861 ********************************************************************/
2863 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2865 SAM_ACCOUNT *pwd = NULL;
2867 pstring plaintext_buf;
2872 if (!pdb_getsampwsid(pwd, sid)) {
2877 DEBUG(5, ("Attempting administrator password change for user %s\n",
2878 pdb_get_username(pwd)));
2880 acct_ctrl = pdb_get_acct_ctrl(pwd);
2882 ZERO_STRUCT(plaintext_buf);
2884 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) {
2889 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2894 /* if it's a trust account, don't update /etc/passwd */
2895 if ( (!IS_SAM_UNIX_USER(pwd)) ||
2896 ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2897 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2898 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2899 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2901 /* update the UNIX password */
2902 if (lp_unix_password_sync()) {
2903 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2910 ZERO_STRUCT(plaintext_buf);
2912 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2914 /* update the SAMBA password */
2915 if(!pdb_update_sam_account(pwd)) {
2925 /*******************************************************************
2926 samr_reply_set_userinfo
2927 ********************************************************************/
2929 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2932 POLICY_HND *pol = &q_u->pol;
2933 uint16 switch_value = q_u->switch_value;
2934 SAM_USERINFO_CTR *ctr = q_u->ctr;
2936 uint32 acc_required;
2938 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2940 r_u->status = NT_STATUS_OK;
2942 /* find the policy handle. open a policy on it. */
2943 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2944 return NT_STATUS_INVALID_HANDLE;
2946 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
2947 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2951 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
2954 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2955 return NT_STATUS_INVALID_INFO_CLASS;
2958 /* ok! user info levels (lots: see MSDEV help), off we go... */
2959 switch (switch_value) {
2961 if (!set_user_info_12(ctr->info.id12, &sid))
2962 return NT_STATUS_ACCESS_DENIED;
2966 SamOEMhash(ctr->info.id24->pass, p->session_key, 516);
2968 dump_data(100, (char *)ctr->info.id24->pass, 516);
2970 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
2971 return NT_STATUS_ACCESS_DENIED;
2977 * Currently we don't really know how to unmarshall
2978 * the level 25 struct, and the password encryption
2979 * is different. This is a placeholder for when we
2980 * do understand it. In the meantime just return INVALID
2981 * info level and W2K SP2 drops down to level 23... JRA.
2984 SamOEMhash(ctr->info.id25->pass, p->session_key, 532);
2986 dump_data(100, (char *)ctr->info.id25->pass, 532);
2988 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
2989 return NT_STATUS_ACCESS_DENIED;
2992 return NT_STATUS_INVALID_INFO_CLASS;
2995 SamOEMhash(ctr->info.id23->pass, p->session_key, 516);
2997 dump_data(100, (char *)ctr->info.id23->pass, 516);
2999 if (!set_user_info_23(ctr->info.id23, &sid))
3000 return NT_STATUS_ACCESS_DENIED;
3004 return NT_STATUS_INVALID_INFO_CLASS;
3010 /*******************************************************************
3011 samr_reply_set_userinfo2
3012 ********************************************************************/
3014 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3017 SAM_USERINFO_CTR *ctr = q_u->ctr;
3018 POLICY_HND *pol = &q_u->pol;
3019 uint16 switch_value = q_u->switch_value;
3021 uint32 acc_required;
3023 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3025 r_u->status = NT_STATUS_OK;
3027 /* find the policy handle. open a policy on it. */
3028 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3029 return NT_STATUS_INVALID_HANDLE;
3031 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3032 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3036 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3039 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3040 return NT_STATUS_INVALID_INFO_CLASS;
3043 switch_value=ctr->switch_value;
3045 /* ok! user info levels (lots: see MSDEV help), off we go... */
3046 switch (switch_value) {
3048 if (!set_user_info_21(ctr->info.id21, &sid))
3049 return NT_STATUS_ACCESS_DENIED;
3052 if (!set_user_info_10(ctr->info.id10, &sid))
3053 return NT_STATUS_ACCESS_DENIED;
3056 /* Used by AS/U JRA. */
3057 if (!set_user_info_12(ctr->info.id12, &sid))
3058 return NT_STATUS_ACCESS_DENIED;
3061 return NT_STATUS_INVALID_INFO_CLASS;
3067 /*********************************************************************
3068 _samr_query_aliasmem
3069 *********************************************************************/
3071 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3073 int num_groups = 0, tmp_num_groups=0;
3074 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3075 struct samr_info *info = NULL;
3081 /* until i see a real useraliases query, we fack one up */
3083 /* I have seen one, JFM 2/12/2001 */
3085 * Explanation of what this call does:
3086 * for all the SID given in the request:
3087 * return a list of alias (local groups)
3088 * that have those SID as members.
3090 * and that's the alias in the domain specified
3091 * in the policy_handle
3093 * if the policy handle is on an incorrect sid
3094 * for example a user's sid
3095 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3098 r_u->status = NT_STATUS_OK;
3100 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3102 /* find the policy handle. open a policy on it. */
3103 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3104 return NT_STATUS_INVALID_HANDLE;
3106 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3107 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3109 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3110 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3111 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3112 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3116 if (!sid_check_is_domain(&info->sid) &&
3117 !sid_check_is_builtin(&info->sid))
3118 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3121 for (i=0; i<q_u->num_sids1; i++) {
3123 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3126 * if there is an error, we just continue as
3127 * it can be an unfound user or group
3129 if (!NT_STATUS_IS_OK(r_u->status)) {
3130 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3134 if (tmp_num_groups==0) {
3135 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3139 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3140 if (new_rids==NULL) {
3141 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3142 return NT_STATUS_NO_MEMORY;
3146 for (j=0; j<tmp_num_groups; j++)
3147 rids[j+num_groups]=tmp_rids[j];
3149 safe_free(tmp_rids);
3151 num_groups+=tmp_num_groups;
3154 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3155 return NT_STATUS_OK;
3158 /*********************************************************************
3159 _samr_query_aliasmem
3160 *********************************************************************/
3162 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3174 fstring alias_sid_str;
3177 SAM_ACCOUNT *sam_user = NULL;
3181 /* find the policy handle. open a policy on it. */
3182 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3183 return NT_STATUS_INVALID_HANDLE;
3185 if (!NT_STATUS_IS_OK(r_u->status =
3186 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3190 sid_copy(&als_sid, &alias_sid);
3191 sid_to_string(alias_sid_str, &alias_sid);
3192 sid_split_rid(&alias_sid, &alias_rid);
3194 DEBUG(10, ("sid is %s\n", alias_sid_str));
3196 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
3197 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3198 if(!get_builtin_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
3199 return NT_STATUS_NO_SUCH_ALIAS;
3201 if (sid_equal(&alias_sid, get_global_sam_sid())) {
3202 DEBUG(10, ("lookup on Server SID\n"));
3203 if(!get_local_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
3204 return NT_STATUS_NO_SUCH_ALIAS;
3208 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3209 return NT_STATUS_NO_SUCH_ALIAS;
3211 DEBUG(10, ("sid is %s\n", alias_sid_str));
3212 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
3213 if (num_uids!=0 && sid == NULL)
3214 return NT_STATUS_NO_MEMORY;
3216 for (i = 0; i < num_uids; i++) {
3217 struct passwd *pass;
3220 sid_copy(&temp_sid, get_global_sam_sid());
3222 pass = getpwuid_alloc(uid[i]);
3223 if (!pass) continue;
3225 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3231 check = pdb_getsampwnam(sam_user, pass->pw_name);
3234 if (check != True) {
3235 pdb_free_sam(&sam_user);
3240 rid = pdb_get_user_rid(sam_user);
3242 pdb_free_sam(&sam_user);
3247 pdb_free_sam(&sam_user);
3250 sid_append_rid(&temp_sid, rid);
3252 init_dom_sid2(&sid[i], &temp_sid);
3255 DEBUG(10, ("sid is %s\n", alias_sid_str));
3256 init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
3258 return NT_STATUS_OK;
3261 /*********************************************************************
3262 _samr_query_groupmem
3263 *********************************************************************/
3265 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3271 fstring group_sid_str;
3279 SAM_ACCOUNT *sam_user = NULL;
3283 /* find the policy handle. open a policy on it. */
3284 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3285 return NT_STATUS_INVALID_HANDLE;
3287 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3291 /* todo: change to use sid_compare_front */
3293 sid_split_rid(&group_sid, &group_rid);
3294 sid_to_string(group_sid_str, &group_sid);
3295 DEBUG(10, ("sid is %s\n", group_sid_str));
3297 /* can we get a query for an SID outside our domain ? */
3298 if (!sid_equal(&group_sid, get_global_sam_sid()))
3299 return NT_STATUS_NO_SUCH_GROUP;
3301 sid_append_rid(&group_sid, group_rid);
3302 DEBUG(10, ("lookup on Domain SID\n"));
3304 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3305 return NT_STATUS_NO_SUCH_GROUP;
3307 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3308 return NT_STATUS_NO_SUCH_GROUP;
3310 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3311 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3313 if (num_uids!=0 && (rid==NULL || attr==NULL))
3314 return NT_STATUS_NO_MEMORY;
3316 for (i=0; i<num_uids; i++) {
3317 struct passwd *pass;
3320 pass = getpwuid_alloc(uid[i]);
3321 if (!pass) continue;
3323 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3329 check = pdb_getsampwnam(sam_user, pass->pw_name);
3332 if (check != True) {
3333 pdb_free_sam(&sam_user);
3338 urid = pdb_get_user_rid(sam_user);
3340 pdb_free_sam(&sam_user);
3345 pdb_free_sam(&sam_user);
3349 attr[i] = SID_NAME_USER;
3352 init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
3354 return NT_STATUS_OK;
3357 /*********************************************************************
3359 *********************************************************************/
3361 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3364 fstring alias_sid_str;
3371 SAM_ACCOUNT *sam_user = NULL;
3375 /* Find the policy handle. Open a policy on it. */
3376 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3377 return NT_STATUS_INVALID_HANDLE;
3379 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3383 sid_to_string(alias_sid_str, &alias_sid);
3384 DEBUG(10, ("sid is %s\n", alias_sid_str));
3386 if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
3387 DEBUG(10, ("adding member on Server SID\n"));
3388 if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3389 return NT_STATUS_NO_SUCH_ALIAS;
3392 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
3393 DEBUG(10, ("adding member on BUILTIN SID\n"));
3394 if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3395 return NT_STATUS_NO_SUCH_ALIAS;
3398 return NT_STATUS_NO_SUCH_ALIAS;
3401 ret = pdb_init_sam(&sam_user);
3402 if (!NT_STATUS_IS_OK(ret))
3405 check = pdb_getsampwsid(sam_user, &q_u->sid.sid);
3407 if (check != True) {
3408 pdb_free_sam(&sam_user);
3409 return NT_STATUS_NO_SUCH_USER;
3412 uid = pdb_get_uid(sam_user);
3414 pdb_free_sam(&sam_user);
3415 return NT_STATUS_NO_SUCH_USER;
3418 pdb_free_sam(&sam_user);
3420 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3421 return NT_STATUS_NO_SUCH_USER;
3424 if ((grp=getgrgid(map.gid)) == NULL) {
3426 return NT_STATUS_NO_SUCH_ALIAS;
3429 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3430 fstrcpy(grp_name, grp->gr_name);
3432 /* if the user is already in the group */
3433 if(user_in_group_list(pwd->pw_name, grp_name)) {
3435 return NT_STATUS_MEMBER_IN_ALIAS;
3439 * ok, the group exist, the user exist, the user is not in the group,
3440 * we can (finally) add it to the group !
3442 smb_add_user_group(grp_name, pwd->pw_name);
3444 /* check if the user has been added then ... */
3445 if(!user_in_group_list(pwd->pw_name, grp_name)) {
3447 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3451 return NT_STATUS_OK;
3454 /*********************************************************************
3456 *********************************************************************/
3458 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3461 fstring alias_sid_str;
3465 SAM_ACCOUNT *sam_pass=NULL;
3468 /* Find the policy handle. Open a policy on it. */
3469 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3470 return NT_STATUS_INVALID_HANDLE;
3472 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3476 sid_to_string(alias_sid_str, &alias_sid);
3477 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
3479 if (!sid_check_is_in_our_domain(&alias_sid) &&
3480 !sid_check_is_in_builtin(&alias_sid)) {
3481 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3482 return NT_STATUS_NO_SUCH_ALIAS;
3485 if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3486 return NT_STATUS_NO_SUCH_ALIAS;
3488 if ((grp=getgrgid(map.gid)) == NULL)
3489 return NT_STATUS_NO_SUCH_ALIAS;
3491 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3492 fstrcpy(grp_name, grp->gr_name);
3494 /* check if the user exists before trying to remove it from the group */
3495 pdb_init_sam(&sam_pass);
3496 if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
3497 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3498 pdb_free_sam(&sam_pass);
3499 return NT_STATUS_NO_SUCH_USER;
3502 /* if the user is not in the group */
3503 if(!user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
3504 pdb_free_sam(&sam_pass);
3505 return NT_STATUS_MEMBER_IN_ALIAS;
3508 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3510 /* check if the user has been removed then ... */
3511 if(user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
3512 pdb_free_sam(&sam_pass);
3513 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3516 pdb_free_sam(&sam_pass);
3517 return NT_STATUS_OK;
3520 /*********************************************************************
3522 *********************************************************************/
3524 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3528 fstring group_sid_str;
3535 SAM_ACCOUNT *sam_user=NULL;
3539 /* Find the policy handle. Open a policy on it. */
3540 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3541 return NT_STATUS_INVALID_HANDLE;
3543 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3547 sid_to_string(group_sid_str, &group_sid);
3548 DEBUG(10, ("sid is %s\n", group_sid_str));
3550 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3551 return NT_STATUS_NO_SUCH_GROUP;
3553 DEBUG(10, ("lookup on Domain SID\n"));
3555 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3556 return NT_STATUS_NO_SUCH_GROUP;
3558 sid_copy(&user_sid, get_global_sam_sid());
3559 sid_append_rid(&user_sid, q_u->rid);
3561 ret = pdb_init_sam(&sam_user);
3562 if (!NT_STATUS_IS_OK(ret))
3565 check = pdb_getsampwsid(sam_user, &user_sid);
3567 if (check != True) {
3568 pdb_free_sam(&sam_user);
3569 return NT_STATUS_NO_SUCH_USER;
3572 uid = pdb_get_uid(sam_user);
3574 pdb_free_sam(&sam_user);
3575 return NT_STATUS_NO_SUCH_USER;
3578 pdb_free_sam(&sam_user);
3580 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3581 return NT_STATUS_NO_SUCH_USER;
3584 if ((grp=getgrgid(map.gid)) == NULL) {
3586 return NT_STATUS_NO_SUCH_GROUP;
3589 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3590 fstrcpy(grp_name, grp->gr_name);
3592 /* if the user is already in the group */
3593 if(user_in_group_list(pwd->pw_name, grp_name)) {
3595 return NT_STATUS_MEMBER_IN_GROUP;
3599 * ok, the group exist, the user exist, the user is not in the group,
3601 * we can (finally) add it to the group !
3604 smb_add_user_group(grp_name, pwd->pw_name);
3606 /* check if the user has been added then ... */
3607 if(!user_in_group_list(pwd->pw_name, grp_name)) {
3609 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3613 return NT_STATUS_OK;
3616 /*********************************************************************
3618 *********************************************************************/
3620 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3624 SAM_ACCOUNT *sam_pass=NULL;
3631 * delete the group member named q_u->rid
3632 * who is a member of the sid associated with the handle
3633 * the rid is a user's rid as the group is a domain group.
3636 /* Find the policy handle. Open a policy on it. */
3637 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3638 return NT_STATUS_INVALID_HANDLE;
3640 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3644 if (!sid_check_is_in_our_domain(&group_sid))
3645 return NT_STATUS_NO_SUCH_GROUP;
3647 sid_copy(&user_sid, get_global_sam_sid());
3648 sid_append_rid(&user_sid, q_u->rid);
3650 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3651 return NT_STATUS_NO_SUCH_GROUP;
3653 if ((grp=getgrgid(map.gid)) == NULL)
3654 return NT_STATUS_NO_SUCH_GROUP;
3656 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3657 fstrcpy(grp_name, grp->gr_name);
3659 /* check if the user exists before trying to remove it from the group */
3660 pdb_init_sam(&sam_pass);
3661 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3662 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3663 pdb_free_sam(&sam_pass);
3664 return NT_STATUS_NO_SUCH_USER;
3667 /* if the user is not in the group */
3668 if (!user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
3669 pdb_free_sam(&sam_pass);
3670 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3673 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3675 /* check if the user has been removed then ... */
3676 if (user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
3677 pdb_free_sam(&sam_pass);
3678 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3681 pdb_free_sam(&sam_pass);
3682 return NT_STATUS_OK;
3686 /****************************************************************************
3687 Delete a UNIX user on demand.
3688 ****************************************************************************/
3690 static int smb_delete_user(const char *unix_user)
3695 pstrcpy(del_script, lp_deluser_script());
3698 all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3699 ret = smbrun(del_script,NULL);
3700 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3704 /*********************************************************************
3705 _samr_delete_dom_user
3706 *********************************************************************/
3708 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3711 SAM_ACCOUNT *sam_pass=NULL;
3714 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3716 /* Find the policy handle. Open a policy on it. */
3717 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3718 return NT_STATUS_INVALID_HANDLE;
3720 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3724 if (!sid_check_is_in_our_domain(&user_sid))
3725 return NT_STATUS_CANNOT_DELETE;
3727 /* check if the user exists before trying to delete */
3728 pdb_init_sam(&sam_pass);
3729 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3730 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3731 pdb_free_sam(&sam_pass);
3732 return NT_STATUS_NO_SUCH_USER;
3735 /* delete the unix side */
3737 * note: we don't check if the delete really happened
3738 * as the script is not necessary present
3739 * and maybe the sysadmin doesn't want to delete the unix side
3741 smb_delete_user(pdb_get_username(sam_pass));
3743 /* and delete the samba side */
3744 if (!pdb_delete_sam_account(sam_pass)) {
3745 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3746 pdb_free_sam(&sam_pass);
3747 return NT_STATUS_CANNOT_DELETE;
3750 pdb_free_sam(&sam_pass);
3752 if (!close_policy_hnd(p, &q_u->user_pol))
3753 return NT_STATUS_OBJECT_NAME_INVALID;
3755 return NT_STATUS_OK;
3758 /*********************************************************************
3759 _samr_delete_dom_group
3760 *********************************************************************/
3762 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3767 fstring group_sid_str;
3773 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3775 /* Find the policy handle. Open a policy on it. */
3776 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3777 return NT_STATUS_INVALID_HANDLE;
3779 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3783 sid_copy(&dom_sid, &group_sid);
3784 sid_to_string(group_sid_str, &dom_sid);
3785 sid_split_rid(&dom_sid, &group_rid);
3787 DEBUG(10, ("sid is %s\n", group_sid_str));
3789 /* we check if it's our SID before deleting */
3790 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3791 return NT_STATUS_NO_SUCH_GROUP;
3793 DEBUG(10, ("lookup on Domain SID\n"));
3795 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3796 return NT_STATUS_NO_SUCH_GROUP;
3800 /* check if group really exists */
3801 if ( (grp=getgrgid(gid)) == NULL)
3802 return NT_STATUS_NO_SUCH_GROUP;
3804 /* we can delete the UNIX group */
3805 smb_delete_group(grp->gr_name);
3807 /* check if the group has been successfully deleted */
3808 if ( (grp=getgrgid(gid)) != NULL)
3809 return NT_STATUS_ACCESS_DENIED;
3811 if(!pdb_delete_group_mapping_entry(group_sid))
3812 return NT_STATUS_ACCESS_DENIED;
3814 if (!close_policy_hnd(p, &q_u->group_pol))
3815 return NT_STATUS_OBJECT_NAME_INVALID;
3817 return NT_STATUS_OK;
3820 /*********************************************************************
3821 _samr_delete_dom_alias
3822 *********************************************************************/
3824 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3829 fstring alias_sid_str;
3835 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3837 /* Find the policy handle. Open a policy on it. */
3838 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3839 return NT_STATUS_INVALID_HANDLE;
3841 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3845 sid_copy(&dom_sid, &alias_sid);
3846 sid_to_string(alias_sid_str, &dom_sid);
3847 sid_split_rid(&dom_sid, &alias_rid);
3849 DEBUG(10, ("sid is %s\n", alias_sid_str));
3851 /* we check if it's our SID before deleting */
3852 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3853 return NT_STATUS_NO_SUCH_ALIAS;
3855 DEBUG(10, ("lookup on Local SID\n"));
3857 if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3858 return NT_STATUS_NO_SUCH_ALIAS;
3862 /* check if group really exists */
3863 if ( (grp=getgrgid(gid)) == NULL)
3864 return NT_STATUS_NO_SUCH_ALIAS;
3866 /* we can delete the UNIX group */
3867 smb_delete_group(grp->gr_name);
3869 /* check if the group has been successfully deleted */
3870 if ( (grp=getgrgid(gid)) != NULL)
3871 return NT_STATUS_ACCESS_DENIED;
3873 /* don't check if we removed it as it could be an un-mapped group */
3874 pdb_delete_group_mapping_entry(alias_sid);
3876 if (!close_policy_hnd(p, &q_u->alias_pol))
3877 return NT_STATUS_OBJECT_NAME_INVALID;
3879 return NT_STATUS_OK;
3882 /*********************************************************************
3883 _samr_create_dom_group
3884 *********************************************************************/
3886 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3893 struct samr_info *info;
3894 PRIVILEGE_SET priv_set;
3898 init_privilege(&priv_set);
3900 /* Find the policy handle. Open a policy on it. */
3901 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3902 return NT_STATUS_INVALID_HANDLE;
3904 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3908 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3909 return NT_STATUS_ACCESS_DENIED;
3911 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3913 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3915 /* check if group already exist */
3916 if ((grp=getgrnam(name)) != NULL)
3917 return NT_STATUS_GROUP_EXISTS;
3919 /* we can create the UNIX group */
3920 if (smb_create_group(name, &gid) != 0)
3921 return NT_STATUS_ACCESS_DENIED;
3923 /* check if the group has been successfully created */
3924 if ((grp=getgrgid(gid)) == NULL)
3925 return NT_STATUS_ACCESS_DENIED;
3927 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3929 /* add the group to the mapping table */
3930 sid_copy(&info_sid, get_global_sam_sid());
3931 sid_append_rid(&info_sid, r_u->rid);
3932 sid_to_string(sid_string, &info_sid);
3934 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
3935 return NT_STATUS_ACCESS_DENIED;
3937 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3938 return NT_STATUS_NO_MEMORY;
3940 /* get a (unique) handle. open a policy on it. */
3941 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3942 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3944 return NT_STATUS_OK;
3947 /*********************************************************************
3948 _samr_create_dom_alias
3949 *********************************************************************/
3951 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3958 struct samr_info *info;
3959 PRIVILEGE_SET priv_set;
3963 init_privilege(&priv_set);
3965 /* Find the policy handle. Open a policy on it. */
3966 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
3967 return NT_STATUS_INVALID_HANDLE;
3969 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3973 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3974 return NT_STATUS_ACCESS_DENIED;
3976 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3978 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3980 /* check if group already exists */
3981 if ( (grp=getgrnam(name)) != NULL)
3982 return NT_STATUS_GROUP_EXISTS;
3984 /* we can create the UNIX group */
3985 if (smb_create_group(name, &gid) != 0)
3986 return NT_STATUS_ACCESS_DENIED;
3988 /* check if the group has been successfully created */
3989 if ((grp=getgrgid(gid)) == NULL)
3990 return NT_STATUS_ACCESS_DENIED;
3992 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3994 sid_copy(&info_sid, get_global_sam_sid());
3995 sid_append_rid(&info_sid, r_u->rid);
3996 sid_to_string(sid_string, &info_sid);
3998 /* add the group to the mapping table */
3999 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
4000 return NT_STATUS_ACCESS_DENIED;
4002 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4003 return NT_STATUS_NO_MEMORY;
4005 /* get a (unique) handle. open a policy on it. */
4006 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4007 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4009 return NT_STATUS_OK;
4012 /*********************************************************************
4013 _samr_query_groupinfo
4015 sends the name/comment pair of a domain group
4016 level 1 send also the number of users of that group
4017 *********************************************************************/
4019 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4025 GROUP_INFO_CTR *ctr;
4028 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4029 return NT_STATUS_INVALID_HANDLE;
4031 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4035 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
4036 return NT_STATUS_INVALID_HANDLE;
4038 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
4040 return NT_STATUS_NO_MEMORY;
4042 switch (q_u->switch_level) {
4044 ctr->switch_value1 = 1;
4045 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
4046 return NT_STATUS_NO_SUCH_GROUP;
4047 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
4051 ctr->switch_value1 = 3;
4052 init_samr_group_info3(&ctr->group.info3);
4055 ctr->switch_value1 = 4;
4056 init_samr_group_info4(&ctr->group.info4, map.comment);
4059 return NT_STATUS_INVALID_INFO_CLASS;
4062 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4064 return NT_STATUS_OK;
4067 /*********************************************************************
4070 update a domain group's comment.
4071 *********************************************************************/
4073 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4077 GROUP_INFO_CTR *ctr;
4080 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4081 return NT_STATUS_INVALID_HANDLE;
4083 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4087 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
4088 return NT_STATUS_NO_SUCH_GROUP;
4092 switch (ctr->switch_value1) {
4094 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4097 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4100 free_privilege(&map.priv_set);
4101 return NT_STATUS_INVALID_INFO_CLASS;
4104 if(!pdb_update_group_mapping_entry(&map)) {
4105 free_privilege(&map.priv_set);
4106 return NT_STATUS_NO_SUCH_GROUP;
4109 free_privilege(&map.priv_set);
4111 return NT_STATUS_OK;
4114 /*********************************************************************
4117 update an alias's comment.
4118 *********************************************************************/
4120 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4124 ALIAS_INFO_CTR *ctr;
4127 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4128 return NT_STATUS_INVALID_HANDLE;
4130 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4134 if (!get_local_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
4135 return NT_STATUS_NO_SUCH_GROUP;
4139 switch (ctr->switch_value1) {
4141 unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
4144 free_privilege(&map.priv_set);
4145 return NT_STATUS_INVALID_INFO_CLASS;
4148 if(!pdb_update_group_mapping_entry(&map)) {
4149 free_privilege(&map.priv_set);
4150 return NT_STATUS_NO_SUCH_GROUP;
4153 free_privilege(&map.priv_set);
4155 return NT_STATUS_OK;
4158 /*********************************************************************
4159 _samr_get_dom_pwinfo
4160 *********************************************************************/
4162 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4164 /* Perform access check. Since this rpc does not require a
4165 policy handle it will not be caught by the access checks on
4166 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4168 if (!pipe_access_check(p)) {
4169 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4170 r_u->status = NT_STATUS_ACCESS_DENIED;
4174 /* Actually, returning zeros here works quite well :-). */
4176 return NT_STATUS_OK;
4179 /*********************************************************************
4181 *********************************************************************/
4183 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4188 struct samr_info *info;
4189 SEC_DESC *psd = NULL;
4196 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4197 return NT_STATUS_INVALID_HANDLE;
4199 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4203 /*check if access can be granted as requested by client. */
4204 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4205 se_map_generic(&des_access,&grp_generic_mapping);
4206 if (!NT_STATUS_IS_OK(status =
4207 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4208 des_access, &acc_granted, "_samr_open_group"))) {
4213 /* this should not be hard-coded like this */
4214 if (!sid_equal(&sid, get_global_sam_sid()))
4215 return NT_STATUS_ACCESS_DENIED;
4217 sid_copy(&info_sid, get_global_sam_sid());
4218 sid_append_rid(&info_sid, q_u->rid_group);
4219 sid_to_string(sid_string, &info_sid);
4221 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4222 return NT_STATUS_NO_MEMORY;
4224 info->acc_granted = acc_granted;
4226 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4228 /* check if that group really exists */
4229 if (!get_domain_group_from_sid(info->sid, &map, MAPPING_WITHOUT_PRIV))
4230 return NT_STATUS_NO_SUCH_GROUP;
4232 /* get a (unique) handle. open a policy on it. */
4233 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4234 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4236 return NT_STATUS_OK;
4239 /*********************************************************************
4241 *********************************************************************/
4243 NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
4245 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
4246 return NT_STATUS_NOT_IMPLEMENTED;
4249 /*******************************************************************
4251 ********************************************************************/
4253 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4255 struct samr_info *info = NULL;
4257 uint32 min_pass_len,pass_hist,flag;
4258 time_t u_expire, u_min_age;
4259 NTTIME nt_expire, nt_min_age;
4261 time_t u_lock_duration, u_reset_time;
4262 NTTIME nt_lock_duration, nt_reset_time;
4268 uint32 num_users=0, num_groups=0, num_aliases=0;
4270 uint32 account_policy_temp;
4272 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4273 return NT_STATUS_NO_MEMORY;
4277 r_u->status = NT_STATUS_OK;
4279 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4281 /* find the policy handle. open a policy on it. */
4282 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4283 return NT_STATUS_INVALID_HANDLE;
4285 switch (q_u->switch_value) {
4287 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4288 min_pass_len = account_policy_temp;
4290 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4291 pass_hist = account_policy_temp;
4293 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4294 flag = account_policy_temp;
4296 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4297 u_expire = account_policy_temp;
4299 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4300 u_min_age = account_policy_temp;
4302 unix_to_nt_time_abs(&nt_expire, u_expire);
4303 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4305 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4306 flag, nt_expire, nt_min_age);
4310 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4312 if (!NT_STATUS_IS_OK(r_u->status)) {
4313 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4316 num_users=info->disp_info.num_user_account;
4319 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4320 if (NT_STATUS_IS_ERR(r_u->status)) {
4321 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4324 num_groups=info->disp_info.num_group_account;
4327 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4328 init_unk_info2(&ctr->info.inf2, global_myworkgroup, global_myname, (uint32) time(NULL),
4329 num_users, num_groups, num_aliases);
4332 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4333 u_logout = account_policy_temp;
4335 unix_to_nt_time_abs(&nt_logout, u_logout);
4337 init_unk_info3(&ctr->info.inf3, nt_logout);
4340 init_unk_info5(&ctr->info.inf5, global_myname);
4343 init_unk_info6(&ctr->info.inf6);
4346 init_unk_info7(&ctr->info.inf7);
4349 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4350 u_lock_duration = account_policy_temp;
4352 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4353 u_reset_time = account_policy_temp;
4355 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4356 lockout = account_policy_temp;
4358 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4359 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4361 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4364 return NT_STATUS_INVALID_INFO_CLASS;
4367 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4369 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4374 /*******************************************************************
4376 ********************************************************************/
4378 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4380 time_t u_expire, u_min_age;
4382 time_t u_lock_duration, u_reset_time;
4384 r_u->status = NT_STATUS_OK;
4386 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4388 /* find the policy handle. open a policy on it. */
4389 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4390 return NT_STATUS_INVALID_HANDLE;
4392 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4394 switch (q_u->switch_value) {
4396 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4397 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4399 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4400 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4401 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4402 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4403 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4408 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4409 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4418 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4419 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count);
4421 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4422 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4423 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4426 return NT_STATUS_INVALID_INFO_CLASS;
4429 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4431 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));