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 SAM_ACCOUNT *disp_user_info;
49 uint32 num_group_account;
50 DOMAIN_GRP *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;
154 /*******************************************************************
155 Function to free the per handle data.
156 ********************************************************************/
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 SAM_ACCOUNT *sam = &info->disp_info.disp_user_info[i];
165 /* Not really a free, actually a 'clear' */
169 info->disp_info.user_dbloaded=False;
170 info->disp_info.num_user_account=0;
173 /*******************************************************************
174 Function to free the per handle data.
175 ********************************************************************/
177 static void free_samr_db(struct samr_info *info)
179 /* Groups are talloced */
181 free_samr_users(info);
183 info->disp_info.group_dbloaded=False;
184 info->disp_info.num_group_account=0;
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 SAM_ACCOUNT *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=(SAM_ACCOUNT *)talloc_realloc(mem_ctx, info->disp_info.disp_user_info,
259 (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(SAM_ACCOUNT));
262 return NT_STATUS_NO_MEMORY;
264 info->disp_info.disp_user_info=pwd_array;
267 /* Copy the SAM_ACCOUNT into the array */
268 info->disp_info.disp_user_info[info->disp_info.num_user_account]=*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 DOMAIN_GRP *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)) {
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=(DOMAIN_GRP *)talloc(mem_ctx, info->disp_info.num_group_account*sizeof(DOMAIN_GRP));
317 if (group_entries!=0 && grp_array==NULL) {
318 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
320 return NT_STATUS_NO_MEMORY;
323 info->disp_info.disp_group_info=grp_array;
325 for (i=0; i<group_entries; i++) {
326 fstrcpy(grp_array[i].name, map[i].nt_name);
327 fstrcpy(grp_array[i].comment, map[i].comment);
328 sid_split_rid(&map[i].sid, &grp_array[i].rid);
329 grp_array[i].attr=SID_NAME_DOM_GRP;
334 /* the snapshoot is in memory, we're ready to enumerate fast */
336 info->disp_info.group_dbloaded=True;
338 DEBUG(10,("load_group_domain_entries: done\n"));
344 /*******************************************************************
346 ********************************************************************/
348 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
350 r_u->status = NT_STATUS_OK;
352 /* close the policy handle */
353 if (!close_policy_hnd(p, &q_u->pol))
354 return NT_STATUS_OBJECT_NAME_INVALID;
356 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
361 /*******************************************************************
362 samr_reply_open_domain
363 ********************************************************************/
365 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
367 struct samr_info *info;
368 SEC_DESC *psd = NULL;
370 uint32 des_access = q_u->flags;
374 r_u->status = NT_STATUS_OK;
376 /* find the connection policy handle. */
377 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
378 return NT_STATUS_INVALID_HANDLE;
380 if (!NT_STATUS_IS_OK(status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN,"_samr_open_domain"))) {
384 /*check if access can be granted as requested by client. */
385 samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
386 se_map_generic(&des_access,&dom_generic_mapping);
388 if (!NT_STATUS_IS_OK(status =
389 access_check_samr_object(psd, p->pipe_user.nt_user_token,
390 des_access, &acc_granted, "_samr_open_domain"))) {
394 /* associate the domain SID with the (unique) handle. */
395 if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
396 return NT_STATUS_NO_MEMORY;
397 info->acc_granted = acc_granted;
399 /* get a (unique) handle. open a policy on it. */
400 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
401 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
403 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
408 /*******************************************************************
409 _samr_get_usrdom_pwinfo
410 ********************************************************************/
412 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
414 struct samr_info *info = NULL;
416 r_u->status = NT_STATUS_OK;
418 /* find the policy handle. open a policy on it. */
419 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
420 return NT_STATUS_INVALID_HANDLE;
422 if (!sid_check_is_in_our_domain(&info->sid))
423 return NT_STATUS_OBJECT_TYPE_MISMATCH;
425 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
427 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
430 * NT sometimes return NT_STATUS_ACCESS_DENIED
431 * I don't know yet why.
437 /*******************************************************************
439 ********************************************************************/
441 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
443 extern DOM_SID global_sid_World;
452 sid_copy(&adm_sid, &global_sid_Builtin);
453 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
455 sid_copy(&act_sid, &global_sid_Builtin);
456 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
458 /*basic access for every one*/
459 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
460 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
462 /*full access for builtin aliases Administrators and Account Operators*/
463 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS);
464 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
465 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
467 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
468 return NT_STATUS_NO_MEMORY;
470 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
471 return NT_STATUS_NO_MEMORY;
476 /*******************************************************************
478 ********************************************************************/
480 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
482 extern DOM_SID global_sid_World;
491 sid_copy(&adm_sid, &global_sid_Builtin);
492 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
494 sid_copy(&act_sid, &global_sid_Builtin);
495 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
497 /*basic access for every one*/
498 init_sec_access(&mask, GENERIC_RIGHTS_USER_EXECUTE | GENERIC_RIGHTS_USER_READ);
499 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
501 /*full access for builtin aliases Administrators and Account Operators*/
502 init_sec_access(&mask, GENERIC_RIGHTS_USER_ALL_ACCESS);
503 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
504 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
506 /*extended access for the user*/
507 init_sec_access(&mask,READ_CONTROL_ACCESS | SA_RIGHT_USER_CHANGE_PASSWORD | SA_RIGHT_USER_SET_LOC_COM);
508 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
510 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
511 return NT_STATUS_NO_MEMORY;
513 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
514 return NT_STATUS_NO_MEMORY;
519 /*******************************************************************
521 ********************************************************************/
523 static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
525 extern DOM_SID global_sid_World;
534 sid_copy(&adm_sid, &global_sid_Builtin);
535 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
537 sid_copy(&act_sid, &global_sid_Builtin);
538 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
540 /*basic access for every one*/
541 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
542 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
544 /*full access for builtin aliases Administrators and Account Operators*/
545 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_ALL_ACCESS);
546 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
547 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
549 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
550 return NT_STATUS_NO_MEMORY;
552 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
553 return NT_STATUS_NO_MEMORY;
558 /*******************************************************************
560 ********************************************************************/
562 static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
564 extern DOM_SID global_sid_World;
573 sid_copy(&adm_sid, &global_sid_Builtin);
574 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
576 sid_copy(&act_sid, &global_sid_Builtin);
577 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
579 /*basic access for every one*/
580 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
581 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
583 /*full access for builtin aliases Administrators and Account Operators*/
584 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_ALL_ACCESS);
585 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
586 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
588 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
589 return NT_STATUS_NO_MEMORY;
591 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
592 return NT_STATUS_NO_MEMORY;
597 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
599 struct samr_info *info = NULL;
601 /* find the policy handle. open a policy on it. */
602 if (!find_policy_by_hnd(p, pol, (void **)&info))
609 *acc_granted = info->acc_granted;
613 /*******************************************************************
615 ********************************************************************/
617 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
619 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
620 return NT_STATUS_NOT_IMPLEMENTED;
624 /*******************************************************************
626 ********************************************************************/
628 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
632 SEC_DESC * psd = NULL;
636 r_u->status = NT_STATUS_OK;
639 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
640 return NT_STATUS_INVALID_HANDLE;
644 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
646 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
648 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
649 if (pol_sid.sid_rev_num == 0)
651 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
652 r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
654 else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */
657 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
658 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
660 else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */
662 /* TODO: Builtin probably needs a different SD with restricted write access*/
663 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
664 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
666 else if (sid_check_is_in_our_domain(&pol_sid) ||
667 sid_check_is_in_builtin(&pol_sid))
669 /* TODO: different SDs have to be generated for aliases groups and users.
670 Currently all three get a default user SD */
671 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
672 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
674 else return NT_STATUS_OBJECT_TYPE_MISMATCH;
676 if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
677 return NT_STATUS_NO_MEMORY;
679 if (NT_STATUS_IS_OK(r_u->status))
685 /*******************************************************************
686 makes a SAM_ENTRY / UNISTR2* structure from a user list.
687 ********************************************************************/
689 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
690 uint32 num_entries, uint32 start_idx, SAM_ACCOUNT *disp_user_info,
696 SAM_ACCOUNT *pwd = NULL;
697 UNISTR2 uni_temp_name;
698 const char *temp_name;
699 const DOM_SID *user_sid;
701 fstring user_sid_string;
702 fstring domain_sid_string;
707 if (num_entries == 0)
710 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_entries);
712 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_entries);
714 if (sam == NULL || uni_name == NULL) {
715 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
716 return NT_STATUS_NO_MEMORY;
719 for (i = 0; i < num_entries; i++) {
720 pwd = &disp_user_info[i+start_idx];
721 temp_name = pdb_get_username(pwd);
722 init_unistr2(&uni_temp_name, temp_name, strlen(temp_name)+1);
723 user_sid = pdb_get_user_sid(pwd);
725 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
726 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
727 "the domain sid %s. Failing operation.\n",
729 sid_to_string(user_sid_string, user_sid),
730 sid_to_string(domain_sid_string, domain_sid)));
731 return NT_STATUS_UNSUCCESSFUL;
734 init_sam_entry(&sam[i], uni_temp_name.uni_str_len, user_rid);
735 copy_unistr2(&uni_name[i], &uni_temp_name);
739 *uni_name_pp = uni_name;
743 /*******************************************************************
744 samr_reply_enum_dom_users
745 ********************************************************************/
747 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
748 SAMR_R_ENUM_DOM_USERS *r_u)
750 struct samr_info *info = NULL;
751 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
753 uint32 enum_context=q_u->start_idx;
754 uint32 max_size=q_u->max_size;
756 enum remote_arch_types ra_type = get_remote_arch();
757 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
758 uint32 max_entries = max_sam_entries;
761 r_u->status = NT_STATUS_OK;
763 /* find the policy handle. open a policy on it. */
764 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
765 return NT_STATUS_INVALID_HANDLE;
767 domain_sid = info->sid;
769 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
770 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
771 "_samr_enum_dom_users"))) {
775 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
778 r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
781 if (!NT_STATUS_IS_OK(r_u->status))
784 num_account = info->disp_info.num_user_account;
786 if (enum_context > num_account) {
787 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
791 /* verify we won't overflow */
792 if (max_entries > num_account-enum_context) {
793 max_entries = num_account-enum_context;
794 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
797 /* calculate the size and limit on the number of entries we will return */
798 temp_size=max_entries*struct_size;
800 if (temp_size>max_size) {
801 max_entries=MIN((max_size/struct_size),max_entries);;
802 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
806 * Note from JRA. total_entries is not being used here. Currently if there is a
807 * large user base then it looks like NT will enumerate until get_sampwd_entries
808 * returns False due to num_entries being zero. This will cause an access denied
809 * return. I don't think this is right and needs further investigation. Note that
810 * this is also the same in the TNG code (I don't think that has been tested with
811 * a very large user list as MAX_SAM_ENTRIES is set to 600).
813 * I also think that one of the 'num_entries' return parameters is probably
814 * the "max entries" parameter - but in the TNG code they're all currently set to the same
815 * value (again I think this is wrong).
818 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
819 max_entries, enum_context,
820 info->disp_info.disp_user_info,
823 if (!NT_STATUS_IS_OK(r_u->status))
826 if (enum_context+max_entries < num_account)
827 r_u->status = STATUS_MORE_ENTRIES;
829 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
831 init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
833 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
838 /*******************************************************************
839 makes a SAM_ENTRY / UNISTR2* structure from a group list.
840 ********************************************************************/
842 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
843 uint32 num_sam_entries, DOMAIN_GRP *grp)
852 if (num_sam_entries == 0)
855 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
857 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
859 if (sam == NULL || uni_name == NULL) {
860 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
864 for (i = 0; i < num_sam_entries; i++) {
866 * JRA. I think this should include the null. TNG does not.
868 int len = strlen(grp[i].name)+1;
870 init_sam_entry(&sam[i], len, grp[i].rid);
871 init_unistr2(&uni_name[i], grp[i].name, len);
875 *uni_name_pp = uni_name;
878 /*******************************************************************
879 Get the group entries - similar to get_sampwd_entries().
880 ********************************************************************/
882 static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
883 uint32 *p_num_entries, uint32 max_entries)
886 uint32 num_entries = 0;
889 GROUP_MAP *map = NULL;
891 sid_to_string(sid_str, sid);
892 DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str));
896 /* well-known aliases */
897 if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
899 pdb_enum_group_mapping(SID_NAME_WKN_GRP, &map, (int *)&num_entries, ENUM_ONLY_MAPPED);
901 if (num_entries != 0) {
902 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
904 return NT_STATUS_NO_MEMORY;
906 for(i=0; i<num_entries && i<max_entries; i++) {
907 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
908 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
914 } else if (sid_equal(sid, get_global_sam_sid()) && !lp_hide_local_users()) {
915 struct sys_grent *glist;
916 struct sys_grent *grp;
918 gid_t winbind_gid_low, winbind_gid_high;
919 BOOL winbind_groups_exist = lp_idmap_gid(&winbind_gid_low, &winbind_gid_high);
922 /* we return the UNIX groups here. This seems to be the right */
923 /* thing to do, since NT member servers return their local */
924 /* groups in the same situation. */
926 /* use getgrent_list() to retrieve the list of groups to avoid
927 * problems with getgrent possible infinite loop by internal
928 * libc grent structures overwrites by called functions */
929 grp = glist = getgrent_list();
931 return NT_STATUS_NO_MEMORY;
933 for (; (num_entries < max_entries) && (grp != NULL); grp = grp->next) {
936 if(!pdb_getgrgid(&smap, grp->gr_gid))
939 if (smap.sid_name_use!=SID_NAME_ALIAS) {
943 sid_split_rid(&smap.sid, &trid);
945 if (!sid_equal(sid, &smap.sid))
948 /* Don't return winbind groups as they are not local! */
949 if (winbind_groups_exist && (grp->gr_gid >= winbind_gid_low)&&(grp->gr_gid <= winbind_gid_high)) {
950 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
954 /* Don't return user private groups... */
956 if ((pw = Get_Pwnam(smap.nt_name)) != 0) {
957 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
961 for( i = 0; i < num_entries; i++)
962 if ( (*d_grp)[i].rid == trid )
965 if ( i < num_entries ) {
966 continue; /* rid was there, dup! */
969 /* JRA - added this for large group db enumeration... */
972 /* skip the requested number of entries.
973 not very efficient, but hey...
979 *d_grp=talloc_realloc(ctx,*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
982 return NT_STATUS_NO_MEMORY;
985 fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
986 (*d_grp)[num_entries].rid = trid;
988 DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries, trid));
994 *p_num_entries = num_entries;
996 DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries));
998 if (num_entries >= max_entries)
999 return STATUS_MORE_ENTRIES;
1000 return NT_STATUS_OK;
1003 /*******************************************************************
1004 Get the group entries - similar to get_sampwd_entries().
1005 ********************************************************************/
1007 static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
1008 uint32 *p_num_entries, uint32 max_entries)
1010 GROUP_MAP *map=NULL;
1012 uint32 group_entries = 0;
1013 uint32 num_entries = 0;
1017 pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
1019 num_entries=group_entries-start_idx;
1021 /* limit the number of entries */
1022 if (num_entries>max_entries) {
1023 DEBUG(5,("Limiting to %d entries\n", max_entries));
1024 num_entries=max_entries;
1027 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
1028 if (num_entries!=0 && *d_grp==NULL){
1030 return NT_STATUS_NO_MEMORY;
1033 for (i=0; i<num_entries; i++) {
1034 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
1035 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
1036 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
1037 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
1042 *p_num_entries = num_entries;
1044 return NT_STATUS_OK;
1047 /*******************************************************************
1048 samr_reply_enum_dom_groups
1049 ********************************************************************/
1051 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
1053 DOMAIN_GRP *grp=NULL;
1058 r_u->status = NT_STATUS_OK;
1060 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1061 return NT_STATUS_INVALID_HANDLE;
1063 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
1067 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1069 /* the domain group array is being allocated in the function below */
1070 if (!NT_STATUS_IS_OK(r_u->status = get_group_domain_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES))) {
1074 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1076 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
1078 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1084 /*******************************************************************
1085 samr_reply_enum_dom_aliases
1086 ********************************************************************/
1088 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1090 DOMAIN_GRP *grp=NULL;
1091 uint32 num_entries = 0;
1097 r_u->status = NT_STATUS_OK;
1099 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1100 return NT_STATUS_INVALID_HANDLE;
1102 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1106 sid_to_string(sid_str, &sid);
1107 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1109 status = get_group_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1110 &num_entries, MAX_SAM_ENTRIES);
1111 if (NT_STATUS_IS_ERR(status)) return status;
1113 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1117 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1119 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1124 /*******************************************************************
1125 samr_reply_query_dispinfo
1126 ********************************************************************/
1128 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1129 SAMR_R_QUERY_DISPINFO *r_u)
1131 struct samr_info *info = NULL;
1132 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1134 uint32 max_entries=q_u->max_entries;
1135 uint32 enum_context=q_u->start_idx;
1136 uint32 max_size=q_u->max_size;
1138 SAM_DISPINFO_CTR *ctr;
1139 uint32 temp_size=0, total_data_size=0;
1141 uint32 num_account = 0;
1142 enum remote_arch_types ra_type = get_remote_arch();
1143 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1146 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1147 r_u->status = NT_STATUS_OK;
1149 /* find the policy handle. open a policy on it. */
1150 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1151 return NT_STATUS_INVALID_HANDLE;
1153 domain_sid = info->sid;
1156 * calculate how many entries we will return.
1158 * - the number of entries the client asked
1159 * - our limit on that
1160 * - the starting point (enumeration context)
1161 * - the buffer size the client will accept
1165 * We are a lot more like W2K. Instead of reading the SAM
1166 * each time to find the records we need to send back,
1167 * we read it once and link that copy to the sam handle.
1168 * For large user list (over the MAX_SAM_ENTRIES)
1169 * it's a definitive win.
1170 * second point to notice: between enumerations
1171 * our sam is now the same as it's a snapshoot.
1172 * third point: got rid of the static SAM_USER_21 struct
1173 * no more intermediate.
1174 * con: it uses much more memory, as a full copy is stored
1177 * If you want to change it, think twice and think
1178 * of the second point , that's really important.
1183 /* Get what we need from the password database */
1184 switch (q_u->switch_level) {
1186 /* When playing with usrmgr, this is necessary
1187 if you want immediate refresh after editing
1188 a user. I would like to do this after the
1189 setuserinfo2, but we do not have access to
1190 the domain handle in that call, only to the
1191 user handle. Where else does this hurt?
1195 /* We cannot do this here - it kills performace. JRA. */
1196 free_samr_users(info);
1201 /* Level 2 is for all machines, otherwise only 'normal' users */
1202 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1204 if (!NT_STATUS_IS_OK(r_u->status)) {
1205 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1208 num_account = info->disp_info.num_user_account;
1212 r_u->status = load_group_domain_entries(info, &info->sid);
1213 if (!NT_STATUS_IS_OK(r_u->status))
1215 num_account = info->disp_info.num_group_account;
1218 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1219 return NT_STATUS_INVALID_INFO_CLASS;
1222 /* first limit the number of entries we will return */
1223 if(max_entries > max_sam_entries) {
1224 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1225 max_entries = max_sam_entries;
1228 if (enum_context > num_account) {
1229 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1230 return NT_STATUS_NO_MORE_ENTRIES;
1233 /* verify we won't overflow */
1234 if (max_entries > num_account-enum_context) {
1235 max_entries = num_account-enum_context;
1236 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1239 /* calculate the size and limit on the number of entries we will return */
1240 temp_size=max_entries*struct_size;
1242 if (temp_size>max_size) {
1243 max_entries=MIN((max_size/struct_size),max_entries);;
1244 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1247 if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1248 return NT_STATUS_NO_MEMORY;
1252 /* Now create reply structure */
1253 switch (q_u->switch_level) {
1256 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
1257 return NT_STATUS_NO_MEMORY;
1259 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1260 info->disp_info.disp_user_info, &domain_sid);
1261 if (!NT_STATUS_IS_OK(disp_ret))
1266 if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1267 return NT_STATUS_NO_MEMORY;
1269 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1270 info->disp_info.disp_user_info, &domain_sid);
1271 if (!NT_STATUS_IS_OK(disp_ret))
1276 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1277 return NT_STATUS_NO_MEMORY;
1279 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1280 if (!NT_STATUS_IS_OK(disp_ret))
1285 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1286 return NT_STATUS_NO_MEMORY;
1288 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1289 if (!NT_STATUS_IS_OK(disp_ret))
1294 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1295 return NT_STATUS_NO_MEMORY;
1297 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1298 if (!NT_STATUS_IS_OK(disp_ret))
1303 ctr->sam.info = NULL;
1304 return NT_STATUS_INVALID_INFO_CLASS;
1307 /* calculate the total size */
1308 total_data_size=num_account*struct_size;
1310 if (enum_context+max_entries < num_account)
1311 r_u->status = STATUS_MORE_ENTRIES;
1313 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1315 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1321 /*******************************************************************
1322 samr_reply_query_aliasinfo
1323 ********************************************************************/
1325 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1331 r_u->status = NT_STATUS_OK;
1333 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1335 /* find the policy handle. open a policy on it. */
1336 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1337 return NT_STATUS_INVALID_HANDLE;
1338 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1342 if (!sid_check_is_in_our_domain(&sid) &&
1343 !sid_check_is_in_builtin(&sid))
1344 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1346 if (!pdb_getgrsid(&map, sid))
1347 return NT_STATUS_NO_SUCH_ALIAS;
1349 switch (q_u->switch_level) {
1352 r_u->ctr.switch_value1 = 1;
1353 init_samr_alias_info1(&r_u->ctr.alias.info1, map.nt_name, 1, map.comment);
1357 r_u->ctr.switch_value1 = 3;
1358 init_samr_alias_info3(&r_u->ctr.alias.info3, map.comment);
1361 return NT_STATUS_INVALID_INFO_CLASS;
1364 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1370 /*******************************************************************
1371 samr_reply_lookup_ids
1372 ********************************************************************/
1374 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1376 uint32 rid[MAX_SAM_ENTRIES];
1377 int num_rids = q_u->num_sids1;
1379 r_u->status = NT_STATUS_OK;
1381 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1383 if (num_rids > MAX_SAM_ENTRIES) {
1384 num_rids = MAX_SAM_ENTRIES;
1385 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1390 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1392 for (i = 0; i < num_rids && status == 0; i++)
1394 struct sam_passwd *sam_pass;
1398 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1399 q_u->uni_user_name[i].uni_str_len));
1401 /* find the user account */
1403 sam_pass = get_smb21pwd_entry(user_name, 0);
1406 if (sam_pass == NULL)
1408 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1413 rid[i] = sam_pass->user_rid;
1419 rid[0] = BUILTIN_ALIAS_RID_USERS;
1421 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1423 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1429 /*******************************************************************
1431 ********************************************************************/
1433 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1435 uint32 rid[MAX_SAM_ENTRIES];
1437 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1438 enum SID_NAME_USE local_type;
1440 int num_rids = q_u->num_names2;
1445 r_u->status = NT_STATUS_OK;
1447 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1452 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1453 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1457 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 */
1461 if (num_rids > MAX_SAM_ENTRIES) {
1462 num_rids = MAX_SAM_ENTRIES;
1463 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1466 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1468 become_root(); /* local_lookup_name can require root privs */
1470 for (i = 0; i < num_rids; i++) {
1475 r_u->status = NT_STATUS_NONE_MAPPED;
1477 rid [i] = 0xffffffff;
1478 type[i] = SID_NAME_UNKNOWN;
1480 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1483 * we are only looking for a name
1484 * the SID we get back can be outside
1485 * the scope of the pol_sid
1487 * in clear: it prevents to reply to domain\group: yes
1488 * when only builtin\group exists.
1490 * a cleaner code is to add the sid of the domain we're looking in
1491 * to the local_lookup_name function.
1494 if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
1495 sid_split_rid(&sid, &local_rid);
1497 if (sid_equal(&sid, &pol_sid)) {
1500 r_u->status = NT_STATUS_OK;
1507 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1509 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1514 /*******************************************************************
1515 _samr_chgpasswd_user
1516 ********************************************************************/
1518 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1523 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1525 r_u->status = NT_STATUS_OK;
1527 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1528 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1530 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1533 * Pass the user through the NT -> unix user mapping
1537 (void)map_username(user_name);
1540 * UNIX username case mangling not required, pass_oem_change
1541 * is case insensitive.
1544 r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1545 q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1547 init_samr_r_chgpasswd_user(r_u, r_u->status);
1549 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1554 /*******************************************************************
1555 makes a SAMR_R_LOOKUP_RIDS structure.
1556 ********************************************************************/
1558 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1559 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1562 UNIHDR *hdr_name=NULL;
1563 UNISTR2 *uni_name=NULL;
1565 *pp_uni_name = NULL;
1566 *pp_hdr_name = NULL;
1568 if (num_names != 0) {
1569 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1570 if (hdr_name == NULL)
1573 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1574 if (uni_name == NULL)
1578 for (i = 0; i < num_names; i++) {
1579 int len = names[i] != NULL ? strlen(names[i]) : 0;
1580 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1581 init_uni_hdr(&hdr_name[i], len);
1582 init_unistr2(&uni_name[i], names[i], len);
1585 *pp_uni_name = uni_name;
1586 *pp_hdr_name = hdr_name;
1591 /*******************************************************************
1593 ********************************************************************/
1595 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1597 fstring group_names[MAX_SAM_ENTRIES];
1598 uint32 *group_attrs = NULL;
1599 UNIHDR *hdr_name = NULL;
1600 UNISTR2 *uni_name = NULL;
1602 int num_rids = q_u->num_rids1;
1606 r_u->status = NT_STATUS_OK;
1608 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1610 /* find the policy handle. open a policy on it. */
1611 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1612 return NT_STATUS_INVALID_HANDLE;
1614 if (num_rids > MAX_SAM_ENTRIES) {
1615 num_rids = MAX_SAM_ENTRIES;
1616 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1620 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1621 return NT_STATUS_NO_MEMORY;
1624 r_u->status = NT_STATUS_NONE_MAPPED;
1626 become_root(); /* lookup_sid can require root privs */
1628 for (i = 0; i < num_rids; i++) {
1632 enum SID_NAME_USE type;
1634 group_attrs[i] = SID_NAME_UNKNOWN;
1635 *group_names[i] = '\0';
1637 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1638 sid_copy(&sid, &pol_sid);
1639 sid_append_rid(&sid, q_u->rid[i]);
1641 if (lookup_sid(&sid, domname, tmpname, &type)) {
1642 r_u->status = NT_STATUS_OK;
1643 group_attrs[i] = (uint32)type;
1644 fstrcpy(group_names[i],tmpname);
1645 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1652 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1653 return NT_STATUS_NO_MEMORY;
1655 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1657 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1662 /*******************************************************************
1663 _api_samr_open_user. Safe - gives out no passwd info.
1664 ********************************************************************/
1666 NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1668 SAM_ACCOUNT *sampass=NULL;
1670 POLICY_HND domain_pol = q_u->domain_pol;
1671 POLICY_HND *user_pol = &r_u->user_pol;
1672 struct samr_info *info = NULL;
1673 SEC_DESC *psd = NULL;
1675 uint32 des_access = q_u->access_mask;
1680 r_u->status = NT_STATUS_OK;
1682 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1683 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1684 return NT_STATUS_INVALID_HANDLE;
1686 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1690 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1691 if (!NT_STATUS_IS_OK(nt_status)) {
1695 /* append the user's RID to it */
1696 if (!sid_append_rid(&sid, q_u->user_rid))
1697 return NT_STATUS_NO_SUCH_USER;
1699 /* check if access can be granted as requested by client. */
1700 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1701 se_map_generic(&des_access, &usr_generic_mapping);
1702 if (!NT_STATUS_IS_OK(nt_status =
1703 access_check_samr_object(psd, p->pipe_user.nt_user_token,
1704 des_access, &acc_granted, "_samr_open_user"))) {
1709 ret=pdb_getsampwsid(sampass, &sid);
1712 /* check that the SID exists in our domain. */
1714 return NT_STATUS_NO_SUCH_USER;
1717 pdb_free_sam(&sampass);
1719 /* associate the user's SID and access bits with the new handle. */
1720 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1721 return NT_STATUS_NO_MEMORY;
1722 info->acc_granted = acc_granted;
1724 /* get a (unique) handle. open a policy on it. */
1725 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1726 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1731 /*************************************************************************
1732 get_user_info_10. Safe. Only gives out acb bits.
1733 *************************************************************************/
1735 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1737 SAM_ACCOUNT *smbpass=NULL;
1741 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1743 if (!NT_STATUS_IS_OK(nt_status)) {
1748 ret = pdb_getsampwsid(smbpass, user_sid);
1752 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1753 return NT_STATUS_NO_SUCH_USER;
1756 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1759 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1761 pdb_free_sam(&smbpass);
1763 return NT_STATUS_OK;
1766 /*************************************************************************
1767 get_user_info_12. OK - this is the killer as it gives out password info.
1768 Ensure that this is only allowed on an encrypted connection with a root
1770 *************************************************************************/
1772 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1774 SAM_ACCOUNT *smbpass=NULL;
1778 if (!p->ntlmssp_auth_validated)
1779 return NT_STATUS_ACCESS_DENIED;
1781 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1782 return NT_STATUS_ACCESS_DENIED;
1785 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1788 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1790 if (!NT_STATUS_IS_OK(nt_status)) {
1794 ret = pdb_getsampwsid(smbpass, user_sid);
1797 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1798 pdb_free_sam(&smbpass);
1799 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1802 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1804 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1805 pdb_free_sam(&smbpass);
1806 return NT_STATUS_ACCOUNT_DISABLED;
1810 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1812 pdb_free_sam(&smbpass);
1814 return NT_STATUS_OK;
1817 /*************************************************************************
1819 *************************************************************************/
1821 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1823 SAM_ACCOUNT *sampass=NULL;
1826 pdb_init_sam_talloc(mem_ctx, &sampass);
1829 ret = pdb_getsampwsid(sampass, user_sid);
1833 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1834 return NT_STATUS_NO_SUCH_USER;
1837 samr_clear_sam_passwd(sampass);
1839 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1842 init_sam_user_info20A(id20, sampass);
1844 pdb_free_sam(&sampass);
1846 return NT_STATUS_OK;
1849 /*************************************************************************
1851 *************************************************************************/
1853 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1854 DOM_SID *user_sid, DOM_SID *domain_sid)
1856 SAM_ACCOUNT *sampass=NULL;
1860 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1861 if (!NT_STATUS_IS_OK(nt_status)) {
1866 ret = pdb_getsampwsid(sampass, user_sid);
1870 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1871 return NT_STATUS_NO_SUCH_USER;
1874 samr_clear_sam_passwd(sampass);
1876 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1879 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1881 pdb_free_sam(&sampass);
1883 return NT_STATUS_OK;
1886 /*******************************************************************
1887 _samr_query_userinfo
1888 ********************************************************************/
1890 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1892 SAM_USERINFO_CTR *ctr;
1893 struct samr_info *info = NULL;
1897 r_u->status=NT_STATUS_OK;
1899 /* search for the handle */
1900 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1901 return NT_STATUS_INVALID_HANDLE;
1903 domain_sid = info->sid;
1905 sid_split_rid(&domain_sid, &rid);
1907 if (!sid_check_is_in_our_domain(&info->sid))
1908 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1910 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1912 ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1914 return NT_STATUS_NO_MEMORY;
1918 /* ok! user info levels (lots: see MSDEV help), off we go... */
1919 ctr->switch_value = q_u->switch_value;
1921 switch (q_u->switch_value) {
1923 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1924 if (ctr->info.id10 == NULL)
1925 return NT_STATUS_NO_MEMORY;
1927 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1932 /* whoops - got this wrong. i think. or don't understand what's happening. */
1936 info = (void *)&id11;
1938 expire.low = 0xffffffff;
1939 expire.high = 0x7fffffff;
1941 ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1946 ZERO_STRUCTP(ctr->info.id11);
1947 init_sam_user_info11(ctr->info.id11, &expire,
1948 "BROOKFIELDS$", /* name */
1949 0x03ef, /* user rid */
1950 0x201, /* group rid */
1951 0x0080); /* acb info */
1958 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1959 if (ctr->info.id12 == NULL)
1960 return NT_STATUS_NO_MEMORY;
1962 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1967 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1968 if (ctr->info.id20 == NULL)
1969 return NT_STATUS_NO_MEMORY;
1970 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1975 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1976 if (ctr->info.id21 == NULL)
1977 return NT_STATUS_NO_MEMORY;
1978 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1979 &info->sid, &domain_sid)))
1984 return NT_STATUS_INVALID_INFO_CLASS;
1987 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1989 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1994 /*******************************************************************
1995 samr_reply_query_usergroups
1996 ********************************************************************/
1998 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
2000 SAM_ACCOUNT *sam_pass=NULL;
2002 DOM_GID *gids = NULL;
2008 * from the SID in the request:
2009 * we should send back the list of DOMAIN GROUPS
2010 * the user is a member of
2012 * and only the DOMAIN GROUPS
2013 * no ALIASES !!! neither aliases of the domain
2014 * nor aliases of the builtin SID
2019 r_u->status = NT_STATUS_OK;
2021 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2023 /* find the policy handle. open a policy on it. */
2024 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
2025 return NT_STATUS_INVALID_HANDLE;
2027 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
2031 if (!sid_check_is_in_our_domain(&sid))
2032 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2034 pdb_init_sam(&sam_pass);
2037 ret = pdb_getsampwsid(sam_pass, &sid);
2041 pdb_free_sam(&sam_pass);
2042 return NT_STATUS_NO_SUCH_USER;
2045 if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
2046 pdb_free_sam(&sam_pass);
2047 return NT_STATUS_NO_SUCH_GROUP;
2050 /* construct the response. lkclXXXX: gids are not copied! */
2051 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
2053 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2055 pdb_free_sam(&sam_pass);
2060 /*******************************************************************
2061 _samr_query_dom_info
2062 ********************************************************************/
2064 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2066 struct samr_info *info = NULL;
2068 uint32 min_pass_len,pass_hist,flag;
2069 time_t u_expire, u_min_age;
2070 NTTIME nt_expire, nt_min_age;
2072 time_t u_lock_duration, u_reset_time;
2073 NTTIME nt_lock_duration, nt_reset_time;
2079 uint32 account_policy_temp;
2081 uint32 num_users=0, num_groups=0, num_aliases=0;
2083 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
2084 return NT_STATUS_NO_MEMORY;
2088 r_u->status = NT_STATUS_OK;
2090 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2092 /* find the policy handle. open a policy on it. */
2093 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2094 return NT_STATUS_INVALID_HANDLE;
2096 switch (q_u->switch_value) {
2099 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2100 min_pass_len = account_policy_temp;
2102 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2103 pass_hist = account_policy_temp;
2105 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2106 flag = account_policy_temp;
2108 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2109 u_expire = account_policy_temp;
2111 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2112 u_min_age = account_policy_temp;
2114 unix_to_nt_time_abs(&nt_expire, u_expire);
2115 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2117 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2118 flag, nt_expire, nt_min_age);
2122 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2124 if (!NT_STATUS_IS_OK(r_u->status)) {
2125 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2128 num_users=info->disp_info.num_user_account;
2131 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2132 if (!NT_STATUS_IS_OK(r_u->status)) {
2133 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2136 num_groups=info->disp_info.num_group_account;
2139 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2140 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
2141 num_users, num_groups, num_aliases);
2144 account_policy_get(AP_TIME_TO_LOGOUT, (int *)&u_logout);
2145 unix_to_nt_time_abs(&nt_logout, u_logout);
2147 init_unk_info3(&ctr->info.inf3, nt_logout);
2150 init_unk_info5(&ctr->info.inf5, global_myname());
2153 init_unk_info6(&ctr->info.inf6);
2156 init_unk_info7(&ctr->info.inf7);
2159 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2160 u_lock_duration = account_policy_temp;
2162 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2163 u_reset_time = account_policy_temp;
2165 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2166 lockout = account_policy_temp;
2168 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2169 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2171 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2174 return NT_STATUS_INVALID_INFO_CLASS;
2177 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2179 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2184 /*******************************************************************
2185 _api_samr_create_user
2186 Create an account, can be either a normal user or a machine.
2187 This funcion will need to be updated for bdc/domain trusts.
2188 ********************************************************************/
2190 NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2192 SAM_ACCOUNT *sam_pass=NULL;
2196 POLICY_HND dom_pol = q_u->domain_pol;
2197 UNISTR2 user_account = q_u->uni_name;
2198 uint16 acb_info = q_u->acb_info;
2199 POLICY_HND *user_pol = &r_u->user_pol;
2200 struct samr_info *info = NULL;
2207 /* check this, when giving away 'add computer to domain' privs */
2208 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2210 /* Get the domain SID stored in the domain policy */
2211 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2212 return NT_STATUS_INVALID_HANDLE;
2214 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2218 /* find the account: tell the caller if it exists.
2219 lkclXXXX i have *no* idea if this is a problem or not
2220 or even if you are supposed to construct a different
2221 reply if the account already exists...
2224 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2225 strlower_m(account);
2227 pdb_init_sam(&sam_pass);
2230 ret = pdb_getsampwnam(sam_pass, account);
2233 /* this account exists: say so */
2234 pdb_free_sam(&sam_pass);
2235 return NT_STATUS_USER_EXISTS;
2238 pdb_free_sam(&sam_pass);
2241 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2242 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2243 * that only people with write access to the smbpasswd file will be able
2244 * to create a user. JRA.
2248 * add the user in the /etc/passwd file or the unix authority system.
2249 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2250 * a) local_password_change() checks for us if the /etc/passwd account really exists
2251 * b) smb_create_user() would return an error if the account already exists
2252 * and as it could return an error also if it can't create the account, it would be tricky.
2254 * So we go the easy way, only check after if the account exists.
2255 * JFM (2/3/2001), to clear any possible bad understanding (-:
2257 * We now have seperate script paramaters for adding users/machines so we
2258 * now have some sainity-checking to match.
2261 DEBUG(10,("checking account %s at pos %d for $ termination\n",account, strlen(account)-1));
2263 if ((acb_info & ACB_WSTRUST) && (account[strlen(account)-1] == '$')) {
2264 pstrcpy(add_script, lp_addmachine_script());
2265 } else if ((!(acb_info & ACB_WSTRUST)) && (account[strlen(account)-1] != '$')) {
2266 pstrcpy(add_script, lp_adduser_script());
2268 DEBUG(0, ("_api_samr_create_user: mismatch between trust flags and $ termination\n"));
2269 pdb_free_sam(&sam_pass);
2270 return NT_STATUS_UNSUCCESSFUL;
2274 /* the passdb lookup has failed; check to see if we need to run the
2275 add user/machine script */
2277 pw = Get_Pwnam(account);
2281 * we can't check both the ending $ and the acb_info.
2283 * UserManager creates trust accounts (ending in $,
2284 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2287 if (account[strlen(account)-1] == '$')
2288 pstrcpy(add_script, lp_addmachine_script());
2290 pstrcpy(add_script, lp_adduser_script());
2294 all_string_sub(add_script, "%u", account, sizeof(account));
2295 add_ret = smbrun(add_script,NULL);
2296 DEBUG(3,("_api_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2301 nt_status = pdb_init_sam_new(&sam_pass, account);
2302 if (!NT_STATUS_IS_OK(nt_status))
2305 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2307 if (!pdb_add_sam_account(sam_pass)) {
2308 pdb_free_sam(&sam_pass);
2309 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2311 return NT_STATUS_ACCESS_DENIED;
2314 /* Get the user's SID */
2315 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2317 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2318 se_map_generic(&des_access, &usr_generic_mapping);
2319 if (!NT_STATUS_IS_OK(nt_status =
2320 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2321 des_access, &acc_granted, "_samr_create_user"))) {
2325 /* associate the user's SID with the new handle. */
2326 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2327 pdb_free_sam(&sam_pass);
2328 return NT_STATUS_NO_MEMORY;
2333 info->acc_granted = acc_granted;
2335 /* get a (unique) handle. open a policy on it. */
2336 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2337 pdb_free_sam(&sam_pass);
2338 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2341 r_u->user_rid=pdb_get_user_rid(sam_pass);
2343 r_u->access_granted = acc_granted;
2345 pdb_free_sam(&sam_pass);
2347 return NT_STATUS_OK;
2350 /*******************************************************************
2351 samr_reply_connect_anon
2352 ********************************************************************/
2354 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2356 struct samr_info *info = NULL;
2360 if (!pipe_access_check(p)) {
2361 DEBUG(3, ("access denied to samr_connect_anon\n"));
2362 r_u->status = NT_STATUS_ACCESS_DENIED;
2366 /* set up the SAMR connect_anon response */
2368 r_u->status = NT_STATUS_OK;
2370 /* associate the user's SID with the new handle. */
2371 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2372 return NT_STATUS_NO_MEMORY;
2374 info->status = q_u->unknown_0;
2376 /* get a (unique) handle. open a policy on it. */
2377 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2378 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2383 /*******************************************************************
2385 ********************************************************************/
2387 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2389 struct samr_info *info = NULL;
2390 SEC_DESC *psd = NULL;
2392 uint32 des_access = q_u->access_mask;
2397 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2401 if (!pipe_access_check(p)) {
2402 DEBUG(3, ("access denied to samr_connect\n"));
2403 r_u->status = NT_STATUS_ACCESS_DENIED;
2407 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2408 se_map_generic(&des_access, &sam_generic_mapping);
2409 if (!NT_STATUS_IS_OK(nt_status =
2410 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2411 des_access, &acc_granted, "_samr_connect"))) {
2415 r_u->status = NT_STATUS_OK;
2417 /* associate the user's SID and access granted with the new handle. */
2418 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2419 return NT_STATUS_NO_MEMORY;
2421 info->acc_granted = acc_granted;
2422 info->status = q_u->access_mask;
2424 /* get a (unique) handle. open a policy on it. */
2425 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2426 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2428 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2433 /*******************************************************************
2435 ********************************************************************/
2437 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2439 struct samr_info *info = NULL;
2440 SEC_DESC *psd = NULL;
2442 uint32 des_access = q_u->access_mask;
2447 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2451 if (!pipe_access_check(p)) {
2452 DEBUG(3, ("access denied to samr_connect4\n"));
2453 r_u->status = NT_STATUS_ACCESS_DENIED;
2457 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2458 se_map_generic(&des_access, &sam_generic_mapping);
2459 if (!NT_STATUS_IS_OK(nt_status =
2460 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2461 des_access, &acc_granted, "_samr_connect"))) {
2465 r_u->status = NT_STATUS_OK;
2467 /* associate the user's SID and access granted with the new handle. */
2468 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2469 return NT_STATUS_NO_MEMORY;
2471 info->acc_granted = acc_granted;
2472 info->status = q_u->access_mask;
2474 /* get a (unique) handle. open a policy on it. */
2475 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2476 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2478 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2483 /**********************************************************************
2484 api_samr_lookup_domain
2485 **********************************************************************/
2487 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2489 struct samr_info *info;
2490 fstring domain_name;
2493 r_u->status = NT_STATUS_OK;
2495 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2496 return NT_STATUS_INVALID_HANDLE;
2498 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain"))) {
2502 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2506 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2507 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2510 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2512 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2517 /******************************************************************
2518 makes a SAMR_R_ENUM_DOMAINS structure.
2519 ********************************************************************/
2521 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2522 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2528 DEBUG(5, ("make_enum_domains\n"));
2531 *pp_uni_name = NULL;
2533 if (num_sam_entries == 0)
2536 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2537 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2539 if (sam == NULL || uni_name == NULL)
2542 for (i = 0; i < num_sam_entries; i++) {
2543 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
2545 init_sam_entry(&sam[i], len, 0);
2546 init_unistr2(&uni_name[i], doms[i], len);
2550 *pp_uni_name = uni_name;
2555 /**********************************************************************
2556 api_samr_enum_domains
2557 **********************************************************************/
2559 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2561 struct samr_info *info;
2562 uint32 num_entries = 2;
2566 r_u->status = NT_STATUS_OK;
2568 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2569 return NT_STATUS_INVALID_HANDLE;
2571 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2575 name = get_global_sam_name();
2577 fstrcpy(dom[0],name);
2579 fstrcpy(dom[1],"Builtin");
2581 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2582 return NT_STATUS_NO_MEMORY;
2584 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2589 /*******************************************************************
2591 ********************************************************************/
2593 NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2596 POLICY_HND domain_pol = q_u->dom_pol;
2597 uint32 alias_rid = q_u->rid_alias;
2598 POLICY_HND *alias_pol = &r_u->pol;
2599 struct samr_info *info = NULL;
2600 SEC_DESC *psd = NULL;
2602 uint32 des_access = q_u->access_mask;
2606 r_u->status = NT_STATUS_OK;
2608 /* find the domain policy and get the SID / access bits stored in the domain policy */
2609 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2610 return NT_STATUS_INVALID_HANDLE;
2612 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2616 /* append the alias' RID to it */
2617 if (!sid_append_rid(&sid, alias_rid))
2618 return NT_STATUS_NO_SUCH_USER;
2620 /*check if access can be granted as requested by client. */
2621 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2622 se_map_generic(&des_access,&ali_generic_mapping);
2623 if (!NT_STATUS_IS_OK(status =
2624 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2625 des_access, &acc_granted, "_samr_open_alias"))) {
2630 * we should check if the rid really exist !!!
2634 /* associate the user's SID with the new handle. */
2635 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2636 return NT_STATUS_NO_MEMORY;
2638 info->acc_granted = acc_granted;
2640 /* get a (unique) handle. open a policy on it. */
2641 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2642 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2647 /*******************************************************************
2649 ********************************************************************/
2651 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2653 SAM_ACCOUNT *pwd =NULL;
2658 ret = pdb_getsampwsid(pwd, sid);
2666 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2671 /* FIX ME: check if the value is really changed --metze */
2672 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2677 if(!pdb_update_sam_account(pwd)) {
2687 /*******************************************************************
2689 ********************************************************************/
2691 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2693 SAM_ACCOUNT *pwd = NULL;
2697 if(!pdb_getsampwsid(pwd, sid)) {
2703 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2708 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2712 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2716 if (!pdb_set_pass_changed_now (pwd)) {
2721 if(!pdb_update_sam_account(pwd)) {
2730 /*******************************************************************
2731 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2732 ********************************************************************/
2733 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2738 if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2740 DEBUG(2,("Could not get gid for primary group of "
2741 "user %s\n", pdb_get_username(sampass)));
2745 grp = getgrgid(gid);
2748 DEBUG(2,("Could not find primary group %d for "
2749 "user %s\n", gid, pdb_get_username(sampass)));
2753 if (smb_set_primary_group(grp->gr_name,
2754 pdb_get_username(sampass)) != 0) {
2755 DEBUG(2,("Could not set primary group for user %s to "
2757 pdb_get_username(sampass), grp->gr_name));
2765 /*******************************************************************
2767 ********************************************************************/
2769 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2771 SAM_ACCOUNT *pwd = NULL;
2774 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2780 if (!pdb_getsampwsid(pwd, sid)) {
2785 copy_id21_to_sam_passwd(pwd, id21);
2788 * The funny part about the previous two calls is
2789 * that pwd still has the password hashes from the
2790 * passdb entry. These have not been updated from
2791 * id21. I don't know if they need to be set. --jerry
2794 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2795 set_unix_primary_group(pwd);
2797 /* write the change out */
2798 if(!pdb_update_sam_account(pwd)) {
2808 /*******************************************************************
2810 ********************************************************************/
2812 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2814 SAM_ACCOUNT *pwd = NULL;
2815 pstring plaintext_buf;
2820 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2826 if (!pdb_getsampwsid(pwd, sid)) {
2831 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2832 pdb_get_username(pwd)));
2834 acct_ctrl = pdb_get_acct_ctrl(pwd);
2836 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
2841 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2846 copy_id23_to_sam_passwd(pwd, id23);
2848 /* if it's a trust account, don't update /etc/passwd */
2849 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2850 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2851 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2852 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2854 /* update the UNIX password */
2855 if (lp_unix_password_sync() )
2856 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2862 ZERO_STRUCT(plaintext_buf);
2864 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2865 set_unix_primary_group(pwd);
2867 if(!pdb_update_sam_account(pwd)) {
2877 /*******************************************************************
2879 ********************************************************************/
2881 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2883 SAM_ACCOUNT *pwd = NULL;
2885 pstring plaintext_buf;
2890 if (!pdb_getsampwsid(pwd, sid)) {
2895 DEBUG(5, ("Attempting administrator password change for user %s\n",
2896 pdb_get_username(pwd)));
2898 acct_ctrl = pdb_get_acct_ctrl(pwd);
2900 ZERO_STRUCT(plaintext_buf);
2902 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) {
2907 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2912 /* if it's a trust account, don't update /etc/passwd */
2913 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2914 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2915 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2916 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2918 /* update the UNIX password */
2919 if (lp_unix_password_sync()) {
2920 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2927 ZERO_STRUCT(plaintext_buf);
2929 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2931 /* update the SAMBA password */
2932 if(!pdb_update_sam_account(pwd)) {
2942 /*******************************************************************
2943 samr_reply_set_userinfo
2944 ********************************************************************/
2946 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2949 POLICY_HND *pol = &q_u->pol;
2950 uint16 switch_value = q_u->switch_value;
2951 SAM_USERINFO_CTR *ctr = q_u->ctr;
2953 uint32 acc_required;
2955 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2957 r_u->status = NT_STATUS_OK;
2959 /* find the policy handle. open a policy on it. */
2960 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2961 return NT_STATUS_INVALID_HANDLE;
2963 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
2964 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2968 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
2971 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2972 return NT_STATUS_INVALID_INFO_CLASS;
2975 /* ok! user info levels (lots: see MSDEV help), off we go... */
2976 switch (switch_value) {
2978 if (!set_user_info_12(ctr->info.id12, &sid))
2979 return NT_STATUS_ACCESS_DENIED;
2983 SamOEMhash(ctr->info.id24->pass, p->session_key, 516);
2985 dump_data(100, (char *)ctr->info.id24->pass, 516);
2987 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
2988 return NT_STATUS_ACCESS_DENIED;
2994 * Currently we don't really know how to unmarshall
2995 * the level 25 struct, and the password encryption
2996 * is different. This is a placeholder for when we
2997 * do understand it. In the meantime just return INVALID
2998 * info level and W2K SP2 drops down to level 23... JRA.
3001 SamOEMhash(ctr->info.id25->pass, p->session_key, 532);
3003 dump_data(100, (char *)ctr->info.id25->pass, 532);
3005 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3006 return NT_STATUS_ACCESS_DENIED;
3009 return NT_STATUS_INVALID_INFO_CLASS;
3012 SamOEMhash(ctr->info.id23->pass, p->session_key, 516);
3014 dump_data(100, (char *)ctr->info.id23->pass, 516);
3016 if (!set_user_info_23(ctr->info.id23, &sid))
3017 return NT_STATUS_ACCESS_DENIED;
3021 return NT_STATUS_INVALID_INFO_CLASS;
3027 /*******************************************************************
3028 samr_reply_set_userinfo2
3029 ********************************************************************/
3031 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3034 SAM_USERINFO_CTR *ctr = q_u->ctr;
3035 POLICY_HND *pol = &q_u->pol;
3036 uint16 switch_value = q_u->switch_value;
3038 uint32 acc_required;
3040 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3042 r_u->status = NT_STATUS_OK;
3044 /* find the policy handle. open a policy on it. */
3045 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3046 return NT_STATUS_INVALID_HANDLE;
3048 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3049 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3053 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3056 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3057 return NT_STATUS_INVALID_INFO_CLASS;
3060 switch_value=ctr->switch_value;
3062 /* ok! user info levels (lots: see MSDEV help), off we go... */
3063 switch (switch_value) {
3065 if (!set_user_info_21(ctr->info.id21, &sid))
3066 return NT_STATUS_ACCESS_DENIED;
3069 if (!set_user_info_10(ctr->info.id10, &sid))
3070 return NT_STATUS_ACCESS_DENIED;
3073 /* Used by AS/U JRA. */
3074 if (!set_user_info_12(ctr->info.id12, &sid))
3075 return NT_STATUS_ACCESS_DENIED;
3078 return NT_STATUS_INVALID_INFO_CLASS;
3084 /*********************************************************************
3085 _samr_query_aliasmem
3086 *********************************************************************/
3088 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3090 int num_groups = 0, tmp_num_groups=0;
3091 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3092 struct samr_info *info = NULL;
3098 /* until i see a real useraliases query, we fack one up */
3100 /* I have seen one, JFM 2/12/2001 */
3102 * Explanation of what this call does:
3103 * for all the SID given in the request:
3104 * return a list of alias (local groups)
3105 * that have those SID as members.
3107 * and that's the alias in the domain specified
3108 * in the policy_handle
3110 * if the policy handle is on an incorrect sid
3111 * for example a user's sid
3112 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3115 r_u->status = NT_STATUS_OK;
3117 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3119 /* find the policy handle. open a policy on it. */
3120 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3121 return NT_STATUS_INVALID_HANDLE;
3123 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3124 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3126 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3127 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3128 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3129 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3133 if (!sid_check_is_domain(&info->sid) &&
3134 !sid_check_is_builtin(&info->sid))
3135 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3138 for (i=0; i<q_u->num_sids1; i++) {
3140 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3143 * if there is an error, we just continue as
3144 * it can be an unfound user or group
3146 if (!NT_STATUS_IS_OK(r_u->status)) {
3147 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3151 if (tmp_num_groups==0) {
3152 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3156 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3157 if (new_rids==NULL) {
3158 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3159 return NT_STATUS_NO_MEMORY;
3163 for (j=0; j<tmp_num_groups; j++)
3164 rids[j+num_groups]=tmp_rids[j];
3166 safe_free(tmp_rids);
3168 num_groups+=tmp_num_groups;
3171 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3172 return NT_STATUS_OK;
3175 /*********************************************************************
3176 _samr_query_aliasmem
3177 *********************************************************************/
3179 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3191 fstring alias_sid_str;
3194 SAM_ACCOUNT *sam_user = NULL;
3198 /* find the policy handle. open a policy on it. */
3199 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3200 return NT_STATUS_INVALID_HANDLE;
3202 if (!NT_STATUS_IS_OK(r_u->status =
3203 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3207 sid_copy(&als_sid, &alias_sid);
3208 sid_to_string(alias_sid_str, &alias_sid);
3209 sid_split_rid(&alias_sid, &alias_rid);
3211 DEBUG(10, ("sid is %s\n", alias_sid_str));
3213 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
3214 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3215 if(!get_builtin_group_from_sid(als_sid, &map))
3216 return NT_STATUS_NO_SUCH_ALIAS;
3218 if (sid_equal(&alias_sid, get_global_sam_sid())) {
3219 DEBUG(10, ("lookup on Server SID\n"));
3220 if(!get_local_group_from_sid(als_sid, &map))
3221 return NT_STATUS_NO_SUCH_ALIAS;
3225 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3226 return NT_STATUS_NO_SUCH_ALIAS;
3228 DEBUG(10, ("sid is %s\n", alias_sid_str));
3229 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
3230 if (num_uids!=0 && sid == NULL)
3231 return NT_STATUS_NO_MEMORY;
3233 for (i = 0; i < num_uids; i++) {
3234 struct passwd *pass;
3237 sid_copy(&temp_sid, get_global_sam_sid());
3239 pass = getpwuid_alloc(uid[i]);
3240 if (!pass) continue;
3242 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3248 check = pdb_getsampwnam(sam_user, pass->pw_name);
3251 if (check != True) {
3252 pdb_free_sam(&sam_user);
3257 rid = pdb_get_user_rid(sam_user);
3259 pdb_free_sam(&sam_user);
3264 pdb_free_sam(&sam_user);
3267 sid_append_rid(&temp_sid, rid);
3269 init_dom_sid2(&sid[i], &temp_sid);
3272 DEBUG(10, ("sid is %s\n", alias_sid_str));
3273 init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
3275 return NT_STATUS_OK;
3278 /*********************************************************************
3279 _samr_query_groupmem
3280 *********************************************************************/
3282 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3288 fstring group_sid_str;
3296 SAM_ACCOUNT *sam_user = NULL;
3300 /* find the policy handle. open a policy on it. */
3301 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3302 return NT_STATUS_INVALID_HANDLE;
3304 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3308 /* todo: change to use sid_compare_front */
3310 sid_split_rid(&group_sid, &group_rid);
3311 sid_to_string(group_sid_str, &group_sid);
3312 DEBUG(10, ("sid is %s\n", group_sid_str));
3314 /* can we get a query for an SID outside our domain ? */
3315 if (!sid_equal(&group_sid, get_global_sam_sid()))
3316 return NT_STATUS_NO_SUCH_GROUP;
3318 sid_append_rid(&group_sid, group_rid);
3319 DEBUG(10, ("lookup on Domain SID\n"));
3321 if(!get_domain_group_from_sid(group_sid, &map))
3322 return NT_STATUS_NO_SUCH_GROUP;
3324 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3325 return NT_STATUS_NO_SUCH_GROUP;
3327 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3328 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3330 if (num_uids!=0 && (rid==NULL || attr==NULL))
3331 return NT_STATUS_NO_MEMORY;
3333 for (i=0; i<num_uids; i++) {
3334 struct passwd *pass;
3337 pass = getpwuid_alloc(uid[i]);
3338 if (!pass) continue;
3340 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3346 check = pdb_getsampwnam(sam_user, pass->pw_name);
3349 if (check != True) {
3350 pdb_free_sam(&sam_user);
3355 urid = pdb_get_user_rid(sam_user);
3357 pdb_free_sam(&sam_user);
3362 pdb_free_sam(&sam_user);
3366 attr[i] = SID_NAME_USER;
3369 init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
3371 return NT_STATUS_OK;
3374 /*********************************************************************
3376 *********************************************************************/
3378 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3381 fstring alias_sid_str;
3388 SAM_ACCOUNT *sam_user = NULL;
3392 /* Find the policy handle. Open a policy on it. */
3393 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3394 return NT_STATUS_INVALID_HANDLE;
3396 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3400 sid_to_string(alias_sid_str, &alias_sid);
3401 DEBUG(10, ("sid is %s\n", alias_sid_str));
3403 if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
3404 DEBUG(10, ("adding member on Server SID\n"));
3405 if(!get_local_group_from_sid(alias_sid, &map))
3406 return NT_STATUS_NO_SUCH_ALIAS;
3409 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
3410 DEBUG(10, ("adding member on BUILTIN SID\n"));
3411 if( !get_local_group_from_sid(alias_sid, &map))
3412 return NT_STATUS_NO_SUCH_ALIAS;
3415 return NT_STATUS_NO_SUCH_ALIAS;
3418 ret = pdb_init_sam(&sam_user);
3419 if (!NT_STATUS_IS_OK(ret))
3422 check = pdb_getsampwsid(sam_user, &q_u->sid.sid);
3424 if (check != True) {
3425 pdb_free_sam(&sam_user);
3426 return NT_STATUS_NO_SUCH_USER;
3429 /* check a real user exist before we run the script to add a user to a group */
3430 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3431 pdb_free_sam(&sam_user);
3432 return NT_STATUS_NO_SUCH_USER;
3435 pdb_free_sam(&sam_user);
3437 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3438 return NT_STATUS_NO_SUCH_USER;
3441 if ((grp=getgrgid(map.gid)) == NULL) {
3443 return NT_STATUS_NO_SUCH_ALIAS;
3446 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3447 fstrcpy(grp_name, grp->gr_name);
3449 /* if the user is already in the group */
3450 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3452 return NT_STATUS_MEMBER_IN_ALIAS;
3456 * ok, the group exist, the user exist, the user is not in the group,
3457 * we can (finally) add it to the group !
3459 smb_add_user_group(grp_name, pwd->pw_name);
3461 /* check if the user has been added then ... */
3462 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3464 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3468 return NT_STATUS_OK;
3471 /*********************************************************************
3473 *********************************************************************/
3475 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3478 fstring alias_sid_str;
3482 SAM_ACCOUNT *sam_pass=NULL;
3485 /* Find the policy handle. Open a policy on it. */
3486 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3487 return NT_STATUS_INVALID_HANDLE;
3489 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3493 sid_to_string(alias_sid_str, &alias_sid);
3494 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
3496 if (!sid_check_is_in_our_domain(&alias_sid) &&
3497 !sid_check_is_in_builtin(&alias_sid)) {
3498 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3499 return NT_STATUS_NO_SUCH_ALIAS;
3502 if( !get_local_group_from_sid(alias_sid, &map))
3503 return NT_STATUS_NO_SUCH_ALIAS;
3505 if ((grp=getgrgid(map.gid)) == NULL)
3506 return NT_STATUS_NO_SUCH_ALIAS;
3508 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3509 fstrcpy(grp_name, grp->gr_name);
3511 /* check if the user exists before trying to remove it from the group */
3512 pdb_init_sam(&sam_pass);
3513 if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
3514 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3515 pdb_free_sam(&sam_pass);
3516 return NT_STATUS_NO_SUCH_USER;
3519 /* if the user is not in the group */
3520 if(!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3521 pdb_free_sam(&sam_pass);
3522 return NT_STATUS_MEMBER_IN_ALIAS;
3525 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3527 /* check if the user has been removed then ... */
3528 if(user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3529 pdb_free_sam(&sam_pass);
3530 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3533 pdb_free_sam(&sam_pass);
3534 return NT_STATUS_OK;
3537 /*********************************************************************
3539 *********************************************************************/
3541 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3545 fstring group_sid_str;
3552 SAM_ACCOUNT *sam_user=NULL;
3556 /* Find the policy handle. Open a policy on it. */
3557 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3558 return NT_STATUS_INVALID_HANDLE;
3560 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3564 sid_to_string(group_sid_str, &group_sid);
3565 DEBUG(10, ("sid is %s\n", group_sid_str));
3567 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3568 return NT_STATUS_NO_SUCH_GROUP;
3570 DEBUG(10, ("lookup on Domain SID\n"));
3572 if(!get_domain_group_from_sid(group_sid, &map))
3573 return NT_STATUS_NO_SUCH_GROUP;
3575 sid_copy(&user_sid, get_global_sam_sid());
3576 sid_append_rid(&user_sid, q_u->rid);
3578 ret = pdb_init_sam(&sam_user);
3579 if (!NT_STATUS_IS_OK(ret))
3582 check = pdb_getsampwsid(sam_user, &user_sid);
3584 if (check != True) {
3585 pdb_free_sam(&sam_user);
3586 return NT_STATUS_NO_SUCH_USER;
3589 /* check a real user exist before we run the script to add a user to a group */
3590 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3591 pdb_free_sam(&sam_user);
3592 return NT_STATUS_NO_SUCH_USER;
3595 pdb_free_sam(&sam_user);
3597 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3598 return NT_STATUS_NO_SUCH_USER;
3601 if ((grp=getgrgid(map.gid)) == NULL) {
3603 return NT_STATUS_NO_SUCH_GROUP;
3606 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3607 fstrcpy(grp_name, grp->gr_name);
3609 /* if the user is already in the group */
3610 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3612 return NT_STATUS_MEMBER_IN_GROUP;
3616 * ok, the group exist, the user exist, the user is not in the group,
3618 * we can (finally) add it to the group !
3621 smb_add_user_group(grp_name, pwd->pw_name);
3623 /* check if the user has been added then ... */
3624 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3626 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3630 return NT_STATUS_OK;
3633 /*********************************************************************
3635 *********************************************************************/
3637 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3641 SAM_ACCOUNT *sam_pass=NULL;
3648 * delete the group member named q_u->rid
3649 * who is a member of the sid associated with the handle
3650 * the rid is a user's rid as the group is a domain group.
3653 /* Find the policy handle. Open a policy on it. */
3654 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3655 return NT_STATUS_INVALID_HANDLE;
3657 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3661 if (!sid_check_is_in_our_domain(&group_sid))
3662 return NT_STATUS_NO_SUCH_GROUP;
3664 sid_copy(&user_sid, get_global_sam_sid());
3665 sid_append_rid(&user_sid, q_u->rid);
3667 if (!get_domain_group_from_sid(group_sid, &map))
3668 return NT_STATUS_NO_SUCH_GROUP;
3670 if ((grp=getgrgid(map.gid)) == NULL)
3671 return NT_STATUS_NO_SUCH_GROUP;
3673 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3674 fstrcpy(grp_name, grp->gr_name);
3676 /* check if the user exists before trying to remove it from the group */
3677 pdb_init_sam(&sam_pass);
3678 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3679 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3680 pdb_free_sam(&sam_pass);
3681 return NT_STATUS_NO_SUCH_USER;
3684 /* if the user is not in the group */
3685 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3686 pdb_free_sam(&sam_pass);
3687 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3690 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3692 /* check if the user has been removed then ... */
3693 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3694 pdb_free_sam(&sam_pass);
3695 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3698 pdb_free_sam(&sam_pass);
3699 return NT_STATUS_OK;
3703 /****************************************************************************
3704 Delete a UNIX user on demand.
3705 ****************************************************************************/
3707 static int smb_delete_user(const char *unix_user)
3712 pstrcpy(del_script, lp_deluser_script());
3715 all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3716 ret = smbrun(del_script,NULL);
3717 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3721 /*********************************************************************
3722 _samr_delete_dom_user
3723 *********************************************************************/
3725 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3728 SAM_ACCOUNT *sam_pass=NULL;
3731 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3733 /* Find the policy handle. Open a policy on it. */
3734 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3735 return NT_STATUS_INVALID_HANDLE;
3737 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3741 if (!sid_check_is_in_our_domain(&user_sid))
3742 return NT_STATUS_CANNOT_DELETE;
3744 /* check if the user exists before trying to delete */
3745 pdb_init_sam(&sam_pass);
3746 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3747 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3748 pdb_free_sam(&sam_pass);
3749 return NT_STATUS_NO_SUCH_USER;
3752 /* delete the unix side */
3754 * note: we don't check if the delete really happened
3755 * as the script is not necessary present
3756 * and maybe the sysadmin doesn't want to delete the unix side
3758 smb_delete_user(pdb_get_username(sam_pass));
3760 /* and delete the samba side */
3761 if (!pdb_delete_sam_account(sam_pass)) {
3762 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3763 pdb_free_sam(&sam_pass);
3764 return NT_STATUS_CANNOT_DELETE;
3767 pdb_free_sam(&sam_pass);
3769 if (!close_policy_hnd(p, &q_u->user_pol))
3770 return NT_STATUS_OBJECT_NAME_INVALID;
3772 return NT_STATUS_OK;
3775 /*********************************************************************
3776 _samr_delete_dom_group
3777 *********************************************************************/
3779 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3784 fstring group_sid_str;
3790 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3792 /* Find the policy handle. Open a policy on it. */
3793 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3794 return NT_STATUS_INVALID_HANDLE;
3796 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3800 sid_copy(&dom_sid, &group_sid);
3801 sid_to_string(group_sid_str, &dom_sid);
3802 sid_split_rid(&dom_sid, &group_rid);
3804 DEBUG(10, ("sid is %s\n", group_sid_str));
3806 /* we check if it's our SID before deleting */
3807 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3808 return NT_STATUS_NO_SUCH_GROUP;
3810 DEBUG(10, ("lookup on Domain SID\n"));
3812 if(!get_domain_group_from_sid(group_sid, &map))
3813 return NT_STATUS_NO_SUCH_GROUP;
3817 /* check if group really exists */
3818 if ( (grp=getgrgid(gid)) == NULL)
3819 return NT_STATUS_NO_SUCH_GROUP;
3821 /* we can delete the UNIX group */
3822 smb_delete_group(grp->gr_name);
3824 /* check if the group has been successfully deleted */
3825 if ( (grp=getgrgid(gid)) != NULL)
3826 return NT_STATUS_ACCESS_DENIED;
3828 if(!pdb_delete_group_mapping_entry(group_sid))
3829 return NT_STATUS_ACCESS_DENIED;
3831 if (!close_policy_hnd(p, &q_u->group_pol))
3832 return NT_STATUS_OBJECT_NAME_INVALID;
3834 return NT_STATUS_OK;
3837 /*********************************************************************
3838 _samr_delete_dom_alias
3839 *********************************************************************/
3841 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3846 fstring alias_sid_str;
3852 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3854 /* Find the policy handle. Open a policy on it. */
3855 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3856 return NT_STATUS_INVALID_HANDLE;
3858 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3862 sid_copy(&dom_sid, &alias_sid);
3863 sid_to_string(alias_sid_str, &dom_sid);
3864 sid_split_rid(&dom_sid, &alias_rid);
3866 DEBUG(10, ("sid is %s\n", alias_sid_str));
3868 /* we check if it's our SID before deleting */
3869 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3870 return NT_STATUS_NO_SUCH_ALIAS;
3872 DEBUG(10, ("lookup on Local SID\n"));
3874 if(!get_local_group_from_sid(alias_sid, &map))
3875 return NT_STATUS_NO_SUCH_ALIAS;
3879 /* check if group really exists */
3880 if ( (grp=getgrgid(gid)) == NULL)
3881 return NT_STATUS_NO_SUCH_ALIAS;
3883 /* we can delete the UNIX group */
3884 smb_delete_group(grp->gr_name);
3886 /* check if the group has been successfully deleted */
3887 if ( (grp=getgrgid(gid)) != NULL)
3888 return NT_STATUS_ACCESS_DENIED;
3890 /* don't check if we removed it as it could be an un-mapped group */
3891 pdb_delete_group_mapping_entry(alias_sid);
3893 if (!close_policy_hnd(p, &q_u->alias_pol))
3894 return NT_STATUS_OBJECT_NAME_INVALID;
3896 return NT_STATUS_OK;
3899 /*********************************************************************
3900 _samr_create_dom_group
3901 *********************************************************************/
3903 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3910 struct samr_info *info;
3914 /* Find the policy handle. Open a policy on it. */
3915 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3916 return NT_STATUS_INVALID_HANDLE;
3918 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3922 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3923 return NT_STATUS_ACCESS_DENIED;
3925 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3927 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3929 /* check if group already exist */
3930 if ((grp=getgrnam(name)) != NULL)
3931 return NT_STATUS_GROUP_EXISTS;
3933 /* we can create the UNIX group */
3934 if (smb_create_group(name, &gid) != 0)
3935 return NT_STATUS_ACCESS_DENIED;
3937 /* check if the group has been successfully created */
3938 if ((grp=getgrgid(gid)) == NULL)
3939 return NT_STATUS_ACCESS_DENIED;
3941 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3943 /* add the group to the mapping table */
3944 sid_copy(&info_sid, get_global_sam_sid());
3945 sid_append_rid(&info_sid, r_u->rid);
3946 sid_to_string(sid_string, &info_sid);
3948 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
3949 return NT_STATUS_ACCESS_DENIED;
3951 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3952 return NT_STATUS_NO_MEMORY;
3954 /* get a (unique) handle. open a policy on it. */
3955 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3956 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3958 return NT_STATUS_OK;
3961 /*********************************************************************
3962 _samr_create_dom_alias
3963 *********************************************************************/
3965 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3972 struct samr_info *info;
3976 /* Find the policy handle. Open a policy on it. */
3977 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
3978 return NT_STATUS_INVALID_HANDLE;
3980 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3984 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3985 return NT_STATUS_ACCESS_DENIED;
3987 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3989 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3991 /* check if group already exists */
3992 if ( (grp=getgrnam(name)) != NULL)
3993 return NT_STATUS_GROUP_EXISTS;
3995 /* we can create the UNIX group */
3996 if (smb_create_group(name, &gid) != 0)
3997 return NT_STATUS_ACCESS_DENIED;
3999 /* check if the group has been successfully created */
4000 if ((grp=getgrgid(gid)) == NULL)
4001 return NT_STATUS_ACCESS_DENIED;
4003 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
4005 sid_copy(&info_sid, get_global_sam_sid());
4006 sid_append_rid(&info_sid, r_u->rid);
4007 sid_to_string(sid_string, &info_sid);
4009 /* add the group to the mapping table */
4010 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL))
4011 return NT_STATUS_ACCESS_DENIED;
4013 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4014 return NT_STATUS_NO_MEMORY;
4016 /* get a (unique) handle. open a policy on it. */
4017 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4018 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4020 return NT_STATUS_OK;
4023 /*********************************************************************
4024 _samr_query_groupinfo
4026 sends the name/comment pair of a domain group
4027 level 1 send also the number of users of that group
4028 *********************************************************************/
4030 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4036 GROUP_INFO_CTR *ctr;
4039 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4040 return NT_STATUS_INVALID_HANDLE;
4042 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4046 if (!get_domain_group_from_sid(group_sid, &map))
4047 return NT_STATUS_INVALID_HANDLE;
4049 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
4051 return NT_STATUS_NO_MEMORY;
4053 switch (q_u->switch_level) {
4055 ctr->switch_value1 = 1;
4056 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
4057 return NT_STATUS_NO_SUCH_GROUP;
4058 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
4062 ctr->switch_value1 = 3;
4063 init_samr_group_info3(&ctr->group.info3);
4066 ctr->switch_value1 = 4;
4067 init_samr_group_info4(&ctr->group.info4, map.comment);
4070 return NT_STATUS_INVALID_INFO_CLASS;
4073 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4075 return NT_STATUS_OK;
4078 /*********************************************************************
4081 update a domain group's comment.
4082 *********************************************************************/
4084 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4088 GROUP_INFO_CTR *ctr;
4091 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4092 return NT_STATUS_INVALID_HANDLE;
4094 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4098 if (!get_domain_group_from_sid(group_sid, &map))
4099 return NT_STATUS_NO_SUCH_GROUP;
4103 switch (ctr->switch_value1) {
4105 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4108 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4111 return NT_STATUS_INVALID_INFO_CLASS;
4114 if(!pdb_update_group_mapping_entry(&map)) {
4115 return NT_STATUS_NO_SUCH_GROUP;
4118 return NT_STATUS_OK;
4121 /*********************************************************************
4124 update an alias's comment.
4125 *********************************************************************/
4127 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4131 ALIAS_INFO_CTR *ctr;
4134 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4135 return NT_STATUS_INVALID_HANDLE;
4137 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4141 if (!get_local_group_from_sid(group_sid, &map))
4142 return NT_STATUS_NO_SUCH_GROUP;
4146 switch (ctr->switch_value1) {
4148 unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
4151 return NT_STATUS_INVALID_INFO_CLASS;
4154 if(!pdb_update_group_mapping_entry(&map)) {
4155 return NT_STATUS_NO_SUCH_GROUP;
4158 return NT_STATUS_OK;
4161 /*********************************************************************
4162 _samr_get_dom_pwinfo
4163 *********************************************************************/
4165 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4167 /* Perform access check. Since this rpc does not require a
4168 policy handle it will not be caught by the access checks on
4169 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4171 if (!pipe_access_check(p)) {
4172 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4173 r_u->status = NT_STATUS_ACCESS_DENIED;
4177 /* Actually, returning zeros here works quite well :-). */
4179 return NT_STATUS_OK;
4182 /*********************************************************************
4184 *********************************************************************/
4186 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4191 struct samr_info *info;
4192 SEC_DESC *psd = NULL;
4199 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4200 return NT_STATUS_INVALID_HANDLE;
4202 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4206 /*check if access can be granted as requested by client. */
4207 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4208 se_map_generic(&des_access,&grp_generic_mapping);
4209 if (!NT_STATUS_IS_OK(status =
4210 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4211 des_access, &acc_granted, "_samr_open_group"))) {
4216 /* this should not be hard-coded like this */
4217 if (!sid_equal(&sid, get_global_sam_sid()))
4218 return NT_STATUS_ACCESS_DENIED;
4220 sid_copy(&info_sid, get_global_sam_sid());
4221 sid_append_rid(&info_sid, q_u->rid_group);
4222 sid_to_string(sid_string, &info_sid);
4224 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4225 return NT_STATUS_NO_MEMORY;
4227 info->acc_granted = acc_granted;
4229 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4231 /* check if that group really exists */
4232 if (!get_domain_group_from_sid(info->sid, &map))
4233 return NT_STATUS_NO_SUCH_GROUP;
4235 /* get a (unique) handle. open a policy on it. */
4236 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4237 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4239 return NT_STATUS_OK;
4242 /*********************************************************************
4244 *********************************************************************/
4246 NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
4248 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
4249 return NT_STATUS_NOT_IMPLEMENTED;
4252 /*******************************************************************
4254 ********************************************************************/
4256 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4258 struct samr_info *info = NULL;
4260 uint32 min_pass_len,pass_hist,flag;
4261 time_t u_expire, u_min_age;
4262 NTTIME nt_expire, nt_min_age;
4264 time_t u_lock_duration, u_reset_time;
4265 NTTIME nt_lock_duration, nt_reset_time;
4271 uint32 num_users=0, num_groups=0, num_aliases=0;
4273 uint32 account_policy_temp;
4275 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4276 return NT_STATUS_NO_MEMORY;
4280 r_u->status = NT_STATUS_OK;
4282 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4284 /* find the policy handle. open a policy on it. */
4285 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4286 return NT_STATUS_INVALID_HANDLE;
4288 switch (q_u->switch_value) {
4290 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4291 min_pass_len = account_policy_temp;
4293 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4294 pass_hist = account_policy_temp;
4296 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4297 flag = account_policy_temp;
4299 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4300 u_expire = account_policy_temp;
4302 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4303 u_min_age = account_policy_temp;
4305 unix_to_nt_time_abs(&nt_expire, u_expire);
4306 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4308 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4309 flag, nt_expire, nt_min_age);
4313 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4315 if (!NT_STATUS_IS_OK(r_u->status)) {
4316 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4319 num_users=info->disp_info.num_user_account;
4322 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4323 if (NT_STATUS_IS_ERR(r_u->status)) {
4324 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4327 num_groups=info->disp_info.num_group_account;
4330 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4331 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
4332 num_users, num_groups, num_aliases);
4335 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4336 u_logout = account_policy_temp;
4338 unix_to_nt_time_abs(&nt_logout, u_logout);
4340 init_unk_info3(&ctr->info.inf3, nt_logout);
4343 init_unk_info5(&ctr->info.inf5, global_myname());
4346 init_unk_info6(&ctr->info.inf6);
4349 init_unk_info7(&ctr->info.inf7);
4352 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4353 u_lock_duration = account_policy_temp;
4355 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4356 u_reset_time = account_policy_temp;
4358 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4359 lockout = account_policy_temp;
4361 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4362 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4364 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4367 return NT_STATUS_INVALID_INFO_CLASS;
4370 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4372 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4377 /*******************************************************************
4379 ********************************************************************/
4381 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4383 time_t u_expire, u_min_age;
4385 time_t u_lock_duration, u_reset_time;
4387 r_u->status = NT_STATUS_OK;
4389 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4391 /* find the policy handle. open a policy on it. */
4392 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4393 return NT_STATUS_INVALID_HANDLE;
4395 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4397 switch (q_u->switch_value) {
4399 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4400 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4402 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4403 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4404 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4405 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4406 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4411 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4412 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4421 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4422 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count);
4424 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4425 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4426 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4429 return NT_STATUS_INVALID_INFO_CLASS;
4432 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4434 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));