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_winbind_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 switch (lp_server_role()) {
2579 case ROLE_DOMAIN_PDC:
2580 case ROLE_DOMAIN_BDC:
2581 name = lp_workgroup();
2584 name = global_myname();
2587 fstrcpy(dom[0],name);
2589 fstrcpy(dom[1],"Builtin");
2591 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2592 return NT_STATUS_NO_MEMORY;
2594 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2599 /*******************************************************************
2601 ********************************************************************/
2603 NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2606 POLICY_HND domain_pol = q_u->dom_pol;
2607 uint32 alias_rid = q_u->rid_alias;
2608 POLICY_HND *alias_pol = &r_u->pol;
2609 struct samr_info *info = NULL;
2610 SEC_DESC *psd = NULL;
2612 uint32 des_access = q_u->access_mask;
2616 r_u->status = NT_STATUS_OK;
2618 /* find the domain policy and get the SID / access bits stored in the domain policy */
2619 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2620 return NT_STATUS_INVALID_HANDLE;
2622 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2626 /* append the alias' RID to it */
2627 if (!sid_append_rid(&sid, alias_rid))
2628 return NT_STATUS_NO_SUCH_USER;
2630 /*check if access can be granted as requested by client. */
2631 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2632 se_map_generic(&des_access,&ali_generic_mapping);
2633 if (!NT_STATUS_IS_OK(status =
2634 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2635 des_access, &acc_granted, "_samr_open_alias"))) {
2640 * we should check if the rid really exist !!!
2644 /* associate the user's SID with the new handle. */
2645 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2646 return NT_STATUS_NO_MEMORY;
2648 info->acc_granted = acc_granted;
2650 /* get a (unique) handle. open a policy on it. */
2651 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2652 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2657 /*******************************************************************
2659 ********************************************************************/
2661 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2663 SAM_ACCOUNT *pwd =NULL;
2668 ret = pdb_getsampwsid(pwd, sid);
2676 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2681 /* FIX ME: check if the value is really changed --metze */
2682 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2687 if(!pdb_update_sam_account(pwd)) {
2697 /*******************************************************************
2699 ********************************************************************/
2701 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2703 SAM_ACCOUNT *pwd = NULL;
2707 if(!pdb_getsampwsid(pwd, sid)) {
2713 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2718 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2722 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2726 if (!pdb_set_pass_changed_now (pwd)) {
2731 if(!pdb_update_sam_account(pwd)) {
2740 /*******************************************************************
2742 ********************************************************************/
2744 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2746 SAM_ACCOUNT *pwd = NULL;
2749 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2755 if (!pdb_getsampwsid(pwd, sid)) {
2760 copy_id21_to_sam_passwd(pwd, id21);
2763 * The funny part about the previous two calls is
2764 * that pwd still has the password hashes from the
2765 * passdb entry. These have not been updated from
2766 * id21. I don't know if they need to be set. --jerry
2769 /* write the change out */
2770 if(!pdb_update_sam_account(pwd)) {
2780 /*******************************************************************
2782 ********************************************************************/
2784 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2786 SAM_ACCOUNT *pwd = NULL;
2787 pstring plaintext_buf;
2792 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2798 if (!pdb_getsampwsid(pwd, sid)) {
2803 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2804 pdb_get_username(pwd)));
2806 acct_ctrl = pdb_get_acct_ctrl(pwd);
2808 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
2813 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2818 copy_id23_to_sam_passwd(pwd, id23);
2820 /* if it's a trust account, don't update /etc/passwd */
2821 if ( (!IS_SAM_UNIX_USER(pwd)) ||
2822 ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2823 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2824 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2825 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2827 /* update the UNIX password */
2828 if (lp_unix_password_sync() )
2829 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2835 ZERO_STRUCT(plaintext_buf);
2837 if(!pdb_update_sam_account(pwd)) {
2847 /*******************************************************************
2849 ********************************************************************/
2851 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2853 SAM_ACCOUNT *pwd = NULL;
2855 pstring plaintext_buf;
2860 if (!pdb_getsampwsid(pwd, sid)) {
2865 DEBUG(5, ("Attempting administrator password change for user %s\n",
2866 pdb_get_username(pwd)));
2868 acct_ctrl = pdb_get_acct_ctrl(pwd);
2870 ZERO_STRUCT(plaintext_buf);
2872 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) {
2877 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2882 /* if it's a trust account, don't update /etc/passwd */
2883 if ( (!IS_SAM_UNIX_USER(pwd)) ||
2884 ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2885 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2886 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2887 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2889 /* update the UNIX password */
2890 if (lp_unix_password_sync()) {
2891 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2898 ZERO_STRUCT(plaintext_buf);
2900 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2902 /* update the SAMBA password */
2903 if(!pdb_update_sam_account(pwd)) {
2913 /*******************************************************************
2914 samr_reply_set_userinfo
2915 ********************************************************************/
2917 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2920 POLICY_HND *pol = &q_u->pol;
2921 uint16 switch_value = q_u->switch_value;
2922 SAM_USERINFO_CTR *ctr = q_u->ctr;
2924 uint32 acc_required;
2926 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2928 r_u->status = NT_STATUS_OK;
2930 /* find the policy handle. open a policy on it. */
2931 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2932 return NT_STATUS_INVALID_HANDLE;
2934 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
2935 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2939 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
2942 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2943 return NT_STATUS_INVALID_INFO_CLASS;
2946 /* ok! user info levels (lots: see MSDEV help), off we go... */
2947 switch (switch_value) {
2949 if (!set_user_info_12(ctr->info.id12, &sid))
2950 return NT_STATUS_ACCESS_DENIED;
2954 SamOEMhash(ctr->info.id24->pass, p->session_key, 516);
2956 dump_data(100, (char *)ctr->info.id24->pass, 516);
2958 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
2959 return NT_STATUS_ACCESS_DENIED;
2965 * Currently we don't really know how to unmarshall
2966 * the level 25 struct, and the password encryption
2967 * is different. This is a placeholder for when we
2968 * do understand it. In the meantime just return INVALID
2969 * info level and W2K SP2 drops down to level 23... JRA.
2972 SamOEMhash(ctr->info.id25->pass, p->session_key, 532);
2974 dump_data(100, (char *)ctr->info.id25->pass, 532);
2976 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
2977 return NT_STATUS_ACCESS_DENIED;
2980 return NT_STATUS_INVALID_INFO_CLASS;
2983 SamOEMhash(ctr->info.id23->pass, p->session_key, 516);
2985 dump_data(100, (char *)ctr->info.id23->pass, 516);
2987 if (!set_user_info_23(ctr->info.id23, &sid))
2988 return NT_STATUS_ACCESS_DENIED;
2992 return NT_STATUS_INVALID_INFO_CLASS;
2998 /*******************************************************************
2999 samr_reply_set_userinfo2
3000 ********************************************************************/
3002 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3005 SAM_USERINFO_CTR *ctr = q_u->ctr;
3006 POLICY_HND *pol = &q_u->pol;
3007 uint16 switch_value = q_u->switch_value;
3009 uint32 acc_required;
3011 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3013 r_u->status = NT_STATUS_OK;
3015 /* find the policy handle. open a policy on it. */
3016 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3017 return NT_STATUS_INVALID_HANDLE;
3019 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3020 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3024 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3027 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3028 return NT_STATUS_INVALID_INFO_CLASS;
3031 switch_value=ctr->switch_value;
3033 /* ok! user info levels (lots: see MSDEV help), off we go... */
3034 switch (switch_value) {
3036 if (!set_user_info_21(ctr->info.id21, &sid))
3037 return NT_STATUS_ACCESS_DENIED;
3040 if (!set_user_info_10(ctr->info.id10, &sid))
3041 return NT_STATUS_ACCESS_DENIED;
3044 /* Used by AS/U JRA. */
3045 if (!set_user_info_12(ctr->info.id12, &sid))
3046 return NT_STATUS_ACCESS_DENIED;
3049 return NT_STATUS_INVALID_INFO_CLASS;
3055 /*********************************************************************
3056 _samr_query_aliasmem
3057 *********************************************************************/
3059 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3061 int num_groups = 0, tmp_num_groups=0;
3062 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3063 struct samr_info *info = NULL;
3069 /* until i see a real useraliases query, we fack one up */
3071 /* I have seen one, JFM 2/12/2001 */
3073 * Explanation of what this call does:
3074 * for all the SID given in the request:
3075 * return a list of alias (local groups)
3076 * that have those SID as members.
3078 * and that's the alias in the domain specified
3079 * in the policy_handle
3081 * if the policy handle is on an incorrect sid
3082 * for example a user's sid
3083 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3086 r_u->status = NT_STATUS_OK;
3088 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3090 /* find the policy handle. open a policy on it. */
3091 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3092 return NT_STATUS_INVALID_HANDLE;
3094 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3095 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3097 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3098 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3099 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3100 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3104 if (!sid_check_is_domain(&info->sid) &&
3105 !sid_check_is_builtin(&info->sid))
3106 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3109 for (i=0; i<q_u->num_sids1; i++) {
3111 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3114 * if there is an error, we just continue as
3115 * it can be an unfound user or group
3117 if (!NT_STATUS_IS_OK(r_u->status)) {
3118 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3122 if (tmp_num_groups==0) {
3123 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3127 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3128 if (new_rids==NULL) {
3129 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3130 return NT_STATUS_NO_MEMORY;
3134 for (j=0; j<tmp_num_groups; j++)
3135 rids[j+num_groups]=tmp_rids[j];
3137 safe_free(tmp_rids);
3139 num_groups+=tmp_num_groups;
3142 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3143 return NT_STATUS_OK;
3146 /*********************************************************************
3147 _samr_query_aliasmem
3148 *********************************************************************/
3150 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3162 fstring alias_sid_str;
3165 SAM_ACCOUNT *sam_user = NULL;
3169 /* find the policy handle. open a policy on it. */
3170 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3171 return NT_STATUS_INVALID_HANDLE;
3173 if (!NT_STATUS_IS_OK(r_u->status =
3174 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3178 sid_copy(&als_sid, &alias_sid);
3179 sid_to_string(alias_sid_str, &alias_sid);
3180 sid_split_rid(&alias_sid, &alias_rid);
3182 DEBUG(10, ("sid is %s\n", alias_sid_str));
3184 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
3185 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3186 if(!get_builtin_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
3187 return NT_STATUS_NO_SUCH_ALIAS;
3189 if (sid_equal(&alias_sid, get_global_sam_sid())) {
3190 DEBUG(10, ("lookup on Server SID\n"));
3191 if(!get_local_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
3192 return NT_STATUS_NO_SUCH_ALIAS;
3196 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3197 return NT_STATUS_NO_SUCH_ALIAS;
3199 DEBUG(10, ("sid is %s\n", alias_sid_str));
3200 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
3201 if (num_uids!=0 && sid == NULL)
3202 return NT_STATUS_NO_MEMORY;
3204 for (i = 0; i < num_uids; i++) {
3205 struct passwd *pass;
3208 sid_copy(&temp_sid, get_global_sam_sid());
3210 pass = getpwuid_alloc(uid[i]);
3211 if (!pass) continue;
3213 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3219 check = pdb_getsampwnam(sam_user, pass->pw_name);
3222 if (check != True) {
3223 pdb_free_sam(&sam_user);
3228 rid = pdb_get_user_rid(sam_user);
3230 pdb_free_sam(&sam_user);
3235 pdb_free_sam(&sam_user);
3238 sid_append_rid(&temp_sid, rid);
3240 init_dom_sid2(&sid[i], &temp_sid);
3243 DEBUG(10, ("sid is %s\n", alias_sid_str));
3244 init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
3246 return NT_STATUS_OK;
3249 /*********************************************************************
3250 _samr_query_groupmem
3251 *********************************************************************/
3253 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3259 fstring group_sid_str;
3267 SAM_ACCOUNT *sam_user = NULL;
3271 /* find the policy handle. open a policy on it. */
3272 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3273 return NT_STATUS_INVALID_HANDLE;
3275 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3279 /* todo: change to use sid_compare_front */
3281 sid_split_rid(&group_sid, &group_rid);
3282 sid_to_string(group_sid_str, &group_sid);
3283 DEBUG(10, ("sid is %s\n", group_sid_str));
3285 /* can we get a query for an SID outside our domain ? */
3286 if (!sid_equal(&group_sid, get_global_sam_sid()))
3287 return NT_STATUS_NO_SUCH_GROUP;
3289 sid_append_rid(&group_sid, group_rid);
3290 DEBUG(10, ("lookup on Domain SID\n"));
3292 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3293 return NT_STATUS_NO_SUCH_GROUP;
3295 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3296 return NT_STATUS_NO_SUCH_GROUP;
3298 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3299 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3301 if (num_uids!=0 && (rid==NULL || attr==NULL))
3302 return NT_STATUS_NO_MEMORY;
3304 for (i=0; i<num_uids; i++) {
3305 struct passwd *pass;
3308 pass = getpwuid_alloc(uid[i]);
3309 if (!pass) continue;
3311 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3317 check = pdb_getsampwnam(sam_user, pass->pw_name);
3320 if (check != True) {
3321 pdb_free_sam(&sam_user);
3326 urid = pdb_get_user_rid(sam_user);
3328 pdb_free_sam(&sam_user);
3333 pdb_free_sam(&sam_user);
3337 attr[i] = SID_NAME_USER;
3340 init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
3342 return NT_STATUS_OK;
3345 /*********************************************************************
3347 *********************************************************************/
3349 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3352 fstring alias_sid_str;
3359 SAM_ACCOUNT *sam_user = NULL;
3363 /* Find the policy handle. Open a policy on it. */
3364 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3365 return NT_STATUS_INVALID_HANDLE;
3367 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3371 sid_to_string(alias_sid_str, &alias_sid);
3372 DEBUG(10, ("sid is %s\n", alias_sid_str));
3374 if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
3375 DEBUG(10, ("adding member on Server SID\n"));
3376 if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3377 return NT_STATUS_NO_SUCH_ALIAS;
3380 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
3381 DEBUG(10, ("adding member on BUILTIN SID\n"));
3382 if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3383 return NT_STATUS_NO_SUCH_ALIAS;
3386 return NT_STATUS_NO_SUCH_ALIAS;
3389 ret = pdb_init_sam(&sam_user);
3390 if (!NT_STATUS_IS_OK(ret))
3393 check = pdb_getsampwsid(sam_user, &q_u->sid.sid);
3395 if (check != True) {
3396 pdb_free_sam(&sam_user);
3397 return NT_STATUS_NO_SUCH_USER;
3400 uid = pdb_get_uid(sam_user);
3402 pdb_free_sam(&sam_user);
3403 return NT_STATUS_NO_SUCH_USER;
3406 pdb_free_sam(&sam_user);
3408 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3409 return NT_STATUS_NO_SUCH_USER;
3412 if ((grp=getgrgid(map.gid)) == NULL) {
3414 return NT_STATUS_NO_SUCH_ALIAS;
3417 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3418 fstrcpy(grp_name, grp->gr_name);
3420 /* if the user is already in the group */
3421 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3423 return NT_STATUS_MEMBER_IN_ALIAS;
3427 * ok, the group exist, the user exist, the user is not in the group,
3428 * we can (finally) add it to the group !
3430 smb_add_user_group(grp_name, pwd->pw_name);
3432 /* check if the user has been added then ... */
3433 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3435 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3439 return NT_STATUS_OK;
3442 /*********************************************************************
3444 *********************************************************************/
3446 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3449 fstring alias_sid_str;
3453 SAM_ACCOUNT *sam_pass=NULL;
3456 /* Find the policy handle. Open a policy on it. */
3457 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3458 return NT_STATUS_INVALID_HANDLE;
3460 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3464 sid_to_string(alias_sid_str, &alias_sid);
3465 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
3467 if (!sid_check_is_in_our_domain(&alias_sid) &&
3468 !sid_check_is_in_builtin(&alias_sid)) {
3469 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3470 return NT_STATUS_NO_SUCH_ALIAS;
3473 if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3474 return NT_STATUS_NO_SUCH_ALIAS;
3476 if ((grp=getgrgid(map.gid)) == NULL)
3477 return NT_STATUS_NO_SUCH_ALIAS;
3479 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3480 fstrcpy(grp_name, grp->gr_name);
3482 /* check if the user exists before trying to remove it from the group */
3483 pdb_init_sam(&sam_pass);
3484 if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
3485 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3486 pdb_free_sam(&sam_pass);
3487 return NT_STATUS_NO_SUCH_USER;
3490 /* if the user is not in the group */
3491 if(!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3492 pdb_free_sam(&sam_pass);
3493 return NT_STATUS_MEMBER_IN_ALIAS;
3496 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3498 /* check if the user has been removed then ... */
3499 if(user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3500 pdb_free_sam(&sam_pass);
3501 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3504 pdb_free_sam(&sam_pass);
3505 return NT_STATUS_OK;
3508 /*********************************************************************
3510 *********************************************************************/
3512 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3516 fstring group_sid_str;
3523 SAM_ACCOUNT *sam_user=NULL;
3527 /* Find the policy handle. Open a policy on it. */
3528 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3529 return NT_STATUS_INVALID_HANDLE;
3531 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3535 sid_to_string(group_sid_str, &group_sid);
3536 DEBUG(10, ("sid is %s\n", group_sid_str));
3538 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3539 return NT_STATUS_NO_SUCH_GROUP;
3541 DEBUG(10, ("lookup on Domain SID\n"));
3543 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3544 return NT_STATUS_NO_SUCH_GROUP;
3546 sid_copy(&user_sid, get_global_sam_sid());
3547 sid_append_rid(&user_sid, q_u->rid);
3549 ret = pdb_init_sam(&sam_user);
3550 if (!NT_STATUS_IS_OK(ret))
3553 check = pdb_getsampwsid(sam_user, &user_sid);
3555 if (check != True) {
3556 pdb_free_sam(&sam_user);
3557 return NT_STATUS_NO_SUCH_USER;
3560 uid = pdb_get_uid(sam_user);
3562 pdb_free_sam(&sam_user);
3563 return NT_STATUS_NO_SUCH_USER;
3566 pdb_free_sam(&sam_user);
3568 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3569 return NT_STATUS_NO_SUCH_USER;
3572 if ((grp=getgrgid(map.gid)) == NULL) {
3574 return NT_STATUS_NO_SUCH_GROUP;
3577 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3578 fstrcpy(grp_name, grp->gr_name);
3580 /* if the user is already in the group */
3581 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3583 return NT_STATUS_MEMBER_IN_GROUP;
3587 * ok, the group exist, the user exist, the user is not in the group,
3589 * we can (finally) add it to the group !
3592 smb_add_user_group(grp_name, pwd->pw_name);
3594 /* check if the user has been added then ... */
3595 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3597 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3601 return NT_STATUS_OK;
3604 /*********************************************************************
3606 *********************************************************************/
3608 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3612 SAM_ACCOUNT *sam_pass=NULL;
3619 * delete the group member named q_u->rid
3620 * who is a member of the sid associated with the handle
3621 * the rid is a user's rid as the group is a domain group.
3624 /* Find the policy handle. Open a policy on it. */
3625 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3626 return NT_STATUS_INVALID_HANDLE;
3628 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3632 if (!sid_check_is_in_our_domain(&group_sid))
3633 return NT_STATUS_NO_SUCH_GROUP;
3635 sid_copy(&user_sid, get_global_sam_sid());
3636 sid_append_rid(&user_sid, q_u->rid);
3638 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3639 return NT_STATUS_NO_SUCH_GROUP;
3641 if ((grp=getgrgid(map.gid)) == NULL)
3642 return NT_STATUS_NO_SUCH_GROUP;
3644 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3645 fstrcpy(grp_name, grp->gr_name);
3647 /* check if the user exists before trying to remove it from the group */
3648 pdb_init_sam(&sam_pass);
3649 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3650 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3651 pdb_free_sam(&sam_pass);
3652 return NT_STATUS_NO_SUCH_USER;
3655 /* if the user is not in the group */
3656 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3657 pdb_free_sam(&sam_pass);
3658 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3661 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3663 /* check if the user has been removed then ... */
3664 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3665 pdb_free_sam(&sam_pass);
3666 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3669 pdb_free_sam(&sam_pass);
3670 return NT_STATUS_OK;
3674 /****************************************************************************
3675 Delete a UNIX user on demand.
3676 ****************************************************************************/
3678 static int smb_delete_user(const char *unix_user)
3683 pstrcpy(del_script, lp_deluser_script());
3686 all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3687 ret = smbrun(del_script,NULL);
3688 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3692 /*********************************************************************
3693 _samr_delete_dom_user
3694 *********************************************************************/
3696 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3699 SAM_ACCOUNT *sam_pass=NULL;
3702 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3704 /* Find the policy handle. Open a policy on it. */
3705 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3706 return NT_STATUS_INVALID_HANDLE;
3708 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3712 if (!sid_check_is_in_our_domain(&user_sid))
3713 return NT_STATUS_CANNOT_DELETE;
3715 /* check if the user exists before trying to delete */
3716 pdb_init_sam(&sam_pass);
3717 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3718 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3719 pdb_free_sam(&sam_pass);
3720 return NT_STATUS_NO_SUCH_USER;
3723 /* delete the unix side */
3725 * note: we don't check if the delete really happened
3726 * as the script is not necessary present
3727 * and maybe the sysadmin doesn't want to delete the unix side
3729 smb_delete_user(pdb_get_username(sam_pass));
3731 /* and delete the samba side */
3732 if (!pdb_delete_sam_account(sam_pass)) {
3733 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3734 pdb_free_sam(&sam_pass);
3735 return NT_STATUS_CANNOT_DELETE;
3738 pdb_free_sam(&sam_pass);
3740 if (!close_policy_hnd(p, &q_u->user_pol))
3741 return NT_STATUS_OBJECT_NAME_INVALID;
3743 return NT_STATUS_OK;
3746 /*********************************************************************
3747 _samr_delete_dom_group
3748 *********************************************************************/
3750 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3755 fstring group_sid_str;
3761 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3763 /* Find the policy handle. Open a policy on it. */
3764 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3765 return NT_STATUS_INVALID_HANDLE;
3767 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3771 sid_copy(&dom_sid, &group_sid);
3772 sid_to_string(group_sid_str, &dom_sid);
3773 sid_split_rid(&dom_sid, &group_rid);
3775 DEBUG(10, ("sid is %s\n", group_sid_str));
3777 /* we check if it's our SID before deleting */
3778 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3779 return NT_STATUS_NO_SUCH_GROUP;
3781 DEBUG(10, ("lookup on Domain SID\n"));
3783 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3784 return NT_STATUS_NO_SUCH_GROUP;
3788 /* check if group really exists */
3789 if ( (grp=getgrgid(gid)) == NULL)
3790 return NT_STATUS_NO_SUCH_GROUP;
3792 /* we can delete the UNIX group */
3793 smb_delete_group(grp->gr_name);
3795 /* check if the group has been successfully deleted */
3796 if ( (grp=getgrgid(gid)) != NULL)
3797 return NT_STATUS_ACCESS_DENIED;
3799 if(!pdb_delete_group_mapping_entry(group_sid))
3800 return NT_STATUS_ACCESS_DENIED;
3802 if (!close_policy_hnd(p, &q_u->group_pol))
3803 return NT_STATUS_OBJECT_NAME_INVALID;
3805 return NT_STATUS_OK;
3808 /*********************************************************************
3809 _samr_delete_dom_alias
3810 *********************************************************************/
3812 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3817 fstring alias_sid_str;
3823 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3825 /* Find the policy handle. Open a policy on it. */
3826 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3827 return NT_STATUS_INVALID_HANDLE;
3829 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3833 sid_copy(&dom_sid, &alias_sid);
3834 sid_to_string(alias_sid_str, &dom_sid);
3835 sid_split_rid(&dom_sid, &alias_rid);
3837 DEBUG(10, ("sid is %s\n", alias_sid_str));
3839 /* we check if it's our SID before deleting */
3840 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3841 return NT_STATUS_NO_SUCH_ALIAS;
3843 DEBUG(10, ("lookup on Local SID\n"));
3845 if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3846 return NT_STATUS_NO_SUCH_ALIAS;
3850 /* check if group really exists */
3851 if ( (grp=getgrgid(gid)) == NULL)
3852 return NT_STATUS_NO_SUCH_ALIAS;
3854 /* we can delete the UNIX group */
3855 smb_delete_group(grp->gr_name);
3857 /* check if the group has been successfully deleted */
3858 if ( (grp=getgrgid(gid)) != NULL)
3859 return NT_STATUS_ACCESS_DENIED;
3861 /* don't check if we removed it as it could be an un-mapped group */
3862 pdb_delete_group_mapping_entry(alias_sid);
3864 if (!close_policy_hnd(p, &q_u->alias_pol))
3865 return NT_STATUS_OBJECT_NAME_INVALID;
3867 return NT_STATUS_OK;
3870 /*********************************************************************
3871 _samr_create_dom_group
3872 *********************************************************************/
3874 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3881 struct samr_info *info;
3882 PRIVILEGE_SET priv_set;
3886 init_privilege(&priv_set);
3888 /* Find the policy handle. Open a policy on it. */
3889 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3890 return NT_STATUS_INVALID_HANDLE;
3892 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3896 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3897 return NT_STATUS_ACCESS_DENIED;
3899 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3901 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3903 /* check if group already exist */
3904 if ((grp=getgrnam(name)) != NULL)
3905 return NT_STATUS_GROUP_EXISTS;
3907 /* we can create the UNIX group */
3908 if (smb_create_group(name, &gid) != 0)
3909 return NT_STATUS_ACCESS_DENIED;
3911 /* check if the group has been successfully created */
3912 if ((grp=getgrgid(gid)) == NULL)
3913 return NT_STATUS_ACCESS_DENIED;
3915 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3917 /* add the group to the mapping table */
3918 sid_copy(&info_sid, get_global_sam_sid());
3919 sid_append_rid(&info_sid, r_u->rid);
3920 sid_to_string(sid_string, &info_sid);
3922 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
3923 return NT_STATUS_ACCESS_DENIED;
3925 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3926 return NT_STATUS_NO_MEMORY;
3928 /* get a (unique) handle. open a policy on it. */
3929 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3930 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3932 return NT_STATUS_OK;
3935 /*********************************************************************
3936 _samr_create_dom_alias
3937 *********************************************************************/
3939 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3946 struct samr_info *info;
3947 PRIVILEGE_SET priv_set;
3951 init_privilege(&priv_set);
3953 /* Find the policy handle. Open a policy on it. */
3954 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
3955 return NT_STATUS_INVALID_HANDLE;
3957 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3961 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3962 return NT_STATUS_ACCESS_DENIED;
3964 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3966 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3968 /* check if group already exists */
3969 if ( (grp=getgrnam(name)) != NULL)
3970 return NT_STATUS_GROUP_EXISTS;
3972 /* we can create the UNIX group */
3973 if (smb_create_group(name, &gid) != 0)
3974 return NT_STATUS_ACCESS_DENIED;
3976 /* check if the group has been successfully created */
3977 if ((grp=getgrgid(gid)) == NULL)
3978 return NT_STATUS_ACCESS_DENIED;
3980 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3982 sid_copy(&info_sid, get_global_sam_sid());
3983 sid_append_rid(&info_sid, r_u->rid);
3984 sid_to_string(sid_string, &info_sid);
3986 /* add the group to the mapping table */
3987 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
3988 return NT_STATUS_ACCESS_DENIED;
3990 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3991 return NT_STATUS_NO_MEMORY;
3993 /* get a (unique) handle. open a policy on it. */
3994 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
3995 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3997 return NT_STATUS_OK;
4000 /*********************************************************************
4001 _samr_query_groupinfo
4003 sends the name/comment pair of a domain group
4004 level 1 send also the number of users of that group
4005 *********************************************************************/
4007 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4013 GROUP_INFO_CTR *ctr;
4016 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4017 return NT_STATUS_INVALID_HANDLE;
4019 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4023 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
4024 return NT_STATUS_INVALID_HANDLE;
4026 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
4028 return NT_STATUS_NO_MEMORY;
4030 switch (q_u->switch_level) {
4032 ctr->switch_value1 = 1;
4033 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
4034 return NT_STATUS_NO_SUCH_GROUP;
4035 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
4039 ctr->switch_value1 = 3;
4040 init_samr_group_info3(&ctr->group.info3);
4043 ctr->switch_value1 = 4;
4044 init_samr_group_info4(&ctr->group.info4, map.comment);
4047 return NT_STATUS_INVALID_INFO_CLASS;
4050 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4052 return NT_STATUS_OK;
4055 /*********************************************************************
4058 update a domain group's comment.
4059 *********************************************************************/
4061 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4065 GROUP_INFO_CTR *ctr;
4068 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4069 return NT_STATUS_INVALID_HANDLE;
4071 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4075 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
4076 return NT_STATUS_NO_SUCH_GROUP;
4080 switch (ctr->switch_value1) {
4082 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4085 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4088 free_privilege(&map.priv_set);
4089 return NT_STATUS_INVALID_INFO_CLASS;
4092 if(!pdb_update_group_mapping_entry(&map)) {
4093 free_privilege(&map.priv_set);
4094 return NT_STATUS_NO_SUCH_GROUP;
4097 free_privilege(&map.priv_set);
4099 return NT_STATUS_OK;
4102 /*********************************************************************
4105 update an alias's comment.
4106 *********************************************************************/
4108 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4112 ALIAS_INFO_CTR *ctr;
4115 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4116 return NT_STATUS_INVALID_HANDLE;
4118 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4122 if (!get_local_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
4123 return NT_STATUS_NO_SUCH_GROUP;
4127 switch (ctr->switch_value1) {
4129 unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
4132 free_privilege(&map.priv_set);
4133 return NT_STATUS_INVALID_INFO_CLASS;
4136 if(!pdb_update_group_mapping_entry(&map)) {
4137 free_privilege(&map.priv_set);
4138 return NT_STATUS_NO_SUCH_GROUP;
4141 free_privilege(&map.priv_set);
4143 return NT_STATUS_OK;
4146 /*********************************************************************
4147 _samr_get_dom_pwinfo
4148 *********************************************************************/
4150 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4152 /* Perform access check. Since this rpc does not require a
4153 policy handle it will not be caught by the access checks on
4154 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4156 if (!pipe_access_check(p)) {
4157 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4158 r_u->status = NT_STATUS_ACCESS_DENIED;
4162 /* Actually, returning zeros here works quite well :-). */
4164 return NT_STATUS_OK;
4167 /*********************************************************************
4169 *********************************************************************/
4171 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4176 struct samr_info *info;
4177 SEC_DESC *psd = NULL;
4184 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4185 return NT_STATUS_INVALID_HANDLE;
4187 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4191 /*check if access can be granted as requested by client. */
4192 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4193 se_map_generic(&des_access,&grp_generic_mapping);
4194 if (!NT_STATUS_IS_OK(status =
4195 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4196 des_access, &acc_granted, "_samr_open_group"))) {
4201 /* this should not be hard-coded like this */
4202 if (!sid_equal(&sid, get_global_sam_sid()))
4203 return NT_STATUS_ACCESS_DENIED;
4205 sid_copy(&info_sid, get_global_sam_sid());
4206 sid_append_rid(&info_sid, q_u->rid_group);
4207 sid_to_string(sid_string, &info_sid);
4209 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4210 return NT_STATUS_NO_MEMORY;
4212 info->acc_granted = acc_granted;
4214 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4216 /* check if that group really exists */
4217 if (!get_domain_group_from_sid(info->sid, &map, MAPPING_WITHOUT_PRIV))
4218 return NT_STATUS_NO_SUCH_GROUP;
4220 /* get a (unique) handle. open a policy on it. */
4221 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4222 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4224 return NT_STATUS_OK;
4227 /*********************************************************************
4229 *********************************************************************/
4231 NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
4233 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
4234 return NT_STATUS_NOT_IMPLEMENTED;
4237 /*******************************************************************
4239 ********************************************************************/
4241 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4243 struct samr_info *info = NULL;
4245 uint32 min_pass_len,pass_hist,flag;
4246 time_t u_expire, u_min_age;
4247 NTTIME nt_expire, nt_min_age;
4249 time_t u_lock_duration, u_reset_time;
4250 NTTIME nt_lock_duration, nt_reset_time;
4256 uint32 num_users=0, num_groups=0, num_aliases=0;
4258 uint32 account_policy_temp;
4260 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4261 return NT_STATUS_NO_MEMORY;
4265 r_u->status = NT_STATUS_OK;
4267 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4269 /* find the policy handle. open a policy on it. */
4270 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4271 return NT_STATUS_INVALID_HANDLE;
4273 switch (q_u->switch_value) {
4275 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4276 min_pass_len = account_policy_temp;
4278 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4279 pass_hist = account_policy_temp;
4281 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4282 flag = account_policy_temp;
4284 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4285 u_expire = account_policy_temp;
4287 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4288 u_min_age = account_policy_temp;
4290 unix_to_nt_time_abs(&nt_expire, u_expire);
4291 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4293 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4294 flag, nt_expire, nt_min_age);
4298 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4300 if (!NT_STATUS_IS_OK(r_u->status)) {
4301 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4304 num_users=info->disp_info.num_user_account;
4307 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4308 if (NT_STATUS_IS_ERR(r_u->status)) {
4309 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4312 num_groups=info->disp_info.num_group_account;
4315 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4316 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
4317 num_users, num_groups, num_aliases);
4320 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4321 u_logout = account_policy_temp;
4323 unix_to_nt_time_abs(&nt_logout, u_logout);
4325 init_unk_info3(&ctr->info.inf3, nt_logout);
4328 init_unk_info5(&ctr->info.inf5, global_myname());
4331 init_unk_info6(&ctr->info.inf6);
4334 init_unk_info7(&ctr->info.inf7);
4337 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4338 u_lock_duration = account_policy_temp;
4340 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4341 u_reset_time = account_policy_temp;
4343 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4344 lockout = account_policy_temp;
4346 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4347 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4349 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4352 return NT_STATUS_INVALID_INFO_CLASS;
4355 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4357 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4362 /*******************************************************************
4364 ********************************************************************/
4366 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4368 time_t u_expire, u_min_age;
4370 time_t u_lock_duration, u_reset_time;
4372 r_u->status = NT_STATUS_OK;
4374 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4376 /* find the policy handle. open a policy on it. */
4377 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4378 return NT_STATUS_INVALID_HANDLE;
4380 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4382 switch (q_u->switch_value) {
4384 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4385 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4387 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4388 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4389 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4390 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4391 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4396 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4397 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4406 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4407 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count);
4409 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4410 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4411 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4414 return NT_STATUS_INVALID_INFO_CLASS;
4417 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4419 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));