2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2002,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Anthony Liguori 2002,
11 * Copyright (C) Jim McDonough 2002.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 * This is the implementation of the SAMR code.
35 #define DBGC_CLASS DBGC_RPC_SRV
37 extern DOM_SID global_sid_Builtin;
39 extern rid_name domain_group_rids[];
40 extern rid_name domain_alias_rids[];
41 extern rid_name builtin_alias_rids[];
44 typedef struct _disp_info {
46 uint32 num_user_account;
47 DISP_USER_INFO *disp_user_info;
49 uint32 num_group_account;
50 DISP_GROUP_INFO *disp_group_info;
54 /* for use by the \PIPE\samr policy */
56 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
65 struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
66 struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
67 struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
68 struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
69 struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
71 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
73 /*******************************************************************
74 Checks if access to an object should be granted, and returns that
75 level of access for further checks.
76 ********************************************************************/
78 NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_token, uint32 des_access,
79 uint32 *acc_granted, const char *debug)
81 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
83 if (!se_access_check(psd, nt_user_token, des_access, acc_granted, &status)) {
84 *acc_granted = des_access;
85 if (geteuid() == sec_initial_uid()) {
86 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n",
88 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
89 status = NT_STATUS_OK;
92 DEBUG(2,("%s: ACCESS DENIED (requested: %#010x)\n",
99 /*******************************************************************
100 Checks if access to a function can be granted
101 ********************************************************************/
103 NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
105 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
106 debug, acc_granted, acc_required));
107 if ((acc_granted & acc_required) != acc_required) {
108 if (geteuid() == sec_initial_uid()) {
109 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
110 debug, acc_granted, acc_required));
111 DEBUGADD(4,("but overwritten by euid == 0\n"));
114 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
115 debug, acc_granted, acc_required));
116 return NT_STATUS_ACCESS_DENIED;
122 /*******************************************************************
123 Create a samr_info struct.
124 ********************************************************************/
126 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
128 struct samr_info *info;
133 sid_to_string(sid_str, psid);
135 fstrcpy(sid_str,"(NULL)");
138 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
140 if ((info = (struct samr_info *)talloc(mem_ctx, sizeof(struct samr_info))) == NULL)
144 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
146 sid_copy( &info->sid, psid);
148 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
150 info->mem_ctx = mem_ctx;
155 /*******************************************************************
156 Function to free the per handle data.
157 ********************************************************************/
158 static void free_samr_users(struct samr_info *info)
162 if (info->disp_info.user_dbloaded){
163 for (i=0; i<info->disp_info.num_user_account; i++) {
164 /* Not really a free, actually a 'clear' */
165 pdb_free_sam(&info->disp_info.disp_user_info[i].sam);
168 info->disp_info.user_dbloaded=False;
169 info->disp_info.num_user_account=0;
173 /*******************************************************************
174 Function to free the per handle data.
175 ********************************************************************/
176 static void free_samr_db(struct samr_info *info)
178 /* Groups are talloced */
180 free_samr_users(info);
182 info->disp_info.group_dbloaded=False;
183 info->disp_info.num_group_account=0;
187 static void free_samr_info(void *ptr)
189 struct samr_info *info=(struct samr_info *) ptr;
192 talloc_destroy(info->mem_ctx);
195 /*******************************************************************
196 Ensure password info is never given out. Paranioa... JRA.
197 ********************************************************************/
199 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
205 /* These now zero out the old password */
207 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
208 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
212 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL all_machines)
214 SAM_ACCOUNT *pwd = NULL;
215 DISP_USER_INFO *pwd_array = NULL;
216 NTSTATUS nt_status = NT_STATUS_OK;
217 TALLOC_CTX *mem_ctx = info->mem_ctx;
219 DEBUG(10,("load_sampwd_entries\n"));
221 /* if the snapshoot is already loaded, return */
222 if ((info->disp_info.user_dbloaded==True)
223 && (info->acb_mask == acb_mask)
224 && (info->all_machines == all_machines)) {
225 DEBUG(10,("load_sampwd_entries: already in memory\n"));
229 free_samr_users(info);
231 if (!pdb_setsampwent(False)) {
232 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
233 return NT_STATUS_ACCESS_DENIED;
236 for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd)))
237 && pdb_getsampwent(pwd) == True; pwd=NULL) {
240 if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST)
241 || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
242 DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
247 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
249 DEBUG(5,(" acb_mask %x reject\n", acb_mask));
254 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
255 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
257 DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
258 pwd_array=(DISP_USER_INFO *)talloc_realloc(mem_ctx, info->disp_info.disp_user_info,
259 (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(DISP_USER_INFO));
262 return NT_STATUS_NO_MEMORY;
264 info->disp_info.disp_user_info=pwd_array;
267 /* link the SAM_ACCOUNT to the array */
268 info->disp_info.disp_user_info[info->disp_info.num_user_account].sam=pwd;
270 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
272 info->disp_info.num_user_account++;
277 /* the snapshoot is in memory, we're ready to enumerate fast */
279 info->acb_mask = acb_mask;
280 info->all_machines = all_machines;
281 info->disp_info.user_dbloaded=True;
283 DEBUG(10,("load_sampwd_entries: done\n"));
288 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
291 DISP_GROUP_INFO *grp_array = NULL;
292 uint32 group_entries = 0;
294 TALLOC_CTX *mem_ctx = info->mem_ctx;
296 DEBUG(10,("load_group_domain_entries\n"));
298 /* if the snapshoot is already loaded, return */
299 if (info->disp_info.group_dbloaded==True) {
300 DEBUG(10,("load_group_domain_entries: already in memory\n"));
307 if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV)) {
308 DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
309 return NT_STATUS_NO_MEMORY;
314 info->disp_info.num_group_account=group_entries;
316 grp_array=(DISP_GROUP_INFO *)talloc(mem_ctx, info->disp_info.num_group_account*sizeof(DISP_GROUP_INFO));
318 if (group_entries!=0 && grp_array==NULL) {
319 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
321 return NT_STATUS_NO_MEMORY;
324 info->disp_info.disp_group_info=grp_array;
326 for (i=0; i<group_entries; i++) {
328 grp_array[i].grp=(DOMAIN_GRP *)talloc(mem_ctx, sizeof(DOMAIN_GRP));
330 fstrcpy(grp_array[i].grp->name, map[i].nt_name);
331 fstrcpy(grp_array[i].grp->comment, map[i].comment);
332 sid_split_rid(&map[i].sid, &grp_array[i].grp->rid);
333 grp_array[i].grp->attr=SID_NAME_DOM_GRP;
338 /* the snapshoot is in memory, we're ready to enumerate fast */
340 info->disp_info.group_dbloaded=True;
342 DEBUG(10,("load_group_domain_entries: done\n"));
348 /*******************************************************************
350 ********************************************************************/
352 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
354 r_u->status = NT_STATUS_OK;
356 /* close the policy handle */
357 if (!close_policy_hnd(p, &q_u->pol))
358 return NT_STATUS_OBJECT_NAME_INVALID;
360 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
365 /*******************************************************************
366 samr_reply_open_domain
367 ********************************************************************/
369 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
371 struct samr_info *info;
372 SEC_DESC *psd = NULL;
374 uint32 des_access = q_u->flags;
378 r_u->status = NT_STATUS_OK;
380 /* find the connection policy handle. */
381 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
382 return NT_STATUS_INVALID_HANDLE;
384 if (!NT_STATUS_IS_OK(status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN,"_samr_open_domain"))) {
388 /*check if access can be granted as requested by client. */
389 samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
390 se_map_generic(&des_access,&dom_generic_mapping);
392 if (!NT_STATUS_IS_OK(status =
393 access_check_samr_object(psd, p->pipe_user.nt_user_token,
394 des_access, &acc_granted, "_samr_open_domain"))) {
398 /* associate the domain SID with the (unique) handle. */
399 if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
400 return NT_STATUS_NO_MEMORY;
401 info->acc_granted = acc_granted;
403 /* get a (unique) handle. open a policy on it. */
404 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
405 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
407 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
412 /*******************************************************************
413 _samr_get_usrdom_pwinfo
414 ********************************************************************/
416 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
418 struct samr_info *info = NULL;
420 r_u->status = NT_STATUS_OK;
422 /* find the policy handle. open a policy on it. */
423 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
424 return NT_STATUS_INVALID_HANDLE;
426 if (!sid_check_is_in_our_domain(&info->sid))
427 return NT_STATUS_OBJECT_TYPE_MISMATCH;
429 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
431 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
434 * NT sometimes return NT_STATUS_ACCESS_DENIED
435 * I don't know yet why.
441 /*******************************************************************
443 ********************************************************************/
445 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
447 extern DOM_SID global_sid_World;
456 sid_copy(&adm_sid, &global_sid_Builtin);
457 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
459 sid_copy(&act_sid, &global_sid_Builtin);
460 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
462 /*basic access for every one*/
463 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
464 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
466 /*full access for builtin aliases Administrators and Account Operators*/
467 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS);
468 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
469 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
471 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
472 return NT_STATUS_NO_MEMORY;
474 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
475 return NT_STATUS_NO_MEMORY;
480 /*******************************************************************
482 ********************************************************************/
484 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
486 extern DOM_SID global_sid_World;
495 sid_copy(&adm_sid, &global_sid_Builtin);
496 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
498 sid_copy(&act_sid, &global_sid_Builtin);
499 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
501 /*basic access for every one*/
502 init_sec_access(&mask, GENERIC_RIGHTS_USER_EXECUTE | GENERIC_RIGHTS_USER_READ);
503 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
505 /*full access for builtin aliases Administrators and Account Operators*/
506 init_sec_access(&mask, GENERIC_RIGHTS_USER_ALL_ACCESS);
507 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
508 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
510 /*extended access for the user*/
511 init_sec_access(&mask,READ_CONTROL_ACCESS | SA_RIGHT_USER_CHANGE_PASSWORD | SA_RIGHT_USER_SET_LOC_COM);
512 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
514 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
515 return NT_STATUS_NO_MEMORY;
517 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
518 return NT_STATUS_NO_MEMORY;
523 /*******************************************************************
525 ********************************************************************/
527 static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
529 extern DOM_SID global_sid_World;
538 sid_copy(&adm_sid, &global_sid_Builtin);
539 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
541 sid_copy(&act_sid, &global_sid_Builtin);
542 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
544 /*basic access for every one*/
545 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
546 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
548 /*full access for builtin aliases Administrators and Account Operators*/
549 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_ALL_ACCESS);
550 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
551 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
553 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
554 return NT_STATUS_NO_MEMORY;
556 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
557 return NT_STATUS_NO_MEMORY;
562 /*******************************************************************
564 ********************************************************************/
566 static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
568 extern DOM_SID global_sid_World;
577 sid_copy(&adm_sid, &global_sid_Builtin);
578 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
580 sid_copy(&act_sid, &global_sid_Builtin);
581 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
583 /*basic access for every one*/
584 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
585 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
587 /*full access for builtin aliases Administrators and Account Operators*/
588 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_ALL_ACCESS);
589 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
590 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
592 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
593 return NT_STATUS_NO_MEMORY;
595 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
596 return NT_STATUS_NO_MEMORY;
601 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
603 struct samr_info *info = NULL;
605 /* find the policy handle. open a policy on it. */
606 if (!find_policy_by_hnd(p, pol, (void **)&info))
613 *acc_granted = info->acc_granted;
617 /*******************************************************************
619 ********************************************************************/
621 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
623 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
624 return NT_STATUS_NOT_IMPLEMENTED;
628 /*******************************************************************
630 ********************************************************************/
632 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
636 SEC_DESC * psd = NULL;
640 r_u->status = NT_STATUS_OK;
643 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
644 return NT_STATUS_INVALID_HANDLE;
648 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
650 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
652 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
653 if (pol_sid.sid_rev_num == 0)
655 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
656 r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
658 else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */
661 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
662 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
664 else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */
666 /* TODO: Builtin probably needs a different SD with restricted write access*/
667 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
668 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
670 else if (sid_check_is_in_our_domain(&pol_sid) ||
671 sid_check_is_in_builtin(&pol_sid))
673 /* TODO: different SDs have to be generated for aliases groups and users.
674 Currently all three get a default user SD */
675 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
676 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
678 else return NT_STATUS_OBJECT_TYPE_MISMATCH;
680 if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
681 return NT_STATUS_NO_MEMORY;
683 if (NT_STATUS_IS_OK(r_u->status))
689 /*******************************************************************
690 makes a SAM_ENTRY / UNISTR2* structure from a user list.
691 ********************************************************************/
693 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
694 uint32 num_entries, uint32 start_idx, DISP_USER_INFO *disp_user_info,
700 SAM_ACCOUNT *pwd = NULL;
701 UNISTR2 uni_temp_name;
702 const char *temp_name;
703 const DOM_SID *user_sid;
705 fstring user_sid_string;
706 fstring domain_sid_string;
711 if (num_entries == 0)
714 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_entries);
716 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_entries);
718 if (sam == NULL || uni_name == NULL) {
719 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
720 return NT_STATUS_NO_MEMORY;
723 for (i = 0; i < num_entries; i++) {
724 pwd = disp_user_info[i+start_idx].sam;
725 temp_name = pdb_get_username(pwd);
726 init_unistr2(&uni_temp_name, temp_name, strlen(temp_name)+1);
727 user_sid = pdb_get_user_sid(pwd);
729 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
730 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
731 "the domain sid %s. Failing operation.\n",
733 sid_to_string(user_sid_string, user_sid),
734 sid_to_string(domain_sid_string, domain_sid)));
735 return NT_STATUS_UNSUCCESSFUL;
738 init_sam_entry(&sam[i], uni_temp_name.uni_str_len, user_rid);
739 copy_unistr2(&uni_name[i], &uni_temp_name);
743 *uni_name_pp = uni_name;
747 /*******************************************************************
748 samr_reply_enum_dom_users
749 ********************************************************************/
751 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
752 SAMR_R_ENUM_DOM_USERS *r_u)
754 struct samr_info *info = NULL;
755 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
757 uint32 enum_context=q_u->start_idx;
758 uint32 max_size=q_u->max_size;
760 enum remote_arch_types ra_type = get_remote_arch();
761 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
762 uint32 max_entries = max_sam_entries;
765 r_u->status = NT_STATUS_OK;
767 /* find the policy handle. open a policy on it. */
768 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
769 return NT_STATUS_INVALID_HANDLE;
771 domain_sid = info->sid;
773 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
774 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
775 "_samr_enum_dom_users"))) {
779 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
782 r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
785 if (!NT_STATUS_IS_OK(r_u->status))
788 num_account = info->disp_info.num_user_account;
790 if (enum_context > num_account) {
791 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
795 /* verify we won't overflow */
796 if (max_entries > num_account-enum_context) {
797 max_entries = num_account-enum_context;
798 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
801 /* calculate the size and limit on the number of entries we will return */
802 temp_size=max_entries*struct_size;
804 if (temp_size>max_size) {
805 max_entries=MIN((max_size/struct_size),max_entries);;
806 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
810 * Note from JRA. total_entries is not being used here. Currently if there is a
811 * large user base then it looks like NT will enumerate until get_sampwd_entries
812 * returns False due to num_entries being zero. This will cause an access denied
813 * return. I don't think this is right and needs further investigation. Note that
814 * this is also the same in the TNG code (I don't think that has been tested with
815 * a very large user list as MAX_SAM_ENTRIES is set to 600).
817 * I also think that one of the 'num_entries' return parameters is probably
818 * the "max entries" parameter - but in the TNG code they're all currently set to the same
819 * value (again I think this is wrong).
822 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
823 max_entries, enum_context,
824 info->disp_info.disp_user_info,
827 if (!NT_STATUS_IS_OK(r_u->status))
830 if (enum_context+max_entries < num_account)
831 r_u->status = STATUS_MORE_ENTRIES;
833 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
835 init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
837 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
842 /*******************************************************************
843 makes a SAM_ENTRY / UNISTR2* structure from a group list.
844 ********************************************************************/
846 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
847 uint32 num_sam_entries, DOMAIN_GRP *grp)
856 if (num_sam_entries == 0)
859 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
861 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
863 if (sam == NULL || uni_name == NULL) {
864 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
868 for (i = 0; i < num_sam_entries; i++) {
870 * JRA. I think this should include the null. TNG does not.
872 int len = strlen(grp[i].name)+1;
874 init_sam_entry(&sam[i], len, grp[i].rid);
875 init_unistr2(&uni_name[i], grp[i].name, len);
879 *uni_name_pp = uni_name;
882 /*******************************************************************
883 Get the group entries - similar to get_sampwd_entries().
884 ********************************************************************/
886 static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
887 uint32 *p_num_entries, uint32 max_entries)
890 uint32 num_entries = 0;
893 GROUP_MAP *map = NULL;
895 sid_to_string(sid_str, sid);
896 DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str));
900 /* well-known aliases */
901 if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
903 pdb_enum_group_mapping(SID_NAME_WKN_GRP, &map, (int *)&num_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
905 if (num_entries != 0) {
906 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
908 return NT_STATUS_NO_MEMORY;
910 for(i=0; i<num_entries && i<max_entries; i++) {
911 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
912 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
918 } else if (sid_equal(sid, get_global_sam_sid()) && !lp_hide_local_users()) {
919 struct sys_grent *glist;
920 struct sys_grent *grp;
922 gid_t winbind_gid_low, winbind_gid_high;
923 BOOL winbind_groups_exist = lp_idmap_gid(&winbind_gid_low, &winbind_gid_high);
926 /* we return the UNIX groups here. This seems to be the right */
927 /* thing to do, since NT member servers return their local */
928 /* groups in the same situation. */
930 /* use getgrent_list() to retrieve the list of groups to avoid
931 * problems with getgrent possible infinite loop by internal
932 * libc grent structures overwrites by called functions */
933 grp = glist = getgrent_list();
935 return NT_STATUS_NO_MEMORY;
937 for (; (num_entries < max_entries) && (grp != NULL); grp = grp->next) {
940 if(!pdb_getgrgid(&smap, grp->gr_gid, MAPPING_WITHOUT_PRIV))
943 if (smap.sid_name_use!=SID_NAME_ALIAS) {
947 sid_split_rid(&smap.sid, &trid);
949 if (!sid_equal(sid, &smap.sid))
952 /* Don't return winbind groups as they are not local! */
953 if (winbind_groups_exist && (grp->gr_gid >= winbind_gid_low)&&(grp->gr_gid <= winbind_gid_high)) {
954 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
958 /* Don't return user private groups... */
960 if ((pw = Get_Pwnam(smap.nt_name)) != 0) {
961 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
965 for( i = 0; i < num_entries; i++)
966 if ( (*d_grp)[i].rid == trid )
969 if ( i < num_entries ) {
970 continue; /* rid was there, dup! */
973 /* JRA - added this for large group db enumeration... */
976 /* skip the requested number of entries.
977 not very efficient, but hey...
983 *d_grp=talloc_realloc(ctx,*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
986 return NT_STATUS_NO_MEMORY;
989 fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
990 (*d_grp)[num_entries].rid = trid;
992 DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries, trid));
998 *p_num_entries = num_entries;
1000 DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries));
1002 if (num_entries >= max_entries)
1003 return STATUS_MORE_ENTRIES;
1004 return NT_STATUS_OK;
1007 /*******************************************************************
1008 Get the group entries - similar to get_sampwd_entries().
1009 ********************************************************************/
1011 static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
1012 uint32 *p_num_entries, uint32 max_entries)
1014 GROUP_MAP *map=NULL;
1016 uint32 group_entries = 0;
1017 uint32 num_entries = 0;
1021 pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
1023 num_entries=group_entries-start_idx;
1025 /* limit the number of entries */
1026 if (num_entries>max_entries) {
1027 DEBUG(5,("Limiting to %d entries\n", max_entries));
1028 num_entries=max_entries;
1031 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
1032 if (num_entries!=0 && *d_grp==NULL){
1034 return NT_STATUS_NO_MEMORY;
1037 for (i=0; i<num_entries; i++) {
1038 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
1039 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
1040 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
1041 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
1046 *p_num_entries = num_entries;
1048 return NT_STATUS_OK;
1051 /*******************************************************************
1052 samr_reply_enum_dom_groups
1053 ********************************************************************/
1055 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
1057 DOMAIN_GRP *grp=NULL;
1062 r_u->status = NT_STATUS_OK;
1064 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1065 return NT_STATUS_INVALID_HANDLE;
1067 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
1071 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1073 /* the domain group array is being allocated in the function below */
1074 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))) {
1078 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1080 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
1082 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1088 /*******************************************************************
1089 samr_reply_enum_dom_aliases
1090 ********************************************************************/
1092 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1094 DOMAIN_GRP *grp=NULL;
1095 uint32 num_entries = 0;
1101 r_u->status = NT_STATUS_OK;
1103 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1104 return NT_STATUS_INVALID_HANDLE;
1106 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1110 sid_to_string(sid_str, &sid);
1111 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1113 status = get_group_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1114 &num_entries, MAX_SAM_ENTRIES);
1115 if (NT_STATUS_IS_ERR(status)) return status;
1117 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1121 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1123 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1128 /*******************************************************************
1129 samr_reply_query_dispinfo
1130 ********************************************************************/
1131 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1132 SAMR_R_QUERY_DISPINFO *r_u)
1134 struct samr_info *info = NULL;
1135 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1137 uint32 max_entries=q_u->max_entries;
1138 uint32 enum_context=q_u->start_idx;
1139 uint32 max_size=q_u->max_size;
1141 SAM_DISPINFO_CTR *ctr;
1142 uint32 temp_size=0, total_data_size=0;
1144 uint32 num_account = 0;
1145 enum remote_arch_types ra_type = get_remote_arch();
1146 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1149 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1150 r_u->status = NT_STATUS_OK;
1152 /* find the policy handle. open a policy on it. */
1153 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1154 return NT_STATUS_INVALID_HANDLE;
1156 domain_sid = info->sid;
1159 * calculate how many entries we will return.
1161 * - the number of entries the client asked
1162 * - our limit on that
1163 * - the starting point (enumeration context)
1164 * - the buffer size the client will accept
1168 * We are a lot more like W2K. Instead of reading the SAM
1169 * each time to find the records we need to send back,
1170 * we read it once and link that copy to the sam handle.
1171 * For large user list (over the MAX_SAM_ENTRIES)
1172 * it's a definitive win.
1173 * second point to notice: between enumerations
1174 * our sam is now the same as it's a snapshoot.
1175 * third point: got rid of the static SAM_USER_21 struct
1176 * no more intermediate.
1177 * con: it uses much more memory, as a full copy is stored
1180 * If you want to change it, think twice and think
1181 * of the second point , that's really important.
1186 /* Get what we need from the password database */
1187 switch (q_u->switch_level) {
1189 /* When playing with usrmgr, this is necessary
1190 if you want immediate refresh after editing
1191 a user. I would like to do this after the
1192 setuserinfo2, but we do not have access to
1193 the domain handle in that call, only to the
1194 user handle. Where else does this hurt?
1198 /* We cannot do this here - it kills performace. JRA. */
1199 free_samr_users(info);
1204 /* Level 2 is for all machines, otherwise only 'normal' users */
1205 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1207 if (!NT_STATUS_IS_OK(r_u->status)) {
1208 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1211 num_account = info->disp_info.num_user_account;
1215 r_u->status = load_group_domain_entries(info, &info->sid);
1216 if (!NT_STATUS_IS_OK(r_u->status))
1218 num_account = info->disp_info.num_group_account;
1221 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1222 return NT_STATUS_INVALID_INFO_CLASS;
1225 /* first limit the number of entries we will return */
1226 if(max_entries > max_sam_entries) {
1227 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1228 max_entries = max_sam_entries;
1231 if (enum_context > num_account) {
1232 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1233 return NT_STATUS_NO_MORE_ENTRIES;
1236 /* verify we won't overflow */
1237 if (max_entries > num_account-enum_context) {
1238 max_entries = num_account-enum_context;
1239 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1242 /* calculate the size and limit on the number of entries we will return */
1243 temp_size=max_entries*struct_size;
1245 if (temp_size>max_size) {
1246 max_entries=MIN((max_size/struct_size),max_entries);;
1247 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1250 if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1251 return NT_STATUS_NO_MEMORY;
1255 /* Now create reply structure */
1256 switch (q_u->switch_level) {
1259 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
1260 return NT_STATUS_NO_MEMORY;
1262 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1263 info->disp_info.disp_user_info, &domain_sid);
1264 if (!NT_STATUS_IS_OK(disp_ret))
1269 if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1270 return NT_STATUS_NO_MEMORY;
1272 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1273 info->disp_info.disp_user_info, &domain_sid);
1274 if (!NT_STATUS_IS_OK(disp_ret))
1279 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1280 return NT_STATUS_NO_MEMORY;
1282 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1283 if (!NT_STATUS_IS_OK(disp_ret))
1288 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1289 return NT_STATUS_NO_MEMORY;
1291 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1292 if (!NT_STATUS_IS_OK(disp_ret))
1297 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1298 return NT_STATUS_NO_MEMORY;
1300 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1301 if (!NT_STATUS_IS_OK(disp_ret))
1306 ctr->sam.info = NULL;
1307 return NT_STATUS_INVALID_INFO_CLASS;
1310 /* calculate the total size */
1311 total_data_size=num_account*struct_size;
1313 if (enum_context+max_entries < num_account)
1314 r_u->status = STATUS_MORE_ENTRIES;
1316 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1318 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1324 /*******************************************************************
1325 samr_reply_query_aliasinfo
1326 ********************************************************************/
1328 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1334 r_u->status = NT_STATUS_OK;
1336 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1338 /* find the policy handle. open a policy on it. */
1339 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1340 return NT_STATUS_INVALID_HANDLE;
1341 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1345 if (!sid_check_is_in_our_domain(&sid) &&
1346 !sid_check_is_in_builtin(&sid))
1347 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1349 if (!pdb_getgrsid(&map, sid, MAPPING_WITHOUT_PRIV))
1350 return NT_STATUS_NO_SUCH_ALIAS;
1352 switch (q_u->switch_level) {
1355 r_u->ctr.switch_value1 = 1;
1356 init_samr_alias_info1(&r_u->ctr.alias.info1, map.nt_name, 1, map.comment);
1360 r_u->ctr.switch_value1 = 3;
1361 init_samr_alias_info3(&r_u->ctr.alias.info3, map.comment);
1364 return NT_STATUS_INVALID_INFO_CLASS;
1367 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1373 /*******************************************************************
1374 samr_reply_lookup_ids
1375 ********************************************************************/
1377 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1379 uint32 rid[MAX_SAM_ENTRIES];
1380 int num_rids = q_u->num_sids1;
1382 r_u->status = NT_STATUS_OK;
1384 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1386 if (num_rids > MAX_SAM_ENTRIES) {
1387 num_rids = MAX_SAM_ENTRIES;
1388 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1393 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1395 for (i = 0; i < num_rids && status == 0; i++)
1397 struct sam_passwd *sam_pass;
1401 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1402 q_u->uni_user_name[i].uni_str_len));
1404 /* find the user account */
1406 sam_pass = get_smb21pwd_entry(user_name, 0);
1409 if (sam_pass == NULL)
1411 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1416 rid[i] = sam_pass->user_rid;
1422 rid[0] = BUILTIN_ALIAS_RID_USERS;
1424 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1426 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1432 /*******************************************************************
1434 ********************************************************************/
1436 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1438 uint32 rid[MAX_SAM_ENTRIES];
1440 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1441 enum SID_NAME_USE local_type;
1443 int num_rids = q_u->num_names2;
1448 r_u->status = NT_STATUS_OK;
1450 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1455 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1456 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1460 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 */
1464 if (num_rids > MAX_SAM_ENTRIES) {
1465 num_rids = MAX_SAM_ENTRIES;
1466 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1469 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1471 become_root(); /* local_lookup_name can require root privs */
1473 for (i = 0; i < num_rids; i++) {
1478 r_u->status = NT_STATUS_NONE_MAPPED;
1480 rid [i] = 0xffffffff;
1481 type[i] = SID_NAME_UNKNOWN;
1483 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1486 * we are only looking for a name
1487 * the SID we get back can be outside
1488 * the scope of the pol_sid
1490 * in clear: it prevents to reply to domain\group: yes
1491 * when only builtin\group exists.
1493 * a cleaner code is to add the sid of the domain we're looking in
1494 * to the local_lookup_name function.
1497 if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
1498 sid_split_rid(&sid, &local_rid);
1500 if (sid_equal(&sid, &pol_sid)) {
1503 r_u->status = NT_STATUS_OK;
1510 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1512 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1517 /*******************************************************************
1518 _samr_chgpasswd_user
1519 ********************************************************************/
1521 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1526 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1528 r_u->status = NT_STATUS_OK;
1530 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1531 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1533 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1536 * Pass the user through the NT -> unix user mapping
1540 (void)map_username(user_name);
1543 * UNIX username case mangling not required, pass_oem_change
1544 * is case insensitive.
1547 r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1548 q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1550 init_samr_r_chgpasswd_user(r_u, r_u->status);
1552 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1557 /*******************************************************************
1558 makes a SAMR_R_LOOKUP_RIDS structure.
1559 ********************************************************************/
1561 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1562 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1565 UNIHDR *hdr_name=NULL;
1566 UNISTR2 *uni_name=NULL;
1568 *pp_uni_name = NULL;
1569 *pp_hdr_name = NULL;
1571 if (num_names != 0) {
1572 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1573 if (hdr_name == NULL)
1576 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1577 if (uni_name == NULL)
1581 for (i = 0; i < num_names; i++) {
1582 int len = names[i] != NULL ? strlen(names[i]) : 0;
1583 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1584 init_uni_hdr(&hdr_name[i], len);
1585 init_unistr2(&uni_name[i], names[i], len);
1588 *pp_uni_name = uni_name;
1589 *pp_hdr_name = hdr_name;
1594 /*******************************************************************
1596 ********************************************************************/
1598 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1600 fstring group_names[MAX_SAM_ENTRIES];
1601 uint32 *group_attrs = NULL;
1602 UNIHDR *hdr_name = NULL;
1603 UNISTR2 *uni_name = NULL;
1605 int num_rids = q_u->num_rids1;
1609 r_u->status = NT_STATUS_OK;
1611 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1613 /* find the policy handle. open a policy on it. */
1614 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1615 return NT_STATUS_INVALID_HANDLE;
1617 if (num_rids > MAX_SAM_ENTRIES) {
1618 num_rids = MAX_SAM_ENTRIES;
1619 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1623 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1624 return NT_STATUS_NO_MEMORY;
1627 r_u->status = NT_STATUS_NONE_MAPPED;
1629 become_root(); /* lookup_sid can require root privs */
1631 for (i = 0; i < num_rids; i++) {
1635 enum SID_NAME_USE type;
1637 group_attrs[i] = SID_NAME_UNKNOWN;
1638 *group_names[i] = '\0';
1640 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1641 sid_copy(&sid, &pol_sid);
1642 sid_append_rid(&sid, q_u->rid[i]);
1644 if (lookup_sid(&sid, domname, tmpname, &type)) {
1645 r_u->status = NT_STATUS_OK;
1646 group_attrs[i] = (uint32)type;
1647 fstrcpy(group_names[i],tmpname);
1648 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1655 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1656 return NT_STATUS_NO_MEMORY;
1658 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1660 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1665 /*******************************************************************
1666 _api_samr_open_user. Safe - gives out no passwd info.
1667 ********************************************************************/
1669 NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1671 SAM_ACCOUNT *sampass=NULL;
1673 POLICY_HND domain_pol = q_u->domain_pol;
1674 POLICY_HND *user_pol = &r_u->user_pol;
1675 struct samr_info *info = NULL;
1676 SEC_DESC *psd = NULL;
1678 uint32 des_access = q_u->access_mask;
1683 r_u->status = NT_STATUS_OK;
1685 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1686 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1687 return NT_STATUS_INVALID_HANDLE;
1689 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1693 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1694 if (!NT_STATUS_IS_OK(nt_status)) {
1698 /* append the user's RID to it */
1699 if (!sid_append_rid(&sid, q_u->user_rid))
1700 return NT_STATUS_NO_SUCH_USER;
1702 /* check if access can be granted as requested by client. */
1703 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1704 se_map_generic(&des_access, &usr_generic_mapping);
1705 if (!NT_STATUS_IS_OK(nt_status =
1706 access_check_samr_object(psd, p->pipe_user.nt_user_token,
1707 des_access, &acc_granted, "_samr_open_user"))) {
1712 ret=pdb_getsampwsid(sampass, &sid);
1715 /* check that the SID exists in our domain. */
1717 return NT_STATUS_NO_SUCH_USER;
1720 pdb_free_sam(&sampass);
1722 /* associate the user's SID and access bits with the new handle. */
1723 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1724 return NT_STATUS_NO_MEMORY;
1725 info->acc_granted = acc_granted;
1727 /* get a (unique) handle. open a policy on it. */
1728 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1729 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1734 /*************************************************************************
1735 get_user_info_10. Safe. Only gives out acb bits.
1736 *************************************************************************/
1738 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1740 SAM_ACCOUNT *smbpass=NULL;
1744 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1746 if (!NT_STATUS_IS_OK(nt_status)) {
1751 ret = pdb_getsampwsid(smbpass, user_sid);
1755 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1756 return NT_STATUS_NO_SUCH_USER;
1759 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1762 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1764 pdb_free_sam(&smbpass);
1766 return NT_STATUS_OK;
1769 /*************************************************************************
1770 get_user_info_12. OK - this is the killer as it gives out password info.
1771 Ensure that this is only allowed on an encrypted connection with a root
1773 *************************************************************************/
1775 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1777 SAM_ACCOUNT *smbpass=NULL;
1781 if (!p->ntlmssp_auth_validated)
1782 return NT_STATUS_ACCESS_DENIED;
1784 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1785 return NT_STATUS_ACCESS_DENIED;
1788 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1791 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1793 if (!NT_STATUS_IS_OK(nt_status)) {
1797 ret = pdb_getsampwsid(smbpass, user_sid);
1800 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1801 pdb_free_sam(&smbpass);
1802 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1805 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1807 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1808 pdb_free_sam(&smbpass);
1809 return NT_STATUS_ACCOUNT_DISABLED;
1813 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1815 pdb_free_sam(&smbpass);
1817 return NT_STATUS_OK;
1820 /*************************************************************************
1822 *************************************************************************/
1824 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1826 SAM_ACCOUNT *sampass=NULL;
1829 pdb_init_sam_talloc(mem_ctx, &sampass);
1832 ret = pdb_getsampwsid(sampass, user_sid);
1836 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1837 return NT_STATUS_NO_SUCH_USER;
1840 samr_clear_sam_passwd(sampass);
1842 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1845 init_sam_user_info20A(id20, sampass);
1847 pdb_free_sam(&sampass);
1849 return NT_STATUS_OK;
1852 /*************************************************************************
1854 *************************************************************************/
1856 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1857 DOM_SID *user_sid, DOM_SID *domain_sid)
1859 SAM_ACCOUNT *sampass=NULL;
1863 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1864 if (!NT_STATUS_IS_OK(nt_status)) {
1869 ret = pdb_getsampwsid(sampass, user_sid);
1873 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1874 return NT_STATUS_NO_SUCH_USER;
1877 samr_clear_sam_passwd(sampass);
1879 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1882 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1884 pdb_free_sam(&sampass);
1886 return NT_STATUS_OK;
1889 /*******************************************************************
1890 _samr_query_userinfo
1891 ********************************************************************/
1893 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1895 SAM_USERINFO_CTR *ctr;
1896 struct samr_info *info = NULL;
1900 r_u->status=NT_STATUS_OK;
1902 /* search for the handle */
1903 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1904 return NT_STATUS_INVALID_HANDLE;
1906 domain_sid = info->sid;
1908 sid_split_rid(&domain_sid, &rid);
1910 if (!sid_check_is_in_our_domain(&info->sid))
1911 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1913 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1915 ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1917 return NT_STATUS_NO_MEMORY;
1921 /* ok! user info levels (lots: see MSDEV help), off we go... */
1922 ctr->switch_value = q_u->switch_value;
1924 switch (q_u->switch_value) {
1926 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1927 if (ctr->info.id10 == NULL)
1928 return NT_STATUS_NO_MEMORY;
1930 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1935 /* whoops - got this wrong. i think. or don't understand what's happening. */
1939 info = (void *)&id11;
1941 expire.low = 0xffffffff;
1942 expire.high = 0x7fffffff;
1944 ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1949 ZERO_STRUCTP(ctr->info.id11);
1950 init_sam_user_info11(ctr->info.id11, &expire,
1951 "BROOKFIELDS$", /* name */
1952 0x03ef, /* user rid */
1953 0x201, /* group rid */
1954 0x0080); /* acb info */
1961 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1962 if (ctr->info.id12 == NULL)
1963 return NT_STATUS_NO_MEMORY;
1965 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1970 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1971 if (ctr->info.id20 == NULL)
1972 return NT_STATUS_NO_MEMORY;
1973 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1978 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1979 if (ctr->info.id21 == NULL)
1980 return NT_STATUS_NO_MEMORY;
1981 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1982 &info->sid, &domain_sid)))
1987 return NT_STATUS_INVALID_INFO_CLASS;
1990 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1992 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1997 /*******************************************************************
1998 samr_reply_query_usergroups
1999 ********************************************************************/
2001 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
2003 SAM_ACCOUNT *sam_pass=NULL;
2005 DOM_GID *gids = NULL;
2011 * from the SID in the request:
2012 * we should send back the list of DOMAIN GROUPS
2013 * the user is a member of
2015 * and only the DOMAIN GROUPS
2016 * no ALIASES !!! neither aliases of the domain
2017 * nor aliases of the builtin SID
2022 r_u->status = NT_STATUS_OK;
2024 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2026 /* find the policy handle. open a policy on it. */
2027 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
2028 return NT_STATUS_INVALID_HANDLE;
2030 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
2034 if (!sid_check_is_in_our_domain(&sid))
2035 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2037 pdb_init_sam(&sam_pass);
2040 ret = pdb_getsampwsid(sam_pass, &sid);
2044 pdb_free_sam(&sam_pass);
2045 return NT_STATUS_NO_SUCH_USER;
2048 if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
2049 pdb_free_sam(&sam_pass);
2050 return NT_STATUS_NO_SUCH_GROUP;
2053 /* construct the response. lkclXXXX: gids are not copied! */
2054 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
2056 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2058 pdb_free_sam(&sam_pass);
2063 /*******************************************************************
2064 _samr_query_dom_info
2065 ********************************************************************/
2067 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2069 struct samr_info *info = NULL;
2071 uint32 min_pass_len,pass_hist,flag;
2072 time_t u_expire, u_min_age;
2073 NTTIME nt_expire, nt_min_age;
2075 time_t u_lock_duration, u_reset_time;
2076 NTTIME nt_lock_duration, nt_reset_time;
2082 uint32 account_policy_temp;
2084 uint32 num_users=0, num_groups=0, num_aliases=0;
2086 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
2087 return NT_STATUS_NO_MEMORY;
2091 r_u->status = NT_STATUS_OK;
2093 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2095 /* find the policy handle. open a policy on it. */
2096 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2097 return NT_STATUS_INVALID_HANDLE;
2099 switch (q_u->switch_value) {
2102 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2103 min_pass_len = account_policy_temp;
2105 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2106 pass_hist = account_policy_temp;
2108 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2109 flag = account_policy_temp;
2111 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2112 u_expire = account_policy_temp;
2114 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2115 u_min_age = account_policy_temp;
2117 unix_to_nt_time_abs(&nt_expire, u_expire);
2118 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2120 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2121 flag, nt_expire, nt_min_age);
2125 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2127 if (!NT_STATUS_IS_OK(r_u->status)) {
2128 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2131 num_users=info->disp_info.num_user_account;
2134 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2135 if (!NT_STATUS_IS_OK(r_u->status)) {
2136 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2139 num_groups=info->disp_info.num_group_account;
2142 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2143 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
2144 num_users, num_groups, num_aliases);
2147 account_policy_get(AP_TIME_TO_LOGOUT, (int *)&u_logout);
2148 unix_to_nt_time_abs(&nt_logout, u_logout);
2150 init_unk_info3(&ctr->info.inf3, nt_logout);
2153 init_unk_info5(&ctr->info.inf5, global_myname());
2156 init_unk_info6(&ctr->info.inf6);
2159 init_unk_info7(&ctr->info.inf7);
2162 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2163 u_lock_duration = account_policy_temp;
2165 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2166 u_reset_time = account_policy_temp;
2168 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2169 lockout = account_policy_temp;
2171 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2172 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2174 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2177 return NT_STATUS_INVALID_INFO_CLASS;
2180 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2182 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2187 /*******************************************************************
2188 _api_samr_create_user
2189 Create an account, can be either a normal user or a machine.
2190 This funcion will need to be updated for bdc/domain trusts.
2191 ********************************************************************/
2193 NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2195 SAM_ACCOUNT *sam_pass=NULL;
2199 POLICY_HND dom_pol = q_u->domain_pol;
2200 UNISTR2 user_account = q_u->uni_name;
2201 uint16 acb_info = q_u->acb_info;
2202 POLICY_HND *user_pol = &r_u->user_pol;
2203 struct samr_info *info = NULL;
2210 /* check this, when giving away 'add computer to domain' privs */
2211 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2213 /* Get the domain SID stored in the domain policy */
2214 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2215 return NT_STATUS_INVALID_HANDLE;
2217 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2221 /* find the account: tell the caller if it exists.
2222 lkclXXXX i have *no* idea if this is a problem or not
2223 or even if you are supposed to construct a different
2224 reply if the account already exists...
2227 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2230 pdb_init_sam(&sam_pass);
2233 ret = pdb_getsampwnam(sam_pass, account);
2236 /* this account exists: say so */
2237 pdb_free_sam(&sam_pass);
2238 return NT_STATUS_USER_EXISTS;
2241 pdb_free_sam(&sam_pass);
2244 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2245 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2246 * that only people with write access to the smbpasswd file will be able
2247 * to create a user. JRA.
2251 * add the user in the /etc/passwd file or the unix authority system.
2252 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2253 * a) local_password_change() checks for us if the /etc/passwd account really exists
2254 * b) smb_create_user() would return an error if the account already exists
2255 * and as it could return an error also if it can't create the account, it would be tricky.
2257 * So we go the easy way, only check after if the account exists.
2258 * JFM (2/3/2001), to clear any possible bad understanding (-:
2260 * We now have seperate script paramaters for adding users/machines so we
2261 * now have some sainity-checking to match.
2264 DEBUG(10,("checking account %s at pos %d for $ termination\n",account, strlen(account)-1));
2266 if ((acb_info & ACB_WSTRUST) && (account[strlen(account)-1] == '$')) {
2267 pstrcpy(add_script, lp_addmachine_script());
2268 } else if ((!(acb_info & ACB_WSTRUST)) && (account[strlen(account)-1] != '$')) {
2269 pstrcpy(add_script, lp_adduser_script());
2271 DEBUG(0, ("_api_samr_create_user: mismatch between trust flags and $ termination\n"));
2272 pdb_free_sam(&sam_pass);
2273 return NT_STATUS_UNSUCCESSFUL;
2277 /* the passdb lookup has failed; check to see if we need to run the
2278 add user/machine script */
2280 pw = Get_Pwnam(account);
2284 * we can't check both the ending $ and the acb_info.
2286 * UserManager creates trust accounts (ending in $,
2287 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2290 if (account[strlen(account)-1] == '$')
2291 pstrcpy(add_script, lp_addmachine_script());
2293 pstrcpy(add_script, lp_adduser_script());
2297 all_string_sub(add_script, "%u", account, sizeof(account));
2298 add_ret = smbrun(add_script,NULL);
2299 DEBUG(3,("_api_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2304 nt_status = pdb_init_sam_new(&sam_pass, account);
2305 if (!NT_STATUS_IS_OK(nt_status))
2308 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2310 if (!pdb_add_sam_account(sam_pass)) {
2311 pdb_free_sam(&sam_pass);
2312 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2314 return NT_STATUS_ACCESS_DENIED;
2317 /* Get the user's SID */
2318 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2320 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2321 se_map_generic(&des_access, &usr_generic_mapping);
2322 if (!NT_STATUS_IS_OK(nt_status =
2323 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2324 des_access, &acc_granted, "_samr_create_user"))) {
2328 /* associate the user's SID with the new handle. */
2329 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2330 pdb_free_sam(&sam_pass);
2331 return NT_STATUS_NO_MEMORY;
2336 info->acc_granted = acc_granted;
2338 /* get a (unique) handle. open a policy on it. */
2339 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2340 pdb_free_sam(&sam_pass);
2341 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2344 r_u->user_rid=pdb_get_user_rid(sam_pass);
2346 r_u->access_granted = acc_granted;
2348 pdb_free_sam(&sam_pass);
2350 return NT_STATUS_OK;
2353 /*******************************************************************
2354 samr_reply_connect_anon
2355 ********************************************************************/
2357 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2359 struct samr_info *info = NULL;
2363 if (!pipe_access_check(p)) {
2364 DEBUG(3, ("access denied to samr_connect_anon\n"));
2365 r_u->status = NT_STATUS_ACCESS_DENIED;
2369 /* set up the SAMR connect_anon response */
2371 r_u->status = NT_STATUS_OK;
2373 /* associate the user's SID with the new handle. */
2374 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2375 return NT_STATUS_NO_MEMORY;
2377 info->status = q_u->unknown_0;
2379 /* get a (unique) handle. open a policy on it. */
2380 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2381 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2386 /*******************************************************************
2388 ********************************************************************/
2390 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2392 struct samr_info *info = NULL;
2393 SEC_DESC *psd = NULL;
2395 uint32 des_access = q_u->access_mask;
2400 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2404 if (!pipe_access_check(p)) {
2405 DEBUG(3, ("access denied to samr_connect\n"));
2406 r_u->status = NT_STATUS_ACCESS_DENIED;
2410 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2411 se_map_generic(&des_access, &sam_generic_mapping);
2412 if (!NT_STATUS_IS_OK(nt_status =
2413 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2414 des_access, &acc_granted, "_samr_connect"))) {
2418 r_u->status = NT_STATUS_OK;
2420 /* associate the user's SID and access granted with the new handle. */
2421 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2422 return NT_STATUS_NO_MEMORY;
2424 info->acc_granted = acc_granted;
2425 info->status = q_u->access_mask;
2427 /* get a (unique) handle. open a policy on it. */
2428 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2429 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2431 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2436 /*******************************************************************
2438 ********************************************************************/
2440 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2442 struct samr_info *info = NULL;
2443 SEC_DESC *psd = NULL;
2445 uint32 des_access = q_u->access_mask;
2450 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2454 if (!pipe_access_check(p)) {
2455 DEBUG(3, ("access denied to samr_connect4\n"));
2456 r_u->status = NT_STATUS_ACCESS_DENIED;
2460 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2461 se_map_generic(&des_access, &sam_generic_mapping);
2462 if (!NT_STATUS_IS_OK(nt_status =
2463 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2464 des_access, &acc_granted, "_samr_connect"))) {
2468 r_u->status = NT_STATUS_OK;
2470 /* associate the user's SID and access granted with the new handle. */
2471 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2472 return NT_STATUS_NO_MEMORY;
2474 info->acc_granted = acc_granted;
2475 info->status = q_u->access_mask;
2477 /* get a (unique) handle. open a policy on it. */
2478 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2479 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2481 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2486 /**********************************************************************
2487 api_samr_lookup_domain
2488 **********************************************************************/
2490 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2492 struct samr_info *info;
2493 fstring domain_name;
2496 r_u->status = NT_STATUS_OK;
2498 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2499 return NT_STATUS_INVALID_HANDLE;
2501 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain"))) {
2505 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2509 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2510 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2513 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2515 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2520 /******************************************************************
2521 makes a SAMR_R_ENUM_DOMAINS structure.
2522 ********************************************************************/
2524 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2525 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2531 DEBUG(5, ("make_enum_domains\n"));
2534 *pp_uni_name = NULL;
2536 if (num_sam_entries == 0)
2539 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2540 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2542 if (sam == NULL || uni_name == NULL)
2545 for (i = 0; i < num_sam_entries; i++) {
2546 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
2548 init_sam_entry(&sam[i], len, 0);
2549 init_unistr2(&uni_name[i], doms[i], len);
2553 *pp_uni_name = uni_name;
2558 /**********************************************************************
2559 api_samr_enum_domains
2560 **********************************************************************/
2562 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2564 struct samr_info *info;
2565 uint32 num_entries = 2;
2569 r_u->status = NT_STATUS_OK;
2571 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2572 return NT_STATUS_INVALID_HANDLE;
2574 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2578 name = get_global_sam_name();
2580 fstrcpy(dom[0],name);
2582 fstrcpy(dom[1],"Builtin");
2584 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2585 return NT_STATUS_NO_MEMORY;
2587 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2592 /*******************************************************************
2594 ********************************************************************/
2596 NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2599 POLICY_HND domain_pol = q_u->dom_pol;
2600 uint32 alias_rid = q_u->rid_alias;
2601 POLICY_HND *alias_pol = &r_u->pol;
2602 struct samr_info *info = NULL;
2603 SEC_DESC *psd = NULL;
2605 uint32 des_access = q_u->access_mask;
2609 r_u->status = NT_STATUS_OK;
2611 /* find the domain policy and get the SID / access bits stored in the domain policy */
2612 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2613 return NT_STATUS_INVALID_HANDLE;
2615 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2619 /* append the alias' RID to it */
2620 if (!sid_append_rid(&sid, alias_rid))
2621 return NT_STATUS_NO_SUCH_USER;
2623 /*check if access can be granted as requested by client. */
2624 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2625 se_map_generic(&des_access,&ali_generic_mapping);
2626 if (!NT_STATUS_IS_OK(status =
2627 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2628 des_access, &acc_granted, "_samr_open_alias"))) {
2633 * we should check if the rid really exist !!!
2637 /* associate the user's SID with the new handle. */
2638 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2639 return NT_STATUS_NO_MEMORY;
2641 info->acc_granted = acc_granted;
2643 /* get a (unique) handle. open a policy on it. */
2644 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2645 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2650 /*******************************************************************
2652 ********************************************************************/
2654 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2656 SAM_ACCOUNT *pwd =NULL;
2661 ret = pdb_getsampwsid(pwd, sid);
2669 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2674 /* FIX ME: check if the value is really changed --metze */
2675 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2680 if(!pdb_update_sam_account(pwd)) {
2690 /*******************************************************************
2692 ********************************************************************/
2694 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2696 SAM_ACCOUNT *pwd = NULL;
2700 if(!pdb_getsampwsid(pwd, sid)) {
2706 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2711 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2715 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2719 if (!pdb_set_pass_changed_now (pwd)) {
2724 if(!pdb_update_sam_account(pwd)) {
2733 /*******************************************************************
2735 ********************************************************************/
2737 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2739 SAM_ACCOUNT *pwd = NULL;
2742 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2748 if (!pdb_getsampwsid(pwd, sid)) {
2753 copy_id21_to_sam_passwd(pwd, id21);
2756 * The funny part about the previous two calls is
2757 * that pwd still has the password hashes from the
2758 * passdb entry. These have not been updated from
2759 * id21. I don't know if they need to be set. --jerry
2762 /* write the change out */
2763 if(!pdb_update_sam_account(pwd)) {
2773 /*******************************************************************
2775 ********************************************************************/
2777 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2779 SAM_ACCOUNT *pwd = NULL;
2780 pstring plaintext_buf;
2785 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2791 if (!pdb_getsampwsid(pwd, sid)) {
2796 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2797 pdb_get_username(pwd)));
2799 acct_ctrl = pdb_get_acct_ctrl(pwd);
2801 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
2806 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2811 copy_id23_to_sam_passwd(pwd, id23);
2813 /* if it's a trust account, don't update /etc/passwd */
2814 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2815 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2816 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2817 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2819 /* update the UNIX password */
2820 if (lp_unix_password_sync() )
2821 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2827 ZERO_STRUCT(plaintext_buf);
2829 if(!pdb_update_sam_account(pwd)) {
2839 /*******************************************************************
2841 ********************************************************************/
2843 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2845 SAM_ACCOUNT *pwd = NULL;
2847 pstring plaintext_buf;
2852 if (!pdb_getsampwsid(pwd, sid)) {
2857 DEBUG(5, ("Attempting administrator password change for user %s\n",
2858 pdb_get_username(pwd)));
2860 acct_ctrl = pdb_get_acct_ctrl(pwd);
2862 ZERO_STRUCT(plaintext_buf);
2864 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) {
2869 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2874 /* if it's a trust account, don't update /etc/passwd */
2875 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2876 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2877 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2878 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2880 /* update the UNIX password */
2881 if (lp_unix_password_sync()) {
2882 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2889 ZERO_STRUCT(plaintext_buf);
2891 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2893 /* update the SAMBA password */
2894 if(!pdb_update_sam_account(pwd)) {
2904 /*******************************************************************
2905 samr_reply_set_userinfo
2906 ********************************************************************/
2908 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2911 POLICY_HND *pol = &q_u->pol;
2912 uint16 switch_value = q_u->switch_value;
2913 SAM_USERINFO_CTR *ctr = q_u->ctr;
2915 uint32 acc_required;
2917 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2919 r_u->status = NT_STATUS_OK;
2921 /* find the policy handle. open a policy on it. */
2922 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2923 return NT_STATUS_INVALID_HANDLE;
2925 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
2926 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2930 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
2933 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2934 return NT_STATUS_INVALID_INFO_CLASS;
2937 /* ok! user info levels (lots: see MSDEV help), off we go... */
2938 switch (switch_value) {
2940 if (!set_user_info_12(ctr->info.id12, &sid))
2941 return NT_STATUS_ACCESS_DENIED;
2945 SamOEMhash(ctr->info.id24->pass, p->session_key, 516);
2947 dump_data(100, (char *)ctr->info.id24->pass, 516);
2949 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
2950 return NT_STATUS_ACCESS_DENIED;
2956 * Currently we don't really know how to unmarshall
2957 * the level 25 struct, and the password encryption
2958 * is different. This is a placeholder for when we
2959 * do understand it. In the meantime just return INVALID
2960 * info level and W2K SP2 drops down to level 23... JRA.
2963 SamOEMhash(ctr->info.id25->pass, p->session_key, 532);
2965 dump_data(100, (char *)ctr->info.id25->pass, 532);
2967 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
2968 return NT_STATUS_ACCESS_DENIED;
2971 return NT_STATUS_INVALID_INFO_CLASS;
2974 SamOEMhash(ctr->info.id23->pass, p->session_key, 516);
2976 dump_data(100, (char *)ctr->info.id23->pass, 516);
2978 if (!set_user_info_23(ctr->info.id23, &sid))
2979 return NT_STATUS_ACCESS_DENIED;
2983 return NT_STATUS_INVALID_INFO_CLASS;
2989 /*******************************************************************
2990 samr_reply_set_userinfo2
2991 ********************************************************************/
2993 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
2996 SAM_USERINFO_CTR *ctr = q_u->ctr;
2997 POLICY_HND *pol = &q_u->pol;
2998 uint16 switch_value = q_u->switch_value;
3000 uint32 acc_required;
3002 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3004 r_u->status = NT_STATUS_OK;
3006 /* find the policy handle. open a policy on it. */
3007 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3008 return NT_STATUS_INVALID_HANDLE;
3010 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3011 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3015 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3018 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3019 return NT_STATUS_INVALID_INFO_CLASS;
3022 switch_value=ctr->switch_value;
3024 /* ok! user info levels (lots: see MSDEV help), off we go... */
3025 switch (switch_value) {
3027 if (!set_user_info_21(ctr->info.id21, &sid))
3028 return NT_STATUS_ACCESS_DENIED;
3031 if (!set_user_info_10(ctr->info.id10, &sid))
3032 return NT_STATUS_ACCESS_DENIED;
3035 /* Used by AS/U JRA. */
3036 if (!set_user_info_12(ctr->info.id12, &sid))
3037 return NT_STATUS_ACCESS_DENIED;
3040 return NT_STATUS_INVALID_INFO_CLASS;
3046 /*********************************************************************
3047 _samr_query_aliasmem
3048 *********************************************************************/
3050 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3052 int num_groups = 0, tmp_num_groups=0;
3053 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3054 struct samr_info *info = NULL;
3060 /* until i see a real useraliases query, we fack one up */
3062 /* I have seen one, JFM 2/12/2001 */
3064 * Explanation of what this call does:
3065 * for all the SID given in the request:
3066 * return a list of alias (local groups)
3067 * that have those SID as members.
3069 * and that's the alias in the domain specified
3070 * in the policy_handle
3072 * if the policy handle is on an incorrect sid
3073 * for example a user's sid
3074 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3077 r_u->status = NT_STATUS_OK;
3079 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3081 /* find the policy handle. open a policy on it. */
3082 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3083 return NT_STATUS_INVALID_HANDLE;
3085 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3086 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3088 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3089 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3090 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3091 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3095 if (!sid_check_is_domain(&info->sid) &&
3096 !sid_check_is_builtin(&info->sid))
3097 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3100 for (i=0; i<q_u->num_sids1; i++) {
3102 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3105 * if there is an error, we just continue as
3106 * it can be an unfound user or group
3108 if (!NT_STATUS_IS_OK(r_u->status)) {
3109 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3113 if (tmp_num_groups==0) {
3114 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3118 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3119 if (new_rids==NULL) {
3120 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3121 return NT_STATUS_NO_MEMORY;
3125 for (j=0; j<tmp_num_groups; j++)
3126 rids[j+num_groups]=tmp_rids[j];
3128 safe_free(tmp_rids);
3130 num_groups+=tmp_num_groups;
3133 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3134 return NT_STATUS_OK;
3137 /*********************************************************************
3138 _samr_query_aliasmem
3139 *********************************************************************/
3141 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3153 fstring alias_sid_str;
3156 SAM_ACCOUNT *sam_user = NULL;
3160 /* find the policy handle. open a policy on it. */
3161 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3162 return NT_STATUS_INVALID_HANDLE;
3164 if (!NT_STATUS_IS_OK(r_u->status =
3165 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3169 sid_copy(&als_sid, &alias_sid);
3170 sid_to_string(alias_sid_str, &alias_sid);
3171 sid_split_rid(&alias_sid, &alias_rid);
3173 DEBUG(10, ("sid is %s\n", alias_sid_str));
3175 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
3176 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3177 if(!get_builtin_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
3178 return NT_STATUS_NO_SUCH_ALIAS;
3180 if (sid_equal(&alias_sid, get_global_sam_sid())) {
3181 DEBUG(10, ("lookup on Server SID\n"));
3182 if(!get_local_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
3183 return NT_STATUS_NO_SUCH_ALIAS;
3187 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3188 return NT_STATUS_NO_SUCH_ALIAS;
3190 DEBUG(10, ("sid is %s\n", alias_sid_str));
3191 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
3192 if (num_uids!=0 && sid == NULL)
3193 return NT_STATUS_NO_MEMORY;
3195 for (i = 0; i < num_uids; i++) {
3196 struct passwd *pass;
3199 sid_copy(&temp_sid, get_global_sam_sid());
3201 pass = getpwuid_alloc(uid[i]);
3202 if (!pass) continue;
3204 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3210 check = pdb_getsampwnam(sam_user, pass->pw_name);
3213 if (check != True) {
3214 pdb_free_sam(&sam_user);
3219 rid = pdb_get_user_rid(sam_user);
3221 pdb_free_sam(&sam_user);
3226 pdb_free_sam(&sam_user);
3229 sid_append_rid(&temp_sid, rid);
3231 init_dom_sid2(&sid[i], &temp_sid);
3234 DEBUG(10, ("sid is %s\n", alias_sid_str));
3235 init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
3237 return NT_STATUS_OK;
3240 /*********************************************************************
3241 _samr_query_groupmem
3242 *********************************************************************/
3244 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3250 fstring group_sid_str;
3258 SAM_ACCOUNT *sam_user = NULL;
3262 /* find the policy handle. open a policy on it. */
3263 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3264 return NT_STATUS_INVALID_HANDLE;
3266 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3270 /* todo: change to use sid_compare_front */
3272 sid_split_rid(&group_sid, &group_rid);
3273 sid_to_string(group_sid_str, &group_sid);
3274 DEBUG(10, ("sid is %s\n", group_sid_str));
3276 /* can we get a query for an SID outside our domain ? */
3277 if (!sid_equal(&group_sid, get_global_sam_sid()))
3278 return NT_STATUS_NO_SUCH_GROUP;
3280 sid_append_rid(&group_sid, group_rid);
3281 DEBUG(10, ("lookup on Domain SID\n"));
3283 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3284 return NT_STATUS_NO_SUCH_GROUP;
3286 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3287 return NT_STATUS_NO_SUCH_GROUP;
3289 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3290 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3292 if (num_uids!=0 && (rid==NULL || attr==NULL))
3293 return NT_STATUS_NO_MEMORY;
3295 for (i=0; i<num_uids; i++) {
3296 struct passwd *pass;
3299 pass = getpwuid_alloc(uid[i]);
3300 if (!pass) continue;
3302 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3308 check = pdb_getsampwnam(sam_user, pass->pw_name);
3311 if (check != True) {
3312 pdb_free_sam(&sam_user);
3317 urid = pdb_get_user_rid(sam_user);
3319 pdb_free_sam(&sam_user);
3324 pdb_free_sam(&sam_user);
3328 attr[i] = SID_NAME_USER;
3331 init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
3333 return NT_STATUS_OK;
3336 /*********************************************************************
3338 *********************************************************************/
3340 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3343 fstring alias_sid_str;
3350 SAM_ACCOUNT *sam_user = NULL;
3354 /* Find the policy handle. Open a policy on it. */
3355 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3356 return NT_STATUS_INVALID_HANDLE;
3358 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3362 sid_to_string(alias_sid_str, &alias_sid);
3363 DEBUG(10, ("sid is %s\n", alias_sid_str));
3365 if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
3366 DEBUG(10, ("adding member on Server SID\n"));
3367 if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3368 return NT_STATUS_NO_SUCH_ALIAS;
3371 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
3372 DEBUG(10, ("adding member on BUILTIN SID\n"));
3373 if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3374 return NT_STATUS_NO_SUCH_ALIAS;
3377 return NT_STATUS_NO_SUCH_ALIAS;
3380 ret = pdb_init_sam(&sam_user);
3381 if (!NT_STATUS_IS_OK(ret))
3384 check = pdb_getsampwsid(sam_user, &q_u->sid.sid);
3386 if (check != True) {
3387 pdb_free_sam(&sam_user);
3388 return NT_STATUS_NO_SUCH_USER;
3391 /* check a real user exist before we run the script to add a user to a group */
3392 if (NT_STATUS_IS_ERR(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3393 pdb_free_sam(&sam_user);
3394 return NT_STATUS_NO_SUCH_USER;
3397 pdb_free_sam(&sam_user);
3399 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3400 return NT_STATUS_NO_SUCH_USER;
3403 if ((grp=getgrgid(map.gid)) == NULL) {
3405 return NT_STATUS_NO_SUCH_ALIAS;
3408 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3409 fstrcpy(grp_name, grp->gr_name);
3411 /* if the user is already in the group */
3412 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3414 return NT_STATUS_MEMBER_IN_ALIAS;
3418 * ok, the group exist, the user exist, the user is not in the group,
3419 * we can (finally) add it to the group !
3421 smb_add_user_group(grp_name, pwd->pw_name);
3423 /* check if the user has been added then ... */
3424 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3426 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3430 return NT_STATUS_OK;
3433 /*********************************************************************
3435 *********************************************************************/
3437 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3440 fstring alias_sid_str;
3444 SAM_ACCOUNT *sam_pass=NULL;
3447 /* Find the policy handle. Open a policy on it. */
3448 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3449 return NT_STATUS_INVALID_HANDLE;
3451 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3455 sid_to_string(alias_sid_str, &alias_sid);
3456 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
3458 if (!sid_check_is_in_our_domain(&alias_sid) &&
3459 !sid_check_is_in_builtin(&alias_sid)) {
3460 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3461 return NT_STATUS_NO_SUCH_ALIAS;
3464 if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3465 return NT_STATUS_NO_SUCH_ALIAS;
3467 if ((grp=getgrgid(map.gid)) == NULL)
3468 return NT_STATUS_NO_SUCH_ALIAS;
3470 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3471 fstrcpy(grp_name, grp->gr_name);
3473 /* check if the user exists before trying to remove it from the group */
3474 pdb_init_sam(&sam_pass);
3475 if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
3476 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3477 pdb_free_sam(&sam_pass);
3478 return NT_STATUS_NO_SUCH_USER;
3481 /* if the user is not in the group */
3482 if(!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3483 pdb_free_sam(&sam_pass);
3484 return NT_STATUS_MEMBER_IN_ALIAS;
3487 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3489 /* check if the user has been removed then ... */
3490 if(user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3491 pdb_free_sam(&sam_pass);
3492 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3495 pdb_free_sam(&sam_pass);
3496 return NT_STATUS_OK;
3499 /*********************************************************************
3501 *********************************************************************/
3503 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3507 fstring group_sid_str;
3514 SAM_ACCOUNT *sam_user=NULL;
3518 /* Find the policy handle. Open a policy on it. */
3519 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3520 return NT_STATUS_INVALID_HANDLE;
3522 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3526 sid_to_string(group_sid_str, &group_sid);
3527 DEBUG(10, ("sid is %s\n", group_sid_str));
3529 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3530 return NT_STATUS_NO_SUCH_GROUP;
3532 DEBUG(10, ("lookup on Domain SID\n"));
3534 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3535 return NT_STATUS_NO_SUCH_GROUP;
3537 sid_copy(&user_sid, get_global_sam_sid());
3538 sid_append_rid(&user_sid, q_u->rid);
3540 ret = pdb_init_sam(&sam_user);
3541 if (!NT_STATUS_IS_OK(ret))
3544 check = pdb_getsampwsid(sam_user, &user_sid);
3546 if (check != True) {
3547 pdb_free_sam(&sam_user);
3548 return NT_STATUS_NO_SUCH_USER;
3551 /* check a real user exist before we run the script to add a user to a group */
3552 if (NT_STATUS_IS_ERR(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3553 pdb_free_sam(&sam_user);
3554 return NT_STATUS_NO_SUCH_USER;
3557 pdb_free_sam(&sam_user);
3559 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3560 return NT_STATUS_NO_SUCH_USER;
3563 if ((grp=getgrgid(map.gid)) == NULL) {
3565 return NT_STATUS_NO_SUCH_GROUP;
3568 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3569 fstrcpy(grp_name, grp->gr_name);
3571 /* if the user is already in the group */
3572 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3574 return NT_STATUS_MEMBER_IN_GROUP;
3578 * ok, the group exist, the user exist, the user is not in the group,
3580 * we can (finally) add it to the group !
3583 smb_add_user_group(grp_name, pwd->pw_name);
3585 /* check if the user has been added then ... */
3586 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3588 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3592 return NT_STATUS_OK;
3595 /*********************************************************************
3597 *********************************************************************/
3599 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3603 SAM_ACCOUNT *sam_pass=NULL;
3610 * delete the group member named q_u->rid
3611 * who is a member of the sid associated with the handle
3612 * the rid is a user's rid as the group is a domain group.
3615 /* Find the policy handle. Open a policy on it. */
3616 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3617 return NT_STATUS_INVALID_HANDLE;
3619 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3623 if (!sid_check_is_in_our_domain(&group_sid))
3624 return NT_STATUS_NO_SUCH_GROUP;
3626 sid_copy(&user_sid, get_global_sam_sid());
3627 sid_append_rid(&user_sid, q_u->rid);
3629 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3630 return NT_STATUS_NO_SUCH_GROUP;
3632 if ((grp=getgrgid(map.gid)) == NULL)
3633 return NT_STATUS_NO_SUCH_GROUP;
3635 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3636 fstrcpy(grp_name, grp->gr_name);
3638 /* check if the user exists before trying to remove it from the group */
3639 pdb_init_sam(&sam_pass);
3640 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3641 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3642 pdb_free_sam(&sam_pass);
3643 return NT_STATUS_NO_SUCH_USER;
3646 /* if the user is not in the group */
3647 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3648 pdb_free_sam(&sam_pass);
3649 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3652 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3654 /* check if the user has been removed then ... */
3655 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3656 pdb_free_sam(&sam_pass);
3657 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3660 pdb_free_sam(&sam_pass);
3661 return NT_STATUS_OK;
3665 /****************************************************************************
3666 Delete a UNIX user on demand.
3667 ****************************************************************************/
3669 static int smb_delete_user(const char *unix_user)
3674 pstrcpy(del_script, lp_deluser_script());
3677 all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3678 ret = smbrun(del_script,NULL);
3679 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3683 /*********************************************************************
3684 _samr_delete_dom_user
3685 *********************************************************************/
3687 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3690 SAM_ACCOUNT *sam_pass=NULL;
3693 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3695 /* Find the policy handle. Open a policy on it. */
3696 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3697 return NT_STATUS_INVALID_HANDLE;
3699 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3703 if (!sid_check_is_in_our_domain(&user_sid))
3704 return NT_STATUS_CANNOT_DELETE;
3706 /* check if the user exists before trying to delete */
3707 pdb_init_sam(&sam_pass);
3708 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3709 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3710 pdb_free_sam(&sam_pass);
3711 return NT_STATUS_NO_SUCH_USER;
3714 /* delete the unix side */
3716 * note: we don't check if the delete really happened
3717 * as the script is not necessary present
3718 * and maybe the sysadmin doesn't want to delete the unix side
3720 smb_delete_user(pdb_get_username(sam_pass));
3722 /* and delete the samba side */
3723 if (!pdb_delete_sam_account(sam_pass)) {
3724 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3725 pdb_free_sam(&sam_pass);
3726 return NT_STATUS_CANNOT_DELETE;
3729 pdb_free_sam(&sam_pass);
3731 if (!close_policy_hnd(p, &q_u->user_pol))
3732 return NT_STATUS_OBJECT_NAME_INVALID;
3734 return NT_STATUS_OK;
3737 /*********************************************************************
3738 _samr_delete_dom_group
3739 *********************************************************************/
3741 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3746 fstring group_sid_str;
3752 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3754 /* Find the policy handle. Open a policy on it. */
3755 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3756 return NT_STATUS_INVALID_HANDLE;
3758 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3762 sid_copy(&dom_sid, &group_sid);
3763 sid_to_string(group_sid_str, &dom_sid);
3764 sid_split_rid(&dom_sid, &group_rid);
3766 DEBUG(10, ("sid is %s\n", group_sid_str));
3768 /* we check if it's our SID before deleting */
3769 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3770 return NT_STATUS_NO_SUCH_GROUP;
3772 DEBUG(10, ("lookup on Domain SID\n"));
3774 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3775 return NT_STATUS_NO_SUCH_GROUP;
3779 /* check if group really exists */
3780 if ( (grp=getgrgid(gid)) == NULL)
3781 return NT_STATUS_NO_SUCH_GROUP;
3783 /* we can delete the UNIX group */
3784 smb_delete_group(grp->gr_name);
3786 /* check if the group has been successfully deleted */
3787 if ( (grp=getgrgid(gid)) != NULL)
3788 return NT_STATUS_ACCESS_DENIED;
3790 if(!pdb_delete_group_mapping_entry(group_sid))
3791 return NT_STATUS_ACCESS_DENIED;
3793 if (!close_policy_hnd(p, &q_u->group_pol))
3794 return NT_STATUS_OBJECT_NAME_INVALID;
3796 return NT_STATUS_OK;
3799 /*********************************************************************
3800 _samr_delete_dom_alias
3801 *********************************************************************/
3803 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3808 fstring alias_sid_str;
3814 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3816 /* Find the policy handle. Open a policy on it. */
3817 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3818 return NT_STATUS_INVALID_HANDLE;
3820 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3824 sid_copy(&dom_sid, &alias_sid);
3825 sid_to_string(alias_sid_str, &dom_sid);
3826 sid_split_rid(&dom_sid, &alias_rid);
3828 DEBUG(10, ("sid is %s\n", alias_sid_str));
3830 /* we check if it's our SID before deleting */
3831 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3832 return NT_STATUS_NO_SUCH_ALIAS;
3834 DEBUG(10, ("lookup on Local SID\n"));
3836 if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3837 return NT_STATUS_NO_SUCH_ALIAS;
3841 /* check if group really exists */
3842 if ( (grp=getgrgid(gid)) == NULL)
3843 return NT_STATUS_NO_SUCH_ALIAS;
3845 /* we can delete the UNIX group */
3846 smb_delete_group(grp->gr_name);
3848 /* check if the group has been successfully deleted */
3849 if ( (grp=getgrgid(gid)) != NULL)
3850 return NT_STATUS_ACCESS_DENIED;
3852 /* don't check if we removed it as it could be an un-mapped group */
3853 pdb_delete_group_mapping_entry(alias_sid);
3855 if (!close_policy_hnd(p, &q_u->alias_pol))
3856 return NT_STATUS_OBJECT_NAME_INVALID;
3858 return NT_STATUS_OK;
3861 /*********************************************************************
3862 _samr_create_dom_group
3863 *********************************************************************/
3865 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3872 struct samr_info *info;
3873 PRIVILEGE_SET priv_set;
3877 init_privilege(&priv_set);
3879 /* Find the policy handle. Open a policy on it. */
3880 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3881 return NT_STATUS_INVALID_HANDLE;
3883 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3887 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3888 return NT_STATUS_ACCESS_DENIED;
3890 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3892 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3894 /* check if group already exist */
3895 if ((grp=getgrnam(name)) != NULL)
3896 return NT_STATUS_GROUP_EXISTS;
3898 /* we can create the UNIX group */
3899 if (smb_create_group(name, &gid) != 0)
3900 return NT_STATUS_ACCESS_DENIED;
3902 /* check if the group has been successfully created */
3903 if ((grp=getgrgid(gid)) == NULL)
3904 return NT_STATUS_ACCESS_DENIED;
3906 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3908 /* add the group to the mapping table */
3909 sid_copy(&info_sid, get_global_sam_sid());
3910 sid_append_rid(&info_sid, r_u->rid);
3911 sid_to_string(sid_string, &info_sid);
3913 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
3914 return NT_STATUS_ACCESS_DENIED;
3916 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3917 return NT_STATUS_NO_MEMORY;
3919 /* get a (unique) handle. open a policy on it. */
3920 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3921 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3923 return NT_STATUS_OK;
3926 /*********************************************************************
3927 _samr_create_dom_alias
3928 *********************************************************************/
3930 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3937 struct samr_info *info;
3938 PRIVILEGE_SET priv_set;
3942 init_privilege(&priv_set);
3944 /* Find the policy handle. Open a policy on it. */
3945 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
3946 return NT_STATUS_INVALID_HANDLE;
3948 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3952 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3953 return NT_STATUS_ACCESS_DENIED;
3955 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3957 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3959 /* check if group already exists */
3960 if ( (grp=getgrnam(name)) != NULL)
3961 return NT_STATUS_GROUP_EXISTS;
3963 /* we can create the UNIX group */
3964 if (smb_create_group(name, &gid) != 0)
3965 return NT_STATUS_ACCESS_DENIED;
3967 /* check if the group has been successfully created */
3968 if ((grp=getgrgid(gid)) == NULL)
3969 return NT_STATUS_ACCESS_DENIED;
3971 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3973 sid_copy(&info_sid, get_global_sam_sid());
3974 sid_append_rid(&info_sid, r_u->rid);
3975 sid_to_string(sid_string, &info_sid);
3977 /* add the group to the mapping table */
3978 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
3979 return NT_STATUS_ACCESS_DENIED;
3981 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3982 return NT_STATUS_NO_MEMORY;
3984 /* get a (unique) handle. open a policy on it. */
3985 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
3986 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3988 return NT_STATUS_OK;
3991 /*********************************************************************
3992 _samr_query_groupinfo
3994 sends the name/comment pair of a domain group
3995 level 1 send also the number of users of that group
3996 *********************************************************************/
3998 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4004 GROUP_INFO_CTR *ctr;
4007 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4008 return NT_STATUS_INVALID_HANDLE;
4010 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4014 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
4015 return NT_STATUS_INVALID_HANDLE;
4017 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
4019 return NT_STATUS_NO_MEMORY;
4021 switch (q_u->switch_level) {
4023 ctr->switch_value1 = 1;
4024 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
4025 return NT_STATUS_NO_SUCH_GROUP;
4026 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
4030 ctr->switch_value1 = 3;
4031 init_samr_group_info3(&ctr->group.info3);
4034 ctr->switch_value1 = 4;
4035 init_samr_group_info4(&ctr->group.info4, map.comment);
4038 return NT_STATUS_INVALID_INFO_CLASS;
4041 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4043 return NT_STATUS_OK;
4046 /*********************************************************************
4049 update a domain group's comment.
4050 *********************************************************************/
4052 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4056 GROUP_INFO_CTR *ctr;
4059 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4060 return NT_STATUS_INVALID_HANDLE;
4062 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4066 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
4067 return NT_STATUS_NO_SUCH_GROUP;
4071 switch (ctr->switch_value1) {
4073 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4076 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4079 free_privilege(&map.priv_set);
4080 return NT_STATUS_INVALID_INFO_CLASS;
4083 if(!pdb_update_group_mapping_entry(&map)) {
4084 free_privilege(&map.priv_set);
4085 return NT_STATUS_NO_SUCH_GROUP;
4088 free_privilege(&map.priv_set);
4090 return NT_STATUS_OK;
4093 /*********************************************************************
4096 update an alias's comment.
4097 *********************************************************************/
4099 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4103 ALIAS_INFO_CTR *ctr;
4106 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4107 return NT_STATUS_INVALID_HANDLE;
4109 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4113 if (!get_local_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
4114 return NT_STATUS_NO_SUCH_GROUP;
4118 switch (ctr->switch_value1) {
4120 unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
4123 free_privilege(&map.priv_set);
4124 return NT_STATUS_INVALID_INFO_CLASS;
4127 if(!pdb_update_group_mapping_entry(&map)) {
4128 free_privilege(&map.priv_set);
4129 return NT_STATUS_NO_SUCH_GROUP;
4132 free_privilege(&map.priv_set);
4134 return NT_STATUS_OK;
4137 /*********************************************************************
4138 _samr_get_dom_pwinfo
4139 *********************************************************************/
4141 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4143 /* Perform access check. Since this rpc does not require a
4144 policy handle it will not be caught by the access checks on
4145 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4147 if (!pipe_access_check(p)) {
4148 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4149 r_u->status = NT_STATUS_ACCESS_DENIED;
4153 /* Actually, returning zeros here works quite well :-). */
4155 return NT_STATUS_OK;
4158 /*********************************************************************
4160 *********************************************************************/
4162 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4167 struct samr_info *info;
4168 SEC_DESC *psd = NULL;
4175 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4176 return NT_STATUS_INVALID_HANDLE;
4178 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4182 /*check if access can be granted as requested by client. */
4183 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4184 se_map_generic(&des_access,&grp_generic_mapping);
4185 if (!NT_STATUS_IS_OK(status =
4186 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4187 des_access, &acc_granted, "_samr_open_group"))) {
4192 /* this should not be hard-coded like this */
4193 if (!sid_equal(&sid, get_global_sam_sid()))
4194 return NT_STATUS_ACCESS_DENIED;
4196 sid_copy(&info_sid, get_global_sam_sid());
4197 sid_append_rid(&info_sid, q_u->rid_group);
4198 sid_to_string(sid_string, &info_sid);
4200 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4201 return NT_STATUS_NO_MEMORY;
4203 info->acc_granted = acc_granted;
4205 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4207 /* check if that group really exists */
4208 if (!get_domain_group_from_sid(info->sid, &map, MAPPING_WITHOUT_PRIV))
4209 return NT_STATUS_NO_SUCH_GROUP;
4211 /* get a (unique) handle. open a policy on it. */
4212 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4213 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4215 return NT_STATUS_OK;
4218 /*********************************************************************
4220 *********************************************************************/
4222 NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
4224 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
4225 return NT_STATUS_NOT_IMPLEMENTED;
4228 /*******************************************************************
4230 ********************************************************************/
4232 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4234 struct samr_info *info = NULL;
4236 uint32 min_pass_len,pass_hist,flag;
4237 time_t u_expire, u_min_age;
4238 NTTIME nt_expire, nt_min_age;
4240 time_t u_lock_duration, u_reset_time;
4241 NTTIME nt_lock_duration, nt_reset_time;
4247 uint32 num_users=0, num_groups=0, num_aliases=0;
4249 uint32 account_policy_temp;
4251 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4252 return NT_STATUS_NO_MEMORY;
4256 r_u->status = NT_STATUS_OK;
4258 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4260 /* find the policy handle. open a policy on it. */
4261 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4262 return NT_STATUS_INVALID_HANDLE;
4264 switch (q_u->switch_value) {
4266 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4267 min_pass_len = account_policy_temp;
4269 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4270 pass_hist = account_policy_temp;
4272 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4273 flag = account_policy_temp;
4275 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4276 u_expire = account_policy_temp;
4278 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4279 u_min_age = account_policy_temp;
4281 unix_to_nt_time_abs(&nt_expire, u_expire);
4282 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4284 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4285 flag, nt_expire, nt_min_age);
4289 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4291 if (!NT_STATUS_IS_OK(r_u->status)) {
4292 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4295 num_users=info->disp_info.num_user_account;
4298 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4299 if (NT_STATUS_IS_ERR(r_u->status)) {
4300 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4303 num_groups=info->disp_info.num_group_account;
4306 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4307 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
4308 num_users, num_groups, num_aliases);
4311 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4312 u_logout = account_policy_temp;
4314 unix_to_nt_time_abs(&nt_logout, u_logout);
4316 init_unk_info3(&ctr->info.inf3, nt_logout);
4319 init_unk_info5(&ctr->info.inf5, global_myname());
4322 init_unk_info6(&ctr->info.inf6);
4325 init_unk_info7(&ctr->info.inf7);
4328 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4329 u_lock_duration = account_policy_temp;
4331 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4332 u_reset_time = account_policy_temp;
4334 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4335 lockout = account_policy_temp;
4337 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4338 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4340 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4343 return NT_STATUS_INVALID_INFO_CLASS;
4346 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4348 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4353 /*******************************************************************
4355 ********************************************************************/
4357 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4359 time_t u_expire, u_min_age;
4361 time_t u_lock_duration, u_reset_time;
4363 r_u->status = NT_STATUS_OK;
4365 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4367 /* find the policy handle. open a policy on it. */
4368 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4369 return NT_STATUS_INVALID_HANDLE;
4371 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4373 switch (q_u->switch_value) {
4375 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4376 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4378 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4379 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4380 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4381 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4382 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4387 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4388 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4397 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4398 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count);
4400 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4401 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4402 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4405 return NT_STATUS_INVALID_INFO_CLASS;
4408 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4410 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));