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) Jim McDonough <jmcd@us.ibm.com> 2002.
11 * Copyright (C) Gerald (Jerry) Carter 2003.
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, SEC_DESC_SELF_RELATIVE, 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, SEC_DESC_SELF_RELATIVE, 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, SEC_DESC_SELF_RELATIVE, 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, SEC_DESC_SELF_RELATIVE, 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, UNI_STR_TERMINATE);
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, 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 init_unistr2(&uni_name[i], grp[i].name, UNI_STR_TERMINATE);
869 init_sam_entry(&sam[i], &uni_name[i], grp[i].rid);
873 *uni_name_pp = uni_name;
876 /*******************************************************************
877 Get the group entries - similar to get_sampwd_entries().
878 ********************************************************************/
880 static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
881 uint32 *p_num_entries, uint32 max_entries)
884 uint32 num_entries = 0;
887 GROUP_MAP *map = NULL;
889 sid_to_string(sid_str, sid);
890 DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str));
894 /* well-known aliases */
895 if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
898 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;
917 gid_t winbind_gid_low, winbind_gid_high;
918 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) {
937 ret = pdb_getgrgid(&smap, grp->gr_gid);
942 if (smap.sid_name_use!=SID_NAME_ALIAS) {
946 sid_split_rid(&smap.sid, &trid);
948 if (!sid_equal(sid, &smap.sid))
951 /* Don't return winbind groups as they are not local! */
952 if (winbind_groups_exist && (grp->gr_gid >= winbind_gid_low)&&(grp->gr_gid <= winbind_gid_high)) {
953 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
957 /* Don't return user private groups... */
959 if (Get_Pwnam(smap.nt_name) != 0) {
960 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
964 for( i = 0; i < num_entries; i++)
965 if ( (*d_grp)[i].rid == trid )
968 if ( i < num_entries ) {
969 continue; /* rid was there, dup! */
972 /* JRA - added this for large group db enumeration... */
975 /* skip the requested number of entries.
976 not very efficient, but hey...
982 *d_grp=talloc_realloc(ctx,*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
985 return NT_STATUS_NO_MEMORY;
988 fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
989 (*d_grp)[num_entries].rid = trid;
991 DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries, trid));
997 *p_num_entries = num_entries;
999 DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries));
1001 if (num_entries >= max_entries)
1002 return STATUS_MORE_ENTRIES;
1003 return NT_STATUS_OK;
1006 /*******************************************************************
1007 Get the group entries - similar to get_sampwd_entries().
1008 ********************************************************************/
1010 static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
1011 uint32 *p_num_entries, uint32 max_entries)
1013 GROUP_MAP *map=NULL;
1015 uint32 group_entries = 0;
1016 uint32 num_entries = 0;
1020 /* access checks for the users were performed higher up. become/unbecome_root()
1021 needed for some passdb backends to enumerate groups */
1024 pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
1027 num_entries=group_entries-start_idx;
1029 /* limit the number of entries */
1030 if (num_entries>max_entries) {
1031 DEBUG(5,("Limiting to %d entries\n", max_entries));
1032 num_entries=max_entries;
1035 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
1036 if (num_entries!=0 && *d_grp==NULL){
1038 return NT_STATUS_NO_MEMORY;
1041 for (i=0; i<num_entries; i++) {
1042 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
1043 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
1044 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
1045 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
1050 *p_num_entries = num_entries;
1052 return NT_STATUS_OK;
1055 /*******************************************************************
1056 samr_reply_enum_dom_groups
1057 ********************************************************************/
1059 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
1061 DOMAIN_GRP *grp=NULL;
1066 r_u->status = NT_STATUS_OK;
1068 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1069 return NT_STATUS_INVALID_HANDLE;
1071 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
1075 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1077 /* the domain group array is being allocated in the function below */
1078 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))) {
1082 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1084 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
1086 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1092 /*******************************************************************
1093 samr_reply_enum_dom_aliases
1094 ********************************************************************/
1096 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1098 DOMAIN_GRP *grp=NULL;
1099 uint32 num_entries = 0;
1105 r_u->status = NT_STATUS_OK;
1107 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1108 return NT_STATUS_INVALID_HANDLE;
1110 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1114 sid_to_string(sid_str, &sid);
1115 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1117 status = get_group_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1118 &num_entries, MAX_SAM_ENTRIES);
1119 if (NT_STATUS_IS_ERR(status)) return status;
1121 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1125 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1127 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1132 /*******************************************************************
1133 samr_reply_query_dispinfo
1134 ********************************************************************/
1136 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1137 SAMR_R_QUERY_DISPINFO *r_u)
1139 struct samr_info *info = NULL;
1140 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1142 uint32 max_entries=q_u->max_entries;
1143 uint32 enum_context=q_u->start_idx;
1144 uint32 max_size=q_u->max_size;
1146 SAM_DISPINFO_CTR *ctr;
1147 uint32 temp_size=0, total_data_size=0;
1149 uint32 num_account = 0;
1150 enum remote_arch_types ra_type = get_remote_arch();
1151 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1154 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1155 r_u->status = NT_STATUS_OK;
1157 /* find the policy handle. open a policy on it. */
1158 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1159 return NT_STATUS_INVALID_HANDLE;
1161 domain_sid = info->sid;
1164 * calculate how many entries we will return.
1166 * - the number of entries the client asked
1167 * - our limit on that
1168 * - the starting point (enumeration context)
1169 * - the buffer size the client will accept
1173 * We are a lot more like W2K. Instead of reading the SAM
1174 * each time to find the records we need to send back,
1175 * we read it once and link that copy to the sam handle.
1176 * For large user list (over the MAX_SAM_ENTRIES)
1177 * it's a definitive win.
1178 * second point to notice: between enumerations
1179 * our sam is now the same as it's a snapshoot.
1180 * third point: got rid of the static SAM_USER_21 struct
1181 * no more intermediate.
1182 * con: it uses much more memory, as a full copy is stored
1185 * If you want to change it, think twice and think
1186 * of the second point , that's really important.
1191 /* Get what we need from the password database */
1192 switch (q_u->switch_level) {
1194 /* When playing with usrmgr, this is necessary
1195 if you want immediate refresh after editing
1196 a user. I would like to do this after the
1197 setuserinfo2, but we do not have access to
1198 the domain handle in that call, only to the
1199 user handle. Where else does this hurt?
1203 /* We cannot do this here - it kills performace. JRA. */
1204 free_samr_users(info);
1209 /* Level 2 is for all machines, otherwise only 'normal' users */
1210 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1212 if (!NT_STATUS_IS_OK(r_u->status)) {
1213 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1216 num_account = info->disp_info.num_user_account;
1220 r_u->status = load_group_domain_entries(info, &info->sid);
1221 if (!NT_STATUS_IS_OK(r_u->status))
1223 num_account = info->disp_info.num_group_account;
1226 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1227 return NT_STATUS_INVALID_INFO_CLASS;
1230 /* first limit the number of entries we will return */
1231 if(max_entries > max_sam_entries) {
1232 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1233 max_entries = max_sam_entries;
1236 if (enum_context > num_account) {
1237 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1238 return NT_STATUS_NO_MORE_ENTRIES;
1241 /* verify we won't overflow */
1242 if (max_entries > num_account-enum_context) {
1243 max_entries = num_account-enum_context;
1244 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1247 /* calculate the size and limit on the number of entries we will return */
1248 temp_size=max_entries*struct_size;
1250 if (temp_size>max_size) {
1251 max_entries=MIN((max_size/struct_size),max_entries);;
1252 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1255 if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1256 return NT_STATUS_NO_MEMORY;
1260 /* Now create reply structure */
1261 switch (q_u->switch_level) {
1264 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
1265 return NT_STATUS_NO_MEMORY;
1267 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1268 info->disp_info.disp_user_info, &domain_sid);
1269 if (!NT_STATUS_IS_OK(disp_ret))
1274 if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1275 return NT_STATUS_NO_MEMORY;
1277 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1278 info->disp_info.disp_user_info, &domain_sid);
1279 if (!NT_STATUS_IS_OK(disp_ret))
1284 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1285 return NT_STATUS_NO_MEMORY;
1287 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1288 if (!NT_STATUS_IS_OK(disp_ret))
1293 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1294 return NT_STATUS_NO_MEMORY;
1296 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1297 if (!NT_STATUS_IS_OK(disp_ret))
1302 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1303 return NT_STATUS_NO_MEMORY;
1305 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1306 if (!NT_STATUS_IS_OK(disp_ret))
1311 ctr->sam.info = NULL;
1312 return NT_STATUS_INVALID_INFO_CLASS;
1315 /* calculate the total size */
1316 total_data_size=num_account*struct_size;
1318 if (enum_context+max_entries < num_account)
1319 r_u->status = STATUS_MORE_ENTRIES;
1321 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1323 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1329 /*******************************************************************
1330 samr_reply_query_aliasinfo
1331 ********************************************************************/
1333 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1339 r_u->status = NT_STATUS_OK;
1341 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1343 /* find the policy handle. open a policy on it. */
1344 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1345 return NT_STATUS_INVALID_HANDLE;
1346 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1350 if (!sid_check_is_in_our_domain(&sid) &&
1351 !sid_check_is_in_builtin(&sid))
1352 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1354 if (!pdb_getgrsid(&map, sid))
1355 return NT_STATUS_NO_SUCH_ALIAS;
1357 switch (q_u->switch_level) {
1360 r_u->ctr.switch_value1 = 1;
1361 init_samr_alias_info1(&r_u->ctr.alias.info1, map.nt_name, 1, map.comment);
1365 r_u->ctr.switch_value1 = 3;
1366 init_samr_alias_info3(&r_u->ctr.alias.info3, map.comment);
1369 return NT_STATUS_INVALID_INFO_CLASS;
1372 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1378 /*******************************************************************
1379 samr_reply_lookup_ids
1380 ********************************************************************/
1382 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1384 uint32 rid[MAX_SAM_ENTRIES];
1385 int num_rids = q_u->num_sids1;
1387 r_u->status = NT_STATUS_OK;
1389 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1391 if (num_rids > MAX_SAM_ENTRIES) {
1392 num_rids = MAX_SAM_ENTRIES;
1393 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1398 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1400 for (i = 0; i < num_rids && status == 0; i++)
1402 struct sam_passwd *sam_pass;
1406 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1407 q_u->uni_user_name[i].uni_str_len));
1409 /* find the user account */
1411 sam_pass = get_smb21pwd_entry(user_name, 0);
1414 if (sam_pass == NULL)
1416 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1421 rid[i] = sam_pass->user_rid;
1427 rid[0] = BUILTIN_ALIAS_RID_USERS;
1429 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1431 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1437 /*******************************************************************
1439 ********************************************************************/
1441 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1443 uint32 rid[MAX_SAM_ENTRIES];
1445 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1446 enum SID_NAME_USE local_type;
1448 int num_rids = q_u->num_names2;
1453 r_u->status = NT_STATUS_OK;
1455 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1460 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1461 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1465 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 */
1469 if (num_rids > MAX_SAM_ENTRIES) {
1470 num_rids = MAX_SAM_ENTRIES;
1471 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1474 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1476 become_root(); /* local_lookup_name can require root privs */
1478 for (i = 0; i < num_rids; i++) {
1483 r_u->status = NT_STATUS_NONE_MAPPED;
1485 rid [i] = 0xffffffff;
1486 type[i] = SID_NAME_UNKNOWN;
1488 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1491 * we are only looking for a name
1492 * the SID we get back can be outside
1493 * the scope of the pol_sid
1495 * in clear: it prevents to reply to domain\group: yes
1496 * when only builtin\group exists.
1498 * a cleaner code is to add the sid of the domain we're looking in
1499 * to the local_lookup_name function.
1502 if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
1503 sid_split_rid(&sid, &local_rid);
1505 if (sid_equal(&sid, &pol_sid)) {
1508 r_u->status = NT_STATUS_OK;
1515 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1517 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1522 /*******************************************************************
1523 _samr_chgpasswd_user
1524 ********************************************************************/
1526 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1531 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1533 r_u->status = NT_STATUS_OK;
1535 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1536 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1538 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1541 * Pass the user through the NT -> unix user mapping
1545 (void)map_username(user_name);
1548 * UNIX username case mangling not required, pass_oem_change
1549 * is case insensitive.
1552 r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1553 q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1555 init_samr_r_chgpasswd_user(r_u, r_u->status);
1557 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1562 /*******************************************************************
1563 makes a SAMR_R_LOOKUP_RIDS structure.
1564 ********************************************************************/
1566 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1567 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1570 UNIHDR *hdr_name=NULL;
1571 UNISTR2 *uni_name=NULL;
1573 *pp_uni_name = NULL;
1574 *pp_hdr_name = NULL;
1576 if (num_names != 0) {
1577 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1578 if (hdr_name == NULL)
1581 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1582 if (uni_name == NULL)
1586 for (i = 0; i < num_names; i++) {
1587 DEBUG(10, ("names[%d]:%s\n", i, names[i] ? names[i] : ""));
1588 init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
1589 init_uni_hdr(&hdr_name[i], &uni_name[i]);
1592 *pp_uni_name = uni_name;
1593 *pp_hdr_name = hdr_name;
1598 /*******************************************************************
1600 ********************************************************************/
1602 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1604 fstring group_names[MAX_SAM_ENTRIES];
1605 uint32 *group_attrs = NULL;
1606 UNIHDR *hdr_name = NULL;
1607 UNISTR2 *uni_name = NULL;
1609 int num_rids = q_u->num_rids1;
1613 r_u->status = NT_STATUS_OK;
1615 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1617 /* find the policy handle. open a policy on it. */
1618 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1619 return NT_STATUS_INVALID_HANDLE;
1621 if (num_rids > MAX_SAM_ENTRIES) {
1622 num_rids = MAX_SAM_ENTRIES;
1623 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1627 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1628 return NT_STATUS_NO_MEMORY;
1631 r_u->status = NT_STATUS_NONE_MAPPED;
1633 become_root(); /* lookup_sid can require root privs */
1635 for (i = 0; i < num_rids; i++) {
1639 enum SID_NAME_USE type;
1641 group_attrs[i] = SID_NAME_UNKNOWN;
1642 *group_names[i] = '\0';
1644 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1645 sid_copy(&sid, &pol_sid);
1646 sid_append_rid(&sid, q_u->rid[i]);
1648 if (lookup_sid(&sid, domname, tmpname, &type)) {
1649 r_u->status = NT_STATUS_OK;
1650 group_attrs[i] = (uint32)type;
1651 fstrcpy(group_names[i],tmpname);
1652 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1659 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1660 return NT_STATUS_NO_MEMORY;
1662 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1664 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1669 /*******************************************************************
1670 _samr_open_user. Safe - gives out no passwd info.
1671 ********************************************************************/
1673 NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1675 SAM_ACCOUNT *sampass=NULL;
1677 POLICY_HND domain_pol = q_u->domain_pol;
1678 POLICY_HND *user_pol = &r_u->user_pol;
1679 struct samr_info *info = NULL;
1680 SEC_DESC *psd = NULL;
1682 uint32 des_access = q_u->access_mask;
1687 r_u->status = NT_STATUS_OK;
1689 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1690 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1691 return NT_STATUS_INVALID_HANDLE;
1693 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1697 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1698 if (!NT_STATUS_IS_OK(nt_status)) {
1702 /* append the user's RID to it */
1703 if (!sid_append_rid(&sid, q_u->user_rid))
1704 return NT_STATUS_NO_SUCH_USER;
1706 /* check if access can be granted as requested by client. */
1707 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1708 se_map_generic(&des_access, &usr_generic_mapping);
1709 if (!NT_STATUS_IS_OK(nt_status =
1710 access_check_samr_object(psd, p->pipe_user.nt_user_token,
1711 des_access, &acc_granted, "_samr_open_user"))) {
1716 ret=pdb_getsampwsid(sampass, &sid);
1719 /* check that the SID exists in our domain. */
1721 return NT_STATUS_NO_SUCH_USER;
1724 pdb_free_sam(&sampass);
1726 /* associate the user's SID and access bits with the new handle. */
1727 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1728 return NT_STATUS_NO_MEMORY;
1729 info->acc_granted = acc_granted;
1731 /* get a (unique) handle. open a policy on it. */
1732 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1733 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1738 /*************************************************************************
1739 get_user_info_10. Safe. Only gives out acb bits.
1740 *************************************************************************/
1742 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1744 SAM_ACCOUNT *smbpass=NULL;
1748 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1750 if (!NT_STATUS_IS_OK(nt_status)) {
1755 ret = pdb_getsampwsid(smbpass, user_sid);
1759 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1760 return NT_STATUS_NO_SUCH_USER;
1763 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1766 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1768 pdb_free_sam(&smbpass);
1770 return NT_STATUS_OK;
1773 /*************************************************************************
1774 get_user_info_12. OK - this is the killer as it gives out password info.
1775 Ensure that this is only allowed on an encrypted connection with a root
1777 *************************************************************************/
1779 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1781 SAM_ACCOUNT *smbpass=NULL;
1785 if (!p->ntlmssp_auth_validated)
1786 return NT_STATUS_ACCESS_DENIED;
1788 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1789 return NT_STATUS_ACCESS_DENIED;
1792 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1795 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1797 if (!NT_STATUS_IS_OK(nt_status)) {
1801 ret = pdb_getsampwsid(smbpass, user_sid);
1804 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1805 pdb_free_sam(&smbpass);
1806 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1809 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1811 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1812 pdb_free_sam(&smbpass);
1813 return NT_STATUS_ACCOUNT_DISABLED;
1817 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1819 pdb_free_sam(&smbpass);
1821 return NT_STATUS_OK;
1824 /*************************************************************************
1826 *************************************************************************/
1828 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1830 SAM_ACCOUNT *sampass=NULL;
1833 pdb_init_sam_talloc(mem_ctx, &sampass);
1836 ret = pdb_getsampwsid(sampass, user_sid);
1840 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1841 return NT_STATUS_NO_SUCH_USER;
1844 samr_clear_sam_passwd(sampass);
1846 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1849 init_sam_user_info20A(id20, sampass);
1851 pdb_free_sam(&sampass);
1853 return NT_STATUS_OK;
1856 /*************************************************************************
1858 *************************************************************************/
1860 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1861 DOM_SID *user_sid, DOM_SID *domain_sid)
1863 SAM_ACCOUNT *sampass=NULL;
1867 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1868 if (!NT_STATUS_IS_OK(nt_status)) {
1873 ret = pdb_getsampwsid(sampass, user_sid);
1877 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1878 return NT_STATUS_NO_SUCH_USER;
1881 samr_clear_sam_passwd(sampass);
1883 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1886 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1888 pdb_free_sam(&sampass);
1890 return NT_STATUS_OK;
1893 /*******************************************************************
1894 _samr_query_userinfo
1895 ********************************************************************/
1897 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1899 SAM_USERINFO_CTR *ctr;
1900 struct samr_info *info = NULL;
1904 r_u->status=NT_STATUS_OK;
1906 /* search for the handle */
1907 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1908 return NT_STATUS_INVALID_HANDLE;
1910 domain_sid = info->sid;
1912 sid_split_rid(&domain_sid, &rid);
1914 if (!sid_check_is_in_our_domain(&info->sid))
1915 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1917 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1919 ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1921 return NT_STATUS_NO_MEMORY;
1925 /* ok! user info levels (lots: see MSDEV help), off we go... */
1926 ctr->switch_value = q_u->switch_value;
1928 switch (q_u->switch_value) {
1930 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1931 if (ctr->info.id10 == NULL)
1932 return NT_STATUS_NO_MEMORY;
1934 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1939 /* whoops - got this wrong. i think. or don't understand what's happening. */
1943 info = (void *)&id11;
1945 expire.low = 0xffffffff;
1946 expire.high = 0x7fffffff;
1948 ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1953 ZERO_STRUCTP(ctr->info.id11);
1954 init_sam_user_info11(ctr->info.id11, &expire,
1955 "BROOKFIELDS$", /* name */
1956 0x03ef, /* user rid */
1957 0x201, /* group rid */
1958 0x0080); /* acb info */
1965 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1966 if (ctr->info.id12 == NULL)
1967 return NT_STATUS_NO_MEMORY;
1969 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1974 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1975 if (ctr->info.id20 == NULL)
1976 return NT_STATUS_NO_MEMORY;
1977 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1982 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1983 if (ctr->info.id21 == NULL)
1984 return NT_STATUS_NO_MEMORY;
1985 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1986 &info->sid, &domain_sid)))
1991 return NT_STATUS_INVALID_INFO_CLASS;
1994 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1996 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
2001 /*******************************************************************
2002 samr_reply_query_usergroups
2003 ********************************************************************/
2005 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
2007 SAM_ACCOUNT *sam_pass=NULL;
2009 DOM_GID *gids = NULL;
2015 * from the SID in the request:
2016 * we should send back the list of DOMAIN GROUPS
2017 * the user is a member of
2019 * and only the DOMAIN GROUPS
2020 * no ALIASES !!! neither aliases of the domain
2021 * nor aliases of the builtin SID
2026 r_u->status = NT_STATUS_OK;
2028 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2030 /* find the policy handle. open a policy on it. */
2031 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
2032 return NT_STATUS_INVALID_HANDLE;
2034 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
2038 if (!sid_check_is_in_our_domain(&sid))
2039 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2041 pdb_init_sam(&sam_pass);
2044 ret = pdb_getsampwsid(sam_pass, &sid);
2048 pdb_free_sam(&sam_pass);
2049 return NT_STATUS_NO_SUCH_USER;
2052 if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
2053 pdb_free_sam(&sam_pass);
2054 return NT_STATUS_NO_SUCH_GROUP;
2057 /* construct the response. lkclXXXX: gids are not copied! */
2058 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
2060 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2062 pdb_free_sam(&sam_pass);
2067 /*******************************************************************
2068 _samr_query_dom_info
2069 ********************************************************************/
2071 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2073 struct samr_info *info = NULL;
2075 uint32 min_pass_len,pass_hist,flag;
2076 time_t u_expire, u_min_age;
2077 NTTIME nt_expire, nt_min_age;
2079 time_t u_lock_duration, u_reset_time;
2080 NTTIME nt_lock_duration, nt_reset_time;
2086 uint32 account_policy_temp;
2088 uint32 num_users=0, num_groups=0, num_aliases=0;
2090 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
2091 return NT_STATUS_NO_MEMORY;
2095 r_u->status = NT_STATUS_OK;
2097 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2099 /* find the policy handle. open a policy on it. */
2100 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2101 return NT_STATUS_INVALID_HANDLE;
2103 switch (q_u->switch_value) {
2106 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2107 min_pass_len = account_policy_temp;
2109 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2110 pass_hist = account_policy_temp;
2112 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2113 flag = account_policy_temp;
2115 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2116 u_expire = account_policy_temp;
2118 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2119 u_min_age = account_policy_temp;
2121 unix_to_nt_time_abs(&nt_expire, u_expire);
2122 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2124 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2125 flag, nt_expire, nt_min_age);
2129 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2131 if (!NT_STATUS_IS_OK(r_u->status)) {
2132 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2135 num_users=info->disp_info.num_user_account;
2138 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2139 if (!NT_STATUS_IS_OK(r_u->status)) {
2140 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2143 num_groups=info->disp_info.num_group_account;
2146 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2147 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
2148 num_users, num_groups, num_aliases);
2151 account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
2152 unix_to_nt_time_abs(&nt_logout, u_logout);
2154 init_unk_info3(&ctr->info.inf3, nt_logout);
2157 init_unk_info5(&ctr->info.inf5, global_myname());
2160 init_unk_info6(&ctr->info.inf6);
2163 init_unk_info7(&ctr->info.inf7);
2166 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2167 u_lock_duration = account_policy_temp;
2169 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2170 u_reset_time = account_policy_temp;
2172 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2173 lockout = account_policy_temp;
2175 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2176 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2178 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2181 return NT_STATUS_INVALID_INFO_CLASS;
2184 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2186 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2191 /*******************************************************************
2193 Create an account, can be either a normal user or a machine.
2194 This funcion will need to be updated for bdc/domain trusts.
2195 ********************************************************************/
2197 NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2199 SAM_ACCOUNT *sam_pass=NULL;
2203 POLICY_HND dom_pol = q_u->domain_pol;
2204 UNISTR2 user_account = q_u->uni_name;
2205 uint16 acb_info = q_u->acb_info;
2206 POLICY_HND *user_pol = &r_u->user_pol;
2207 struct samr_info *info = NULL;
2215 /* check this, when giving away 'add computer to domain' privs */
2216 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2218 /* Get the domain SID stored in the domain policy */
2219 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2220 return NT_STATUS_INVALID_HANDLE;
2222 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2226 /* find the account: tell the caller if it exists.
2227 lkclXXXX i have *no* idea if this is a problem or not
2228 or even if you are supposed to construct a different
2229 reply if the account already exists...
2232 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2233 strlower_m(account);
2235 pdb_init_sam(&sam_pass);
2238 ret = pdb_getsampwnam(sam_pass, account);
2241 /* this account exists: say so */
2242 pdb_free_sam(&sam_pass);
2243 return NT_STATUS_USER_EXISTS;
2246 pdb_free_sam(&sam_pass);
2249 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2250 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2251 * that only people with write access to the smbpasswd file will be able
2252 * to create a user. JRA.
2256 * add the user in the /etc/passwd file or the unix authority system.
2257 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2258 * a) local_password_change() checks for us if the /etc/passwd account really exists
2259 * b) smb_create_user() would return an error if the account already exists
2260 * and as it could return an error also if it can't create the account, it would be tricky.
2262 * So we go the easy way, only check after if the account exists.
2263 * JFM (2/3/2001), to clear any possible bad understanding (-:
2265 * We now have seperate script paramaters for adding users/machines so we
2266 * now have some sainity-checking to match.
2269 DEBUG(10,("checking account %s at pos %lu for $ termination\n",account, (unsigned long)strlen(account)-1));
2272 * we used to have code here that made sure the acb_info flags
2273 * matched with the users named (e.g. an account flags as a machine
2274 * trust account ended in '$'). It has been ifdef'd out for a long
2275 * time, so I replaced it with this comment. --jerry
2278 /* the passdb lookup has failed; check to see if we need to run the
2279 add user/machine script */
2281 pw = Get_Pwnam(account);
2283 /*********************************************************************
2284 * HEADS UP! If we have to create a new user account, we have to get
2285 * a new RID from somewhere. This used to be done by the passdb
2286 * backend. It has been moved into idmap now. Since idmap is now
2287 * wrapped up behind winbind, this means you have to run winbindd if you
2288 * want new accounts to get a new RID when "enable rid algorithm = no".
2289 * Tough. We now have a uniform way of allocating RIDs regardless
2290 * of what ever passdb backend people may use.
2291 * --jerry (2003-07-10)
2292 *********************************************************************/
2296 * we can't check both the ending $ and the acb_info.
2298 * UserManager creates trust accounts (ending in $,
2299 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2302 if (account[strlen(account)-1] == '$')
2303 pstrcpy(add_script, lp_addmachine_script());
2305 pstrcpy(add_script, lp_adduser_script());
2309 all_string_sub(add_script, "%u", account, sizeof(account));
2310 add_ret = smbrun(add_script,NULL);
2311 DEBUG(3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2313 else /* no add user script -- ask winbindd to do it */
2315 if ( !winbind_create_user( account, &new_rid ) ) {
2316 DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n",
2323 /* implicit call to getpwnam() next. we have a valid SID coming out of this call */
2325 if ( !NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pass, account, new_rid)) )
2328 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2330 if (!pdb_add_sam_account(sam_pass)) {
2331 pdb_free_sam(&sam_pass);
2332 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2334 return NT_STATUS_ACCESS_DENIED;
2337 /* Get the user's SID */
2338 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2340 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2341 se_map_generic(&des_access, &usr_generic_mapping);
2342 if (!NT_STATUS_IS_OK(nt_status =
2343 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2344 des_access, &acc_granted, "_samr_create_user"))) {
2348 /* associate the user's SID with the new handle. */
2349 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2350 pdb_free_sam(&sam_pass);
2351 return NT_STATUS_NO_MEMORY;
2356 info->acc_granted = acc_granted;
2358 /* get a (unique) handle. open a policy on it. */
2359 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2360 pdb_free_sam(&sam_pass);
2361 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2364 r_u->user_rid=pdb_get_user_rid(sam_pass);
2366 r_u->access_granted = acc_granted;
2368 pdb_free_sam(&sam_pass);
2370 return NT_STATUS_OK;
2373 /*******************************************************************
2374 samr_reply_connect_anon
2375 ********************************************************************/
2377 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2379 struct samr_info *info = NULL;
2380 uint32 des_access = q_u->access_mask;
2384 if (!pipe_access_check(p)) {
2385 DEBUG(3, ("access denied to samr_connect_anon\n"));
2386 r_u->status = NT_STATUS_ACCESS_DENIED;
2390 /* set up the SAMR connect_anon response */
2392 r_u->status = NT_STATUS_OK;
2394 /* associate the user's SID with the new handle. */
2395 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2396 return NT_STATUS_NO_MEMORY;
2398 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
2399 was observed from a win98 client trying to enumerate users (when configured
2400 user level access control on shares) --jerry */
2402 se_map_generic( &des_access, &sam_generic_mapping );
2403 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2405 info->status = q_u->unknown_0;
2407 /* get a (unique) handle. open a policy on it. */
2408 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2409 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2414 /*******************************************************************
2416 ********************************************************************/
2418 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2420 struct samr_info *info = NULL;
2421 SEC_DESC *psd = NULL;
2423 uint32 des_access = q_u->access_mask;
2428 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2432 if (!pipe_access_check(p)) {
2433 DEBUG(3, ("access denied to samr_connect\n"));
2434 r_u->status = NT_STATUS_ACCESS_DENIED;
2438 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2439 se_map_generic(&des_access, &sam_generic_mapping);
2440 if (!NT_STATUS_IS_OK(nt_status =
2441 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2442 des_access, &acc_granted, "_samr_connect"))) {
2446 r_u->status = NT_STATUS_OK;
2448 /* associate the user's SID and access granted with the new handle. */
2449 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2450 return NT_STATUS_NO_MEMORY;
2452 info->acc_granted = acc_granted;
2453 info->status = q_u->access_mask;
2455 /* get a (unique) handle. open a policy on it. */
2456 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2457 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2459 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2464 /*******************************************************************
2466 ********************************************************************/
2468 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2470 struct samr_info *info = NULL;
2471 SEC_DESC *psd = NULL;
2473 uint32 des_access = q_u->access_mask;
2478 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2482 if (!pipe_access_check(p)) {
2483 DEBUG(3, ("access denied to samr_connect4\n"));
2484 r_u->status = NT_STATUS_ACCESS_DENIED;
2488 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2489 se_map_generic(&des_access, &sam_generic_mapping);
2490 if (!NT_STATUS_IS_OK(nt_status =
2491 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2492 des_access, &acc_granted, "_samr_connect"))) {
2496 r_u->status = NT_STATUS_OK;
2498 /* associate the user's SID and access granted with the new handle. */
2499 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2500 return NT_STATUS_NO_MEMORY;
2502 info->acc_granted = acc_granted;
2503 info->status = q_u->access_mask;
2505 /* get a (unique) handle. open a policy on it. */
2506 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2507 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2509 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2514 /**********************************************************************
2515 api_samr_lookup_domain
2516 **********************************************************************/
2518 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2520 struct samr_info *info;
2521 fstring domain_name;
2524 r_u->status = NT_STATUS_OK;
2526 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2527 return NT_STATUS_INVALID_HANDLE;
2529 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
2530 SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_lookup_domain")))
2535 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2539 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2540 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2543 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2545 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2550 /******************************************************************
2551 makes a SAMR_R_ENUM_DOMAINS structure.
2552 ********************************************************************/
2554 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2555 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2561 DEBUG(5, ("make_enum_domains\n"));
2564 *pp_uni_name = NULL;
2566 if (num_sam_entries == 0)
2569 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2570 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2572 if (sam == NULL || uni_name == NULL)
2575 for (i = 0; i < num_sam_entries; i++) {
2576 init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
2577 init_sam_entry(&sam[i], &uni_name[i], 0);
2581 *pp_uni_name = uni_name;
2586 /**********************************************************************
2587 api_samr_enum_domains
2588 **********************************************************************/
2590 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2592 struct samr_info *info;
2593 uint32 num_entries = 2;
2597 r_u->status = NT_STATUS_OK;
2599 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2600 return NT_STATUS_INVALID_HANDLE;
2602 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2606 name = get_global_sam_name();
2608 fstrcpy(dom[0],name);
2610 fstrcpy(dom[1],"Builtin");
2612 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2613 return NT_STATUS_NO_MEMORY;
2615 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2620 /*******************************************************************
2622 ********************************************************************/
2624 NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2627 POLICY_HND domain_pol = q_u->dom_pol;
2628 uint32 alias_rid = q_u->rid_alias;
2629 POLICY_HND *alias_pol = &r_u->pol;
2630 struct samr_info *info = NULL;
2631 SEC_DESC *psd = NULL;
2633 uint32 des_access = q_u->access_mask;
2637 r_u->status = NT_STATUS_OK;
2639 /* find the domain policy and get the SID / access bits stored in the domain policy */
2640 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2641 return NT_STATUS_INVALID_HANDLE;
2643 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2647 /* append the alias' RID to it */
2648 if (!sid_append_rid(&sid, alias_rid))
2649 return NT_STATUS_NO_SUCH_USER;
2651 /*check if access can be granted as requested by client. */
2652 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2653 se_map_generic(&des_access,&ali_generic_mapping);
2654 if (!NT_STATUS_IS_OK(status =
2655 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2656 des_access, &acc_granted, "_samr_open_alias"))) {
2661 * we should check if the rid really exist !!!
2665 /* associate the user's SID with the new handle. */
2666 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2667 return NT_STATUS_NO_MEMORY;
2669 info->acc_granted = acc_granted;
2671 /* get a (unique) handle. open a policy on it. */
2672 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2673 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2678 /*******************************************************************
2680 ********************************************************************/
2682 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2684 SAM_ACCOUNT *pwd =NULL;
2689 ret = pdb_getsampwsid(pwd, sid);
2697 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2702 /* FIX ME: check if the value is really changed --metze */
2703 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2708 if(!pdb_update_sam_account(pwd)) {
2718 /*******************************************************************
2720 ********************************************************************/
2722 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2724 SAM_ACCOUNT *pwd = NULL;
2728 if(!pdb_getsampwsid(pwd, sid)) {
2734 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2739 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2743 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2747 if (!pdb_set_pass_changed_now (pwd)) {
2752 if(!pdb_update_sam_account(pwd)) {
2761 /*******************************************************************
2762 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2763 ********************************************************************/
2764 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2769 if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2771 DEBUG(2,("Could not get gid for primary group of "
2772 "user %s\n", pdb_get_username(sampass)));
2776 grp = getgrgid(gid);
2779 DEBUG(2,("Could not find primary group %lu for "
2780 "user %s\n", (unsigned long)gid,
2781 pdb_get_username(sampass)));
2785 if (smb_set_primary_group(grp->gr_name,
2786 pdb_get_username(sampass)) != 0) {
2787 DEBUG(2,("Could not set primary group for user %s to "
2789 pdb_get_username(sampass), grp->gr_name));
2797 /*******************************************************************
2799 ********************************************************************/
2801 static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, DOM_SID *sid)
2803 SAM_ACCOUNT *pwd = NULL;
2806 DEBUG(5, ("set_user_info_20: NULL id20\n"));
2812 if (!pdb_getsampwsid(pwd, sid)) {
2817 copy_id20_to_sam_passwd(pwd, id20);
2819 /* write the change out */
2820 if(!pdb_update_sam_account(pwd)) {
2829 /*******************************************************************
2831 ********************************************************************/
2833 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2835 SAM_ACCOUNT *pwd = NULL;
2838 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2844 if (!pdb_getsampwsid(pwd, sid)) {
2849 copy_id21_to_sam_passwd(pwd, id21);
2852 * The funny part about the previous two calls is
2853 * that pwd still has the password hashes from the
2854 * passdb entry. These have not been updated from
2855 * id21. I don't know if they need to be set. --jerry
2858 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2859 set_unix_primary_group(pwd);
2861 /* write the change out */
2862 if(!pdb_update_sam_account(pwd)) {
2872 /*******************************************************************
2874 ********************************************************************/
2876 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2878 SAM_ACCOUNT *pwd = NULL;
2879 pstring plaintext_buf;
2884 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2890 if (!pdb_getsampwsid(pwd, sid)) {
2895 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2896 pdb_get_username(pwd)));
2898 acct_ctrl = pdb_get_acct_ctrl(pwd);
2900 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
2905 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2910 copy_id23_to_sam_passwd(pwd, id23);
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)) {
2926 ZERO_STRUCT(plaintext_buf);
2928 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2929 set_unix_primary_group(pwd);
2931 if(!pdb_update_sam_account(pwd)) {
2941 /*******************************************************************
2943 ********************************************************************/
2945 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2947 SAM_ACCOUNT *pwd = NULL;
2949 pstring plaintext_buf;
2954 if (!pdb_getsampwsid(pwd, sid)) {
2959 DEBUG(5, ("Attempting administrator password change for user %s\n",
2960 pdb_get_username(pwd)));
2962 acct_ctrl = pdb_get_acct_ctrl(pwd);
2964 ZERO_STRUCT(plaintext_buf);
2966 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) {
2971 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2976 /* if it's a trust account, don't update /etc/passwd */
2977 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2978 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2979 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2980 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2982 /* update the UNIX password */
2983 if (lp_unix_password_sync()) {
2984 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2991 ZERO_STRUCT(plaintext_buf);
2993 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2995 /* update the SAMBA password */
2996 if(!pdb_update_sam_account(pwd)) {
3006 /*******************************************************************
3007 samr_reply_set_userinfo
3008 ********************************************************************/
3010 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
3013 POLICY_HND *pol = &q_u->pol;
3014 uint16 switch_value = q_u->switch_value;
3015 SAM_USERINFO_CTR *ctr = q_u->ctr;
3017 uint32 acc_required;
3019 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
3021 r_u->status = NT_STATUS_OK;
3023 /* find the policy handle. open a policy on it. */
3024 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3025 return NT_STATUS_INVALID_HANDLE;
3027 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3028 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
3032 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
3035 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
3036 return NT_STATUS_INVALID_INFO_CLASS;
3039 /* ok! user info levels (lots: see MSDEV help), off we go... */
3040 switch (switch_value) {
3042 if (!set_user_info_12(ctr->info.id12, &sid))
3043 return NT_STATUS_ACCESS_DENIED;
3047 SamOEMhash(ctr->info.id24->pass, p->session_key, 516);
3049 dump_data(100, (char *)ctr->info.id24->pass, 516);
3051 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
3052 return NT_STATUS_ACCESS_DENIED;
3058 * Currently we don't really know how to unmarshall
3059 * the level 25 struct, and the password encryption
3060 * is different. This is a placeholder for when we
3061 * do understand it. In the meantime just return INVALID
3062 * info level and W2K SP2 drops down to level 23... JRA.
3065 SamOEMhash(ctr->info.id25->pass, p->session_key, 532);
3067 dump_data(100, (char *)ctr->info.id25->pass, 532);
3069 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3070 return NT_STATUS_ACCESS_DENIED;
3073 return NT_STATUS_INVALID_INFO_CLASS;
3076 SamOEMhash(ctr->info.id23->pass, p->session_key, 516);
3078 dump_data(100, (char *)ctr->info.id23->pass, 516);
3080 if (!set_user_info_23(ctr->info.id23, &sid))
3081 return NT_STATUS_ACCESS_DENIED;
3085 return NT_STATUS_INVALID_INFO_CLASS;
3091 /*******************************************************************
3092 samr_reply_set_userinfo2
3093 ********************************************************************/
3095 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3098 SAM_USERINFO_CTR *ctr = q_u->ctr;
3099 POLICY_HND *pol = &q_u->pol;
3100 uint16 switch_value = q_u->switch_value;
3102 uint32 acc_required;
3104 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3106 r_u->status = NT_STATUS_OK;
3108 /* find the policy handle. open a policy on it. */
3109 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3110 return NT_STATUS_INVALID_HANDLE;
3112 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3113 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3117 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3120 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3121 return NT_STATUS_INVALID_INFO_CLASS;
3124 switch_value=ctr->switch_value;
3126 /* ok! user info levels (lots: see MSDEV help), off we go... */
3127 switch (switch_value) {
3129 if (!set_user_info_21(ctr->info.id21, &sid))
3130 return NT_STATUS_ACCESS_DENIED;
3133 if (!set_user_info_20(ctr->info.id20, &sid))
3134 return NT_STATUS_ACCESS_DENIED;
3137 if (!set_user_info_10(ctr->info.id10, &sid))
3138 return NT_STATUS_ACCESS_DENIED;
3141 /* Used by AS/U JRA. */
3142 if (!set_user_info_12(ctr->info.id12, &sid))
3143 return NT_STATUS_ACCESS_DENIED;
3146 return NT_STATUS_INVALID_INFO_CLASS;
3152 /*********************************************************************
3153 _samr_query_aliasmem
3154 *********************************************************************/
3156 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3158 int num_groups = 0, tmp_num_groups=0;
3159 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3160 struct samr_info *info = NULL;
3166 /* until i see a real useraliases query, we fack one up */
3168 /* I have seen one, JFM 2/12/2001 */
3170 * Explanation of what this call does:
3171 * for all the SID given in the request:
3172 * return a list of alias (local groups)
3173 * that have those SID as members.
3175 * and that's the alias in the domain specified
3176 * in the policy_handle
3178 * if the policy handle is on an incorrect sid
3179 * for example a user's sid
3180 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3183 r_u->status = NT_STATUS_OK;
3185 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3187 /* find the policy handle. open a policy on it. */
3188 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3189 return NT_STATUS_INVALID_HANDLE;
3191 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3192 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3194 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3195 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3196 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3197 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3201 if (!sid_check_is_domain(&info->sid) &&
3202 !sid_check_is_builtin(&info->sid))
3203 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3206 for (i=0; i<q_u->num_sids1; i++) {
3208 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3211 * if there is an error, we just continue as
3212 * it can be an unfound user or group
3214 if (!NT_STATUS_IS_OK(r_u->status)) {
3215 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3219 if (tmp_num_groups==0) {
3220 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3224 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3225 if (new_rids==NULL) {
3226 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3227 return NT_STATUS_NO_MEMORY;
3231 for (j=0; j<tmp_num_groups; j++)
3232 rids[j+num_groups]=tmp_rids[j];
3234 safe_free(tmp_rids);
3236 num_groups+=tmp_num_groups;
3239 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3240 return NT_STATUS_OK;
3243 /*********************************************************************
3244 _samr_query_aliasmem
3245 *********************************************************************/
3247 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3259 fstring alias_sid_str;
3262 SAM_ACCOUNT *sam_user = NULL;
3266 /* find the policy handle. open a policy on it. */
3267 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3268 return NT_STATUS_INVALID_HANDLE;
3270 if (!NT_STATUS_IS_OK(r_u->status =
3271 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3275 sid_copy(&als_sid, &alias_sid);
3276 sid_to_string(alias_sid_str, &alias_sid);
3277 sid_split_rid(&alias_sid, &alias_rid);
3279 DEBUG(10, ("sid is %s\n", alias_sid_str));
3281 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
3282 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3283 if(!get_builtin_group_from_sid(als_sid, &map))
3284 return NT_STATUS_NO_SUCH_ALIAS;
3286 if (sid_equal(&alias_sid, get_global_sam_sid())) {
3287 DEBUG(10, ("lookup on Server SID\n"));
3288 if(!get_local_group_from_sid(als_sid, &map))
3289 return NT_STATUS_NO_SUCH_ALIAS;
3293 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3294 return NT_STATUS_NO_SUCH_ALIAS;
3296 DEBUG(10, ("sid is %s\n", alias_sid_str));
3297 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
3298 if (num_uids!=0 && sid == NULL)
3299 return NT_STATUS_NO_MEMORY;
3301 for (i = 0; i < num_uids; i++) {
3302 struct passwd *pass;
3305 sid_copy(&temp_sid, get_global_sam_sid());
3307 pass = getpwuid_alloc(uid[i]);
3308 if (!pass) continue;
3310 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3316 check = pdb_getsampwnam(sam_user, pass->pw_name);
3319 if (check != True) {
3320 pdb_free_sam(&sam_user);
3325 rid = pdb_get_user_rid(sam_user);
3327 pdb_free_sam(&sam_user);
3332 pdb_free_sam(&sam_user);
3335 sid_append_rid(&temp_sid, rid);
3337 init_dom_sid2(&sid[i], &temp_sid);
3340 DEBUG(10, ("sid is %s\n", alias_sid_str));
3341 init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
3343 return NT_STATUS_OK;
3346 /*********************************************************************
3347 _samr_query_groupmem
3348 *********************************************************************/
3350 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3356 fstring group_sid_str;
3364 SAM_ACCOUNT *sam_user = NULL;
3368 /* find the policy handle. open a policy on it. */
3369 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3370 return NT_STATUS_INVALID_HANDLE;
3372 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3376 /* todo: change to use sid_compare_front */
3378 sid_split_rid(&group_sid, &group_rid);
3379 sid_to_string(group_sid_str, &group_sid);
3380 DEBUG(10, ("sid is %s\n", group_sid_str));
3382 /* can we get a query for an SID outside our domain ? */
3383 if (!sid_equal(&group_sid, get_global_sam_sid()))
3384 return NT_STATUS_NO_SUCH_GROUP;
3386 sid_append_rid(&group_sid, group_rid);
3387 DEBUG(10, ("lookup on Domain SID\n"));
3389 if(!get_domain_group_from_sid(group_sid, &map))
3390 return NT_STATUS_NO_SUCH_GROUP;
3392 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3393 return NT_STATUS_NO_SUCH_GROUP;
3395 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3396 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3398 if (num_uids!=0 && (rid==NULL || attr==NULL))
3399 return NT_STATUS_NO_MEMORY;
3401 for (i=0; i<num_uids; i++) {
3402 struct passwd *pass;
3405 pass = getpwuid_alloc(uid[i]);
3406 if (!pass) continue;
3408 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3414 check = pdb_getsampwnam(sam_user, pass->pw_name);
3417 if (check != True) {
3418 pdb_free_sam(&sam_user);
3423 urid = pdb_get_user_rid(sam_user);
3425 pdb_free_sam(&sam_user);
3430 pdb_free_sam(&sam_user);
3434 attr[i] = SID_NAME_USER;
3437 init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
3439 return NT_STATUS_OK;
3442 /*********************************************************************
3444 *********************************************************************/
3446 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3449 fstring alias_sid_str;
3456 SAM_ACCOUNT *sam_user = NULL;
3460 /* Find the policy handle. Open a policy on it. */
3461 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3462 return NT_STATUS_INVALID_HANDLE;
3464 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3468 sid_to_string(alias_sid_str, &alias_sid);
3469 DEBUG(10, ("sid is %s\n", alias_sid_str));
3471 if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
3472 DEBUG(10, ("adding member on Server SID\n"));
3473 if(!get_local_group_from_sid(alias_sid, &map))
3474 return NT_STATUS_NO_SUCH_ALIAS;
3477 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
3478 DEBUG(10, ("adding member on BUILTIN SID\n"));
3479 if( !get_local_group_from_sid(alias_sid, &map))
3480 return NT_STATUS_NO_SUCH_ALIAS;
3483 return NT_STATUS_NO_SUCH_ALIAS;
3486 ret = pdb_init_sam(&sam_user);
3487 if (!NT_STATUS_IS_OK(ret))
3490 check = pdb_getsampwsid(sam_user, &q_u->sid.sid);
3492 if (check != True) {
3493 pdb_free_sam(&sam_user);
3494 return NT_STATUS_NO_SUCH_USER;
3497 /* check a real user exist before we run the script to add a user to a group */
3498 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3499 pdb_free_sam(&sam_user);
3500 return NT_STATUS_NO_SUCH_USER;
3503 pdb_free_sam(&sam_user);
3505 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3506 return NT_STATUS_NO_SUCH_USER;
3509 if ((grp=getgrgid(map.gid)) == NULL) {
3511 return NT_STATUS_NO_SUCH_ALIAS;
3514 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3515 fstrcpy(grp_name, grp->gr_name);
3517 /* if the user is already in the group */
3518 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3520 return NT_STATUS_MEMBER_IN_ALIAS;
3524 * ok, the group exist, the user exist, the user is not in the group,
3525 * we can (finally) add it to the group !
3527 smb_add_user_group(grp_name, pwd->pw_name);
3529 /* check if the user has been added then ... */
3530 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3532 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3536 return NT_STATUS_OK;
3539 /*********************************************************************
3541 *********************************************************************/
3543 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3546 fstring alias_sid_str;
3550 SAM_ACCOUNT *sam_pass=NULL;
3553 /* Find the policy handle. Open a policy on it. */
3554 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3555 return NT_STATUS_INVALID_HANDLE;
3557 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3561 sid_to_string(alias_sid_str, &alias_sid);
3562 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
3564 if (!sid_check_is_in_our_domain(&alias_sid) &&
3565 !sid_check_is_in_builtin(&alias_sid)) {
3566 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3567 return NT_STATUS_NO_SUCH_ALIAS;
3570 if( !get_local_group_from_sid(alias_sid, &map))
3571 return NT_STATUS_NO_SUCH_ALIAS;
3573 if ((grp=getgrgid(map.gid)) == NULL)
3574 return NT_STATUS_NO_SUCH_ALIAS;
3576 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3577 fstrcpy(grp_name, grp->gr_name);
3579 /* check if the user exists before trying to remove it from the group */
3580 pdb_init_sam(&sam_pass);
3581 if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
3582 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3583 pdb_free_sam(&sam_pass);
3584 return NT_STATUS_NO_SUCH_USER;
3587 /* if the user is not in the group */
3588 if(!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3589 pdb_free_sam(&sam_pass);
3590 return NT_STATUS_MEMBER_IN_ALIAS;
3593 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3595 /* check if the user has been removed then ... */
3596 if(user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3597 pdb_free_sam(&sam_pass);
3598 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3601 pdb_free_sam(&sam_pass);
3602 return NT_STATUS_OK;
3605 /*********************************************************************
3607 *********************************************************************/
3609 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3613 fstring group_sid_str;
3620 SAM_ACCOUNT *sam_user=NULL;
3624 /* Find the policy handle. Open a policy on it. */
3625 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3626 return NT_STATUS_INVALID_HANDLE;
3628 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3632 sid_to_string(group_sid_str, &group_sid);
3633 DEBUG(10, ("sid is %s\n", group_sid_str));
3635 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3636 return NT_STATUS_NO_SUCH_GROUP;
3638 DEBUG(10, ("lookup on Domain SID\n"));
3640 if(!get_domain_group_from_sid(group_sid, &map))
3641 return NT_STATUS_NO_SUCH_GROUP;
3643 sid_copy(&user_sid, get_global_sam_sid());
3644 sid_append_rid(&user_sid, q_u->rid);
3646 ret = pdb_init_sam(&sam_user);
3647 if (!NT_STATUS_IS_OK(ret))
3650 check = pdb_getsampwsid(sam_user, &user_sid);
3652 if (check != True) {
3653 pdb_free_sam(&sam_user);
3654 return NT_STATUS_NO_SUCH_USER;
3657 /* check a real user exist before we run the script to add a user to a group */
3658 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3659 pdb_free_sam(&sam_user);
3660 return NT_STATUS_NO_SUCH_USER;
3663 pdb_free_sam(&sam_user);
3665 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3666 return NT_STATUS_NO_SUCH_USER;
3669 if ((grp=getgrgid(map.gid)) == NULL) {
3671 return NT_STATUS_NO_SUCH_GROUP;
3674 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3675 fstrcpy(grp_name, grp->gr_name);
3677 /* if the user is already in the group */
3678 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3680 return NT_STATUS_MEMBER_IN_GROUP;
3684 * ok, the group exist, the user exist, the user is not in the group,
3686 * we can (finally) add it to the group !
3689 smb_add_user_group(grp_name, pwd->pw_name);
3691 /* check if the user has been added then ... */
3692 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3694 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3698 return NT_STATUS_OK;
3701 /*********************************************************************
3703 *********************************************************************/
3705 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3709 SAM_ACCOUNT *sam_pass=NULL;
3716 * delete the group member named q_u->rid
3717 * who is a member of the sid associated with the handle
3718 * the rid is a user's rid as the group is a domain group.
3721 /* Find the policy handle. Open a policy on it. */
3722 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3723 return NT_STATUS_INVALID_HANDLE;
3725 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3729 if (!sid_check_is_in_our_domain(&group_sid))
3730 return NT_STATUS_NO_SUCH_GROUP;
3732 sid_copy(&user_sid, get_global_sam_sid());
3733 sid_append_rid(&user_sid, q_u->rid);
3735 if (!get_domain_group_from_sid(group_sid, &map))
3736 return NT_STATUS_NO_SUCH_GROUP;
3738 if ((grp=getgrgid(map.gid)) == NULL)
3739 return NT_STATUS_NO_SUCH_GROUP;
3741 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3742 fstrcpy(grp_name, grp->gr_name);
3744 /* check if the user exists before trying to remove it from the group */
3745 pdb_init_sam(&sam_pass);
3746 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3747 DEBUG(5,("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 /* if the user is not in the group */
3753 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3754 pdb_free_sam(&sam_pass);
3755 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3758 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3760 /* check if the user has been removed then ... */
3761 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3762 pdb_free_sam(&sam_pass);
3763 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3766 pdb_free_sam(&sam_pass);
3767 return NT_STATUS_OK;
3771 /****************************************************************************
3772 Delete a UNIX user on demand.
3773 ****************************************************************************/
3775 static int smb_delete_user(const char *unix_user)
3780 /* try winbindd first since it is impossible to determine where
3781 a user came from via NSS. Try the delete user script if this fails
3782 meaning the user did not exist in winbindd's list of accounts */
3784 if ( winbind_delete_user( unix_user ) ) {
3785 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3790 /* fall back to 'delete user script' */
3792 pstrcpy(del_script, lp_deluser_script());
3795 all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3796 ret = smbrun(del_script,NULL);
3797 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3802 /*********************************************************************
3803 _samr_delete_dom_user
3804 *********************************************************************/
3806 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3809 SAM_ACCOUNT *sam_pass=NULL;
3812 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3814 /* Find the policy handle. Open a policy on it. */
3815 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3816 return NT_STATUS_INVALID_HANDLE;
3818 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3822 if (!sid_check_is_in_our_domain(&user_sid))
3823 return NT_STATUS_CANNOT_DELETE;
3825 /* check if the user exists before trying to delete */
3826 pdb_init_sam(&sam_pass);
3827 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3828 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
3829 sid_string_static(&user_sid)));
3830 pdb_free_sam(&sam_pass);
3831 return NT_STATUS_NO_SUCH_USER;
3834 /* delete the unix side */
3836 * note: we don't check if the delete really happened
3837 * as the script is not necessary present
3838 * and maybe the sysadmin doesn't want to delete the unix side
3840 smb_delete_user(pdb_get_username(sam_pass));
3842 /* and delete the samba side */
3843 if (!pdb_delete_sam_account(sam_pass)) {
3844 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3845 pdb_free_sam(&sam_pass);
3846 return NT_STATUS_CANNOT_DELETE;
3849 pdb_free_sam(&sam_pass);
3851 if (!close_policy_hnd(p, &q_u->user_pol))
3852 return NT_STATUS_OBJECT_NAME_INVALID;
3854 return NT_STATUS_OK;
3857 /*********************************************************************
3858 _samr_delete_dom_group
3859 *********************************************************************/
3861 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3866 fstring group_sid_str;
3872 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3874 /* Find the policy handle. Open a policy on it. */
3875 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3876 return NT_STATUS_INVALID_HANDLE;
3878 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3882 sid_copy(&dom_sid, &group_sid);
3883 sid_to_string(group_sid_str, &dom_sid);
3884 sid_split_rid(&dom_sid, &group_rid);
3886 DEBUG(10, ("sid is %s\n", group_sid_str));
3888 /* we check if it's our SID before deleting */
3889 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3890 return NT_STATUS_NO_SUCH_GROUP;
3892 DEBUG(10, ("lookup on Domain SID\n"));
3894 if(!get_domain_group_from_sid(group_sid, &map))
3895 return NT_STATUS_NO_SUCH_GROUP;
3899 /* check if group really exists */
3900 if ( (grp=getgrgid(gid)) == NULL)
3901 return NT_STATUS_NO_SUCH_GROUP;
3903 /* we can delete the UNIX group */
3904 smb_delete_group(grp->gr_name);
3906 /* check if the group has been successfully deleted */
3907 if ( (grp=getgrgid(gid)) != NULL)
3908 return NT_STATUS_ACCESS_DENIED;
3910 if(!pdb_delete_group_mapping_entry(group_sid))
3911 return NT_STATUS_ACCESS_DENIED;
3913 if (!close_policy_hnd(p, &q_u->group_pol))
3914 return NT_STATUS_OBJECT_NAME_INVALID;
3916 return NT_STATUS_OK;
3919 /*********************************************************************
3920 _samr_delete_dom_alias
3921 *********************************************************************/
3923 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3928 fstring alias_sid_str;
3934 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3936 /* Find the policy handle. Open a policy on it. */
3937 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3938 return NT_STATUS_INVALID_HANDLE;
3940 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3944 sid_copy(&dom_sid, &alias_sid);
3945 sid_to_string(alias_sid_str, &dom_sid);
3946 sid_split_rid(&dom_sid, &alias_rid);
3948 DEBUG(10, ("sid is %s\n", alias_sid_str));
3950 /* we check if it's our SID before deleting */
3951 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3952 return NT_STATUS_NO_SUCH_ALIAS;
3954 DEBUG(10, ("lookup on Local SID\n"));
3956 if(!get_local_group_from_sid(alias_sid, &map))
3957 return NT_STATUS_NO_SUCH_ALIAS;
3961 /* check if group really exists */
3962 if ( (grp=getgrgid(gid)) == NULL)
3963 return NT_STATUS_NO_SUCH_ALIAS;
3965 /* we can delete the UNIX group */
3966 smb_delete_group(grp->gr_name);
3968 /* check if the group has been successfully deleted */
3969 if ( (grp=getgrgid(gid)) != NULL)
3970 return NT_STATUS_ACCESS_DENIED;
3972 /* don't check if we removed it as it could be an un-mapped group */
3973 pdb_delete_group_mapping_entry(alias_sid);
3975 if (!close_policy_hnd(p, &q_u->alias_pol))
3976 return NT_STATUS_OBJECT_NAME_INVALID;
3978 return NT_STATUS_OK;
3981 /*********************************************************************
3982 _samr_create_dom_group
3983 *********************************************************************/
3985 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3992 struct samr_info *info;
3996 /* Find the policy handle. Open a policy on it. */
3997 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3998 return NT_STATUS_INVALID_HANDLE;
4000 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
4004 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4005 return NT_STATUS_ACCESS_DENIED;
4007 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
4009 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4011 /* check if group already exist */
4012 if ((grp=getgrnam(name)) != NULL)
4013 return NT_STATUS_GROUP_EXISTS;
4015 /* we can create the UNIX group */
4016 if (smb_create_group(name, &gid) != 0)
4017 return NT_STATUS_ACCESS_DENIED;
4019 /* check if the group has been successfully created */
4020 if ((grp=getgrgid(gid)) == NULL)
4021 return NT_STATUS_ACCESS_DENIED;
4023 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
4025 /* add the group to the mapping table */
4026 sid_copy(&info_sid, get_global_sam_sid());
4027 sid_append_rid(&info_sid, r_u->rid);
4028 sid_to_string(sid_string, &info_sid);
4030 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
4031 return NT_STATUS_ACCESS_DENIED;
4033 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4034 return NT_STATUS_NO_MEMORY;
4036 /* get a (unique) handle. open a policy on it. */
4037 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4038 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4040 return NT_STATUS_OK;
4043 /*********************************************************************
4044 _samr_create_dom_alias
4045 *********************************************************************/
4047 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
4054 struct samr_info *info;
4058 /* Find the policy handle. Open a policy on it. */
4059 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
4060 return NT_STATUS_INVALID_HANDLE;
4062 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
4066 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4067 return NT_STATUS_ACCESS_DENIED;
4069 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
4071 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4073 /* check if group already exists */
4074 if ( (grp=getgrnam(name)) != NULL)
4075 return NT_STATUS_GROUP_EXISTS;
4077 /* we can create the UNIX group */
4078 if (smb_create_group(name, &gid) != 0)
4079 return NT_STATUS_ACCESS_DENIED;
4081 /* check if the group has been successfully created */
4082 if ((grp=getgrgid(gid)) == NULL)
4083 return NT_STATUS_ACCESS_DENIED;
4085 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
4087 sid_copy(&info_sid, get_global_sam_sid());
4088 sid_append_rid(&info_sid, r_u->rid);
4089 sid_to_string(sid_string, &info_sid);
4091 /* add the group to the mapping table */
4092 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL))
4093 return NT_STATUS_ACCESS_DENIED;
4095 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4096 return NT_STATUS_NO_MEMORY;
4098 /* get a (unique) handle. open a policy on it. */
4099 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4100 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4102 return NT_STATUS_OK;
4105 /*********************************************************************
4106 _samr_query_groupinfo
4108 sends the name/comment pair of a domain group
4109 level 1 send also the number of users of that group
4110 *********************************************************************/
4112 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4118 GROUP_INFO_CTR *ctr;
4122 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4123 return NT_STATUS_INVALID_HANDLE;
4125 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4130 ret = get_domain_group_from_sid(group_sid, &map);
4133 return NT_STATUS_INVALID_HANDLE;
4135 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
4137 return NT_STATUS_NO_MEMORY;
4139 switch (q_u->switch_level) {
4141 ctr->switch_value1 = 1;
4142 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
4143 return NT_STATUS_NO_SUCH_GROUP;
4144 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
4148 ctr->switch_value1 = 3;
4149 init_samr_group_info3(&ctr->group.info3);
4152 ctr->switch_value1 = 4;
4153 init_samr_group_info4(&ctr->group.info4, map.comment);
4156 return NT_STATUS_INVALID_INFO_CLASS;
4159 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4161 return NT_STATUS_OK;
4164 /*********************************************************************
4167 update a domain group's comment.
4168 *********************************************************************/
4170 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4174 GROUP_INFO_CTR *ctr;
4177 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4178 return NT_STATUS_INVALID_HANDLE;
4180 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4184 if (!get_domain_group_from_sid(group_sid, &map))
4185 return NT_STATUS_NO_SUCH_GROUP;
4189 switch (ctr->switch_value1) {
4191 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4194 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4197 return NT_STATUS_INVALID_INFO_CLASS;
4200 if(!pdb_update_group_mapping_entry(&map)) {
4201 return NT_STATUS_NO_SUCH_GROUP;
4204 return NT_STATUS_OK;
4207 /*********************************************************************
4210 update an alias's comment.
4211 *********************************************************************/
4213 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4217 ALIAS_INFO_CTR *ctr;
4220 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4221 return NT_STATUS_INVALID_HANDLE;
4223 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4227 if (!get_local_group_from_sid(group_sid, &map))
4228 return NT_STATUS_NO_SUCH_GROUP;
4232 switch (ctr->switch_value1) {
4234 unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
4237 return NT_STATUS_INVALID_INFO_CLASS;
4240 if(!pdb_update_group_mapping_entry(&map)) {
4241 return NT_STATUS_NO_SUCH_GROUP;
4244 return NT_STATUS_OK;
4247 /*********************************************************************
4248 _samr_get_dom_pwinfo
4249 *********************************************************************/
4251 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4253 /* Perform access check. Since this rpc does not require a
4254 policy handle it will not be caught by the access checks on
4255 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4257 if (!pipe_access_check(p)) {
4258 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4259 r_u->status = NT_STATUS_ACCESS_DENIED;
4263 /* Actually, returning zeros here works quite well :-). */
4265 return NT_STATUS_OK;
4268 /*********************************************************************
4270 *********************************************************************/
4272 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4277 struct samr_info *info;
4278 SEC_DESC *psd = NULL;
4280 uint32 des_access = q_u->access_mask;
4286 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4287 return NT_STATUS_INVALID_HANDLE;
4289 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4293 /*check if access can be granted as requested by client. */
4294 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4295 se_map_generic(&des_access,&grp_generic_mapping);
4296 if (!NT_STATUS_IS_OK(status =
4297 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4298 des_access, &acc_granted, "_samr_open_group"))) {
4303 /* this should not be hard-coded like this */
4304 if (!sid_equal(&sid, get_global_sam_sid()))
4305 return NT_STATUS_ACCESS_DENIED;
4307 sid_copy(&info_sid, get_global_sam_sid());
4308 sid_append_rid(&info_sid, q_u->rid_group);
4309 sid_to_string(sid_string, &info_sid);
4311 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4312 return NT_STATUS_NO_MEMORY;
4314 info->acc_granted = acc_granted;
4316 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4318 /* check if that group really exists */
4320 ret = get_domain_group_from_sid(info->sid, &map);
4323 return NT_STATUS_NO_SUCH_GROUP;
4325 /* get a (unique) handle. open a policy on it. */
4326 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4327 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4329 return NT_STATUS_OK;
4332 /*********************************************************************
4333 _samr_remove_user_foreign_domain
4334 *********************************************************************/
4336 NTSTATUS _samr_remove_user_foreign_domain(pipes_struct *p,
4337 SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN *q_u,
4338 SAMR_R_REMOVE_USER_FOREIGN_DOMAIN *r_u)
4340 DOM_SID user_sid, dom_sid;
4341 SAM_ACCOUNT *sam_pass=NULL;
4344 sid_copy( &user_sid, &q_u->sid.sid );
4346 DEBUG(5,("_samr_remove_user_foreign_domain: removing user [%s]\n",
4347 sid_string_static(&user_sid)));
4349 /* Find the policy handle. Open a policy on it. */
4351 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
4352 return NT_STATUS_INVALID_HANDLE;
4354 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted,
4355 STD_RIGHT_DELETE_ACCESS, "_samr_remove_user_foreign_domain")))
4360 if ( !sid_check_is_in_our_domain(&user_sid) ) {
4361 DEBUG(5,("_samr_remove_user_foreign_domain: user not is our domain!\n"));
4362 return NT_STATUS_NO_SUCH_USER;
4365 /* check if the user exists before trying to delete */
4367 pdb_init_sam(&sam_pass);
4369 if ( !pdb_getsampwsid(sam_pass, &user_sid) ) {
4371 DEBUG(5,("_samr_remove_user_foreign_domain:User %s doesn't exist.\n",
4372 sid_string_static(&user_sid)));
4374 pdb_free_sam(&sam_pass);
4376 return NT_STATUS_NO_SUCH_USER;
4380 * delete the unix side
4382 * note: we don't check if the delete really happened
4383 * as the script is not necessary present
4384 * and maybe the sysadmin doesn't want to delete the unix side
4387 smb_delete_user(pdb_get_username(sam_pass));
4389 /* and delete the samba side */
4391 if ( !pdb_delete_sam_account(sam_pass) ) {
4393 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
4394 pdb_free_sam(&sam_pass);
4396 return NT_STATUS_CANNOT_DELETE;
4399 pdb_free_sam(&sam_pass);
4401 return NT_STATUS_OK;
4404 /*******************************************************************
4406 ********************************************************************/
4408 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4410 struct samr_info *info = NULL;
4412 uint32 min_pass_len,pass_hist,flag;
4413 time_t u_expire, u_min_age;
4414 NTTIME nt_expire, nt_min_age;
4416 time_t u_lock_duration, u_reset_time;
4417 NTTIME nt_lock_duration, nt_reset_time;
4423 uint32 num_users=0, num_groups=0, num_aliases=0;
4425 uint32 account_policy_temp;
4427 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4428 return NT_STATUS_NO_MEMORY;
4432 r_u->status = NT_STATUS_OK;
4434 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4436 /* find the policy handle. open a policy on it. */
4437 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4438 return NT_STATUS_INVALID_HANDLE;
4440 switch (q_u->switch_value) {
4442 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4443 min_pass_len = account_policy_temp;
4445 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4446 pass_hist = account_policy_temp;
4448 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4449 flag = account_policy_temp;
4451 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4452 u_expire = account_policy_temp;
4454 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4455 u_min_age = account_policy_temp;
4457 unix_to_nt_time_abs(&nt_expire, u_expire);
4458 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4460 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4461 flag, nt_expire, nt_min_age);
4465 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4467 if (!NT_STATUS_IS_OK(r_u->status)) {
4468 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4471 num_users=info->disp_info.num_user_account;
4474 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4475 if (NT_STATUS_IS_ERR(r_u->status)) {
4476 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4479 num_groups=info->disp_info.num_group_account;
4482 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4483 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
4484 num_users, num_groups, num_aliases);
4487 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4488 u_logout = account_policy_temp;
4490 unix_to_nt_time_abs(&nt_logout, u_logout);
4492 init_unk_info3(&ctr->info.inf3, nt_logout);
4495 init_unk_info5(&ctr->info.inf5, global_myname());
4498 init_unk_info6(&ctr->info.inf6);
4501 init_unk_info7(&ctr->info.inf7);
4504 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4505 u_lock_duration = account_policy_temp;
4507 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4508 u_reset_time = account_policy_temp;
4510 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4511 lockout = account_policy_temp;
4513 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4514 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4516 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4519 return NT_STATUS_INVALID_INFO_CLASS;
4522 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4524 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4529 /*******************************************************************
4531 ********************************************************************/
4533 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4535 time_t u_expire, u_min_age;
4537 time_t u_lock_duration, u_reset_time;
4539 r_u->status = NT_STATUS_OK;
4541 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4543 /* find the policy handle. open a policy on it. */
4544 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4545 return NT_STATUS_INVALID_HANDLE;
4547 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4549 switch (q_u->switch_value) {
4551 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4552 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4554 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4555 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4556 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4557 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4558 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4563 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4564 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4573 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4574 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count);
4576 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4577 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4578 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4581 return NT_STATUS_INVALID_INFO_CLASS;
4584 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4586 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));