2 * Unix SMB/Netbios implementation.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-1997,
6 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
7 * Copyright (C) Paul Ashton 1997.
8 * Copyright (C) Marc Jacobsen 1999.
9 * Copyright (C) Jeremy Allison 2001-2002.
10 * Copyright (C) Jean François Micouleau 1998-2001.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 * This is the implementation of the SAMR code.
33 extern fstring global_myworkgroup;
34 extern pstring global_myname;
35 extern DOM_SID global_sam_sid;
36 extern DOM_SID global_sid_Builtin;
38 extern rid_name domain_group_rids[];
39 extern rid_name domain_alias_rids[];
40 extern rid_name builtin_alias_rids[];
43 typedef struct _disp_info {
45 uint32 num_user_account;
46 DISP_USER_INFO *disp_user_info;
48 uint32 num_group_account;
49 DISP_GROUP_INFO *disp_group_info;
53 /* for use by the \PIPE\samr policy */
55 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
59 /*******************************************************************
60 Create a samr_info struct.
61 ********************************************************************/
63 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
65 struct samr_info *info;
68 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
73 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_to_string(sid_str, psid) ));
74 sid_copy( &info->sid, psid);
76 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
81 /*******************************************************************
82 Function to free the per handle data.
83 ********************************************************************/
84 static void free_samr_db(struct samr_info *info)
88 if (info->disp_info.group_dbloaded) {
89 for (i=0; i<info->disp_info.num_group_account; i++)
90 SAFE_FREE(info->disp_info.disp_group_info[i].grp);
92 SAFE_FREE(info->disp_info.disp_group_info);
95 if (info->disp_info.user_dbloaded){
96 for (i=0; i<info->disp_info.num_user_account; i++)
97 pdb_free_sam(&info->disp_info.disp_user_info[i].sam);
99 SAFE_FREE(info->disp_info.disp_user_info);
102 info->disp_info.user_dbloaded=False;
103 info->disp_info.group_dbloaded=False;
104 info->disp_info.num_group_account=0;
105 info->disp_info.num_user_account=0;
109 static void free_samr_info(void *ptr)
111 struct samr_info *info=(struct samr_info *) ptr;
117 /*******************************************************************
118 Ensure password info is never given out. Paranioa... JRA.
119 ********************************************************************/
121 static void samr_clear_passwd_fields( SAM_USER_INFO_21 *pass, int num_entries)
128 for (i = 0; i < num_entries; i++) {
129 memset(&pass[i].lm_pwd, '\0', sizeof(pass[i].lm_pwd));
130 memset(&pass[i].nt_pwd, '\0', sizeof(pass[i].nt_pwd));
134 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
140 /* These now zero out the old password */
142 pdb_set_lanman_passwd(sam_pass, NULL);
143 pdb_set_nt_passwd(sam_pass, NULL);
147 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask)
149 SAM_ACCOUNT *pwd = NULL;
150 DISP_USER_INFO *pwd_array = NULL;
152 DEBUG(10,("load_sampwd_entries\n"));
154 /* if the snapshoot is already loaded, return */
155 if (info->disp_info.user_dbloaded==True) {
156 DEBUG(10,("load_sampwd_entries: already in memory\n"));
160 if (!pdb_setsampwent(False)) {
161 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
162 return NT_STATUS_ACCESS_DENIED;
165 for (pdb_init_sam(&pwd); pdb_getsampwent(pwd) == True; pwd=NULL, pdb_init_sam(&pwd) ) {
167 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
169 DEBUG(5,(" acb_mask %x reject\n", acb_mask));
173 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
174 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
176 DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
177 pwd_array=(DISP_USER_INFO *)Realloc(info->disp_info.disp_user_info,
178 (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(DISP_USER_INFO));
181 return NT_STATUS_NO_MEMORY;
183 info->disp_info.disp_user_info=pwd_array;
186 /* link the SAM_ACCOUNT to the array */
187 info->disp_info.disp_user_info[info->disp_info.num_user_account].sam=pwd;
189 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
191 info->disp_info.num_user_account++;
196 /* the snapshoot is in memory, we're ready to enumerate fast */
198 info->disp_info.user_dbloaded=True;
200 DEBUG(12,("load_sampwd_entries: done\n"));
205 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
208 DISP_GROUP_INFO *grp_array = NULL;
209 uint32 group_entries = 0;
212 DEBUG(10,("load_group_domain_entries\n"));
214 /* if the snapshoot is already loaded, return */
215 if (info->disp_info.group_dbloaded==True) {
216 DEBUG(10,("load_group_domain_entries: already in memory\n"));
220 enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
222 info->disp_info.num_group_account=group_entries;
224 grp_array=(DISP_GROUP_INFO *)malloc(info->disp_info.num_group_account*sizeof(DISP_GROUP_INFO));
226 if (group_entries!=0 && grp_array==NULL) {
228 return NT_STATUS_NO_MEMORY;
231 info->disp_info.disp_group_info=grp_array;
233 for (i=0; i<group_entries; i++) {
235 grp_array[i].grp=(DOMAIN_GRP *)malloc(sizeof(DOMAIN_GRP));
237 fstrcpy(grp_array[i].grp->name, map[i].nt_name);
238 fstrcpy(grp_array[i].grp->comment, map[i].comment);
239 sid_split_rid(&map[i].sid, &grp_array[i].grp->rid);
240 grp_array[i].grp->attr=SID_NAME_DOM_GRP;
245 /* the snapshoot is in memory, we're ready to enumerate fast */
247 info->disp_info.group_dbloaded=True;
249 DEBUG(12,("load_group_domain_entries: done\n"));
255 /*******************************************************************
256 This next function should be replaced with something that
257 dynamically returns the correct user info..... JRA.
258 ********************************************************************/
260 static NTSTATUS get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx,
261 int *total_entries, int *num_entries,
262 int max_num_entries, uint16 acb_mask)
264 SAM_ACCOUNT *pwd = NULL;
265 BOOL not_finished = True;
268 (*total_entries) = 0;
271 return NT_STATUS_NO_MEMORY;
275 if (!pdb_setsampwent(False)) {
276 DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n"));
278 return NT_STATUS_ACCESS_DENIED;
281 while (((not_finished = pdb_getsampwent(pwd)) != False)
282 && (*num_entries) < max_num_entries)
290 /* skip the requested number of entries.
291 not very efficient, but hey... */
296 user_name_len = strlen(pdb_get_username(pwd))+1;
297 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pdb_get_username(pwd), user_name_len);
298 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
299 pw_buf[(*num_entries)].user_rid = pdb_get_user_rid(pwd);
300 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
302 /* Now check if the NT compatible password is available. */
303 if (pdb_get_nt_passwd(pwd))
304 memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
306 pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
308 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
309 (*num_entries), pdb_get_username(pwd), pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd) ));
311 if (acb_mask == 0 || (pdb_get_acct_ctrl(pwd) & acb_mask)) {
312 DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
315 DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
328 return STATUS_MORE_ENTRIES;
333 /*******************************************************************
335 ********************************************************************/
337 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
339 r_u->status = NT_STATUS_OK;
341 /* close the policy handle */
342 if (!close_policy_hnd(p, &q_u->pol))
343 return NT_STATUS_OBJECT_NAME_INVALID;
345 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
350 /*******************************************************************
351 samr_reply_open_domain
352 ********************************************************************/
354 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
356 struct samr_info *info;
358 r_u->status = NT_STATUS_OK;
360 /* find the connection policy handle. */
361 if (!find_policy_by_hnd(p, &q_u->pol, NULL))
362 return NT_STATUS_INVALID_HANDLE;
364 /* associate the domain SID with the (unique) handle. */
365 if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
366 return NT_STATUS_NO_MEMORY;
368 /* get a (unique) handle. open a policy on it. */
369 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
370 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
372 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
377 /*******************************************************************
378 _samr_get_usrdom_pwinfo
379 ********************************************************************/
381 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
383 struct samr_info *info = NULL;
385 r_u->status = NT_STATUS_OK;
387 /* find the policy handle. open a policy on it. */
388 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
389 return NT_STATUS_INVALID_HANDLE;
391 if (!sid_check_is_in_our_domain(&info->sid))
392 return NT_STATUS_OBJECT_TYPE_MISMATCH;
394 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
396 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
399 * NT sometimes return NT_STATUS_ACCESS_DENIED
400 * I don't know yet why.
406 /*******************************************************************
408 ********************************************************************/
410 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC_BUF **buf, DOM_SID *usr_sid)
412 extern DOM_SID global_sid_World;
420 SEC_DESC *psd = NULL;
423 sid_copy(&adm_sid, &global_sid_Builtin);
424 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
426 sid_copy(&act_sid, &global_sid_Builtin);
427 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
429 init_sec_access(&mask, 0x2035b);
430 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
432 init_sec_access(&mask, 0xf07ff);
433 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
434 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
436 init_sec_access(&mask,0x20044);
437 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
439 if((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
440 return NT_STATUS_NO_MEMORY;
442 if((psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, &sd_size)) == NULL)
443 return NT_STATUS_NO_MEMORY;
445 if((*buf = make_sec_desc_buf(ctx, sd_size, psd)) == NULL)
446 return NT_STATUS_NO_MEMORY;
451 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid)
453 struct samr_info *info = NULL;
455 /* find the policy handle. open a policy on it. */
456 if (!find_policy_by_hnd(p, pol, (void **)&info))
466 /*******************************************************************
468 ********************************************************************/
470 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
475 r_u->status = NT_STATUS_OK;
479 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid))
480 return NT_STATUS_INVALID_HANDLE;
482 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
484 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &r_u->buf, &pol_sid);
486 if (NT_STATUS_IS_OK(r_u->status))
492 /*******************************************************************
493 makes a SAM_ENTRY / UNISTR2* structure from a user list.
494 ********************************************************************/
496 static void make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
497 uint32 num_sam_entries, SAM_USER_INFO_21 *pass)
506 if (num_sam_entries == 0)
509 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
511 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
513 if (sam == NULL || uni_name == NULL) {
514 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
519 ZERO_STRUCTP(uni_name);
521 for (i = 0; i < num_sam_entries; i++) {
522 int len = pass[i].uni_user_name.uni_str_len;
524 init_sam_entry(&sam[i], len, pass[i].user_rid);
525 copy_unistr2(&uni_name[i], &pass[i].uni_user_name);
529 *uni_name_pp = uni_name;
532 /*******************************************************************
533 samr_reply_enum_dom_users
534 ********************************************************************/
536 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_ENUM_DOM_USERS *r_u)
538 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
540 int total_entries = 0;
542 r_u->status = NT_STATUS_OK;
544 /* find the policy handle. open a policy on it. */
545 if (!find_policy_by_hnd(p, &q_u->pol, NULL))
546 return NT_STATUS_INVALID_HANDLE;
548 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
551 r_u->status = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
552 MAX_SAM_ENTRIES, q_u->acb_mask);
555 if (NT_STATUS_IS_ERR(r_u->status))
558 samr_clear_passwd_fields(pass, num_entries);
561 * Note from JRA. total_entries is not being used here. Currently if there is a
562 * large user base then it looks like NT will enumerate until get_sampwd_entries
563 * returns False due to num_entries being zero. This will cause an access denied
564 * return. I don't think this is right and needs further investigation. Note that
565 * this is also the same in the TNG code (I don't think that has been tested with
566 * a very large user list as MAX_SAM_ENTRIES is set to 600).
568 * I also think that one of the 'num_entries' return parameters is probably
569 * the "max entries" parameter - but in the TNG code they're all currently set to the same
570 * value (again I think this is wrong).
573 make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name, num_entries, pass);
575 init_samr_r_enum_dom_users(r_u, q_u->start_idx + num_entries, num_entries);
577 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
582 /*******************************************************************
583 makes a SAM_ENTRY / UNISTR2* structure from a group list.
584 ********************************************************************/
586 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
587 uint32 num_sam_entries, DOMAIN_GRP *grp)
596 if (num_sam_entries == 0)
599 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
601 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
603 if (sam == NULL || uni_name == NULL) {
604 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
608 for (i = 0; i < num_sam_entries; i++) {
610 * JRA. I think this should include the null. TNG does not.
612 int len = strlen(grp[i].name)+1;
614 init_sam_entry(&sam[i], len, grp[i].rid);
615 init_unistr2(&uni_name[i], grp[i].name, len);
619 *uni_name_pp = uni_name;
622 /*******************************************************************
623 Get the group entries - similar to get_sampwd_entries().
624 ********************************************************************/
626 static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
627 uint32 *p_num_entries, uint32 max_entries)
630 uint32 num_entries = 0;
635 sid_to_string(sid_str, sid);
636 DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str));
640 /* well-known aliases */
641 if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
643 enum_group_mapping(SID_NAME_ALIAS, &map, (int *)&num_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
645 if (num_entries != 0) {
646 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
648 return NT_STATUS_NO_MEMORY;
650 for(i=0; i<num_entries && i<max_entries; i++) {
651 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
652 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
658 } else if (sid_equal(sid, &global_sam_sid) && !lp_hide_local_users()) {
659 struct sys_grent *glist;
660 struct sys_grent *grp;
662 gid_t winbind_gid_low, winbind_gid_high;
664 lp_winbind_gid(&winbind_gid_low, &winbind_gid_high);
667 /* we return the UNIX groups here. This seems to be the right */
668 /* thing to do, since NT member servers return their local */
669 /* groups in the same situation. */
671 /* use getgrent_list() to retrieve the list of groups to avoid
672 * problems with getgrent possible infinite loop by internal
673 * libc grent structures overwrites by called functions */
674 grp = glist = getgrent_list();
676 return NT_STATUS_NO_MEMORY;
678 for (; (num_entries < max_entries) && (grp != NULL); grp = grp->next) {
681 if(!get_group_from_gid(grp->gr_gid, &smap, MAPPING_WITHOUT_PRIV))
684 if (smap.sid_name_use!=SID_NAME_ALIAS) {
688 sid_split_rid(&smap.sid, &trid);
690 if (!sid_equal(sid, &smap.sid))
693 /* Don't return winbind groups as they are not local! */
694 if ((grp->gr_gid >= winbind_gid_low)&&(grp->gr_gid <= winbind_gid_high)) {
695 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
699 /* Don't return user private groups... */
702 * We used to do a Get_Pwnam() here, but this has been
703 * trimmed back to the common case for private groups
704 * to save lookups and to use the _alloc interface.
706 * This also matches the group mapping code
709 if ((pw = getpwnam_alloc(smap.nt_name)) != 0) {
710 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
715 for( i = 0; i < num_entries; i++)
716 if ( (*d_grp)[i].rid == trid )
719 if ( i < num_entries ) {
720 continue; /* rid was there, dup! */
723 /* JRA - added this for large group db enumeration... */
726 /* skip the requested number of entries.
727 not very efficient, but hey...
733 *d_grp=talloc_realloc(ctx,*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
736 return NT_STATUS_NO_MEMORY;
739 fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
740 (*d_grp)[num_entries].rid = trid;
742 DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries, trid));
748 *p_num_entries = num_entries;
750 DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries));
752 if (num_entries >= max_entries)
753 return STATUS_MORE_ENTRIES;
757 /*******************************************************************
758 Get the group entries - similar to get_sampwd_entries().
759 ********************************************************************/
761 static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
762 uint32 *p_num_entries, uint32 max_entries)
766 uint32 group_entries = 0;
767 uint32 num_entries = 0;
771 enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
773 num_entries=group_entries-start_idx;
775 /* limit the number of entries */
776 if (num_entries>max_entries) {
777 DEBUG(5,("Limiting to %d entries\n", max_entries));
778 num_entries=max_entries;
781 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
782 if (num_entries!=0 && *d_grp==NULL){
784 return NT_STATUS_NO_MEMORY;
787 for (i=0; i<num_entries; i++) {
788 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
789 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
790 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
791 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
796 *p_num_entries = num_entries;
801 /*******************************************************************
802 samr_reply_enum_dom_groups
803 Only reply with one group - domain admins. This must be fixed for
805 ********************************************************************/
807 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
809 DOMAIN_GRP *grp=NULL;
813 r_u->status = NT_STATUS_OK;
815 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
816 return NT_STATUS_INVALID_HANDLE;
818 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
820 /* the domain group array is being allocated in the function below */
821 get_group_domain_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES);
823 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
825 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
827 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
833 /*******************************************************************
834 samr_reply_enum_dom_aliases
835 ********************************************************************/
837 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
839 DOMAIN_GRP *grp=NULL;
840 uint32 num_entries = 0;
845 r_u->status = NT_STATUS_OK;
847 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
848 return NT_STATUS_INVALID_HANDLE;
850 sid_to_string(sid_str, &sid);
851 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
853 status = get_group_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
854 &num_entries, MAX_SAM_ENTRIES);
855 if (NT_STATUS_IS_ERR(status)) return status;
857 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
861 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
863 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
868 /*******************************************************************
869 samr_reply_query_dispinfo
870 ********************************************************************/
871 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_QUERY_DISPINFO *r_u)
873 struct samr_info *info = NULL;
874 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
877 uint32 max_entries=q_u->max_entries;
878 uint32 enum_context=q_u->start_idx;
879 uint32 max_size=q_u->max_size;
881 SAM_DISPINFO_CTR *ctr;
882 uint32 temp_size=0, total_data_size=0;
884 uint32 num_account = 0;
885 enum remote_arch_types ra_type = get_remote_arch();
888 max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
890 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
891 r_u->status = NT_STATUS_OK;
893 /* find the policy handle. open a policy on it. */
894 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
895 return NT_STATUS_INVALID_HANDLE;
898 * calculate how many entries we will return.
900 * - the number of entries the client asked
901 * - our limit on that
902 * - the starting point (enumeration context)
903 * - the buffer size the client will accept
907 * We are a lot more like W2K. Instead of reading the SAM
908 * each time to find the records we need to send back,
909 * we read it once and link that copy to the sam handle.
910 * For large user list (over the MAX_SAM_ENTRIES)
911 * it's a definitive win.
912 * second point to notice: between enumerations
913 * our sam is now the same as it's a snapshoot.
914 * third point: got rid of the static SAM_USER_21 struct
915 * no more intermediate.
916 * con: it uses much more memory, as a full copy is stored
919 * If you want to change it, think twice and think
920 * of the second point , that's really important.
925 /* Get what we need from the password database */
927 if (q_u->switch_level==2)
928 acb_mask = ACB_WSTRUST;
930 acb_mask = ACB_NORMAL;
932 /* Get what we need from the password database */
933 switch (q_u->switch_level) {
938 r_u->status=load_sampwd_entries(info, acb_mask);
940 if (NT_STATUS_IS_ERR(r_u->status)) {
941 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
944 num_account = info->disp_info.num_user_account;
948 r_u->status = load_group_domain_entries(info, &info->sid);
949 if (NT_STATUS_IS_ERR(r_u->status))
951 num_account = info->disp_info.num_group_account;
954 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
955 return NT_STATUS_INVALID_INFO_CLASS;
958 /* first limit the number of entries we will return */
959 if(max_entries > max_sam_entries) {
960 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
961 max_entries = max_sam_entries;
964 if (enum_context > num_account) {
965 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
969 /* verify we won't overflow */
970 if (max_entries > num_account-enum_context) {
971 max_entries = num_account-enum_context;
972 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
975 /* calculate the size and limit on the number of entries we will return */
976 temp_size=(enum_context+max_entries)*struct_size;
978 if (temp_size>max_size) {
979 max_entries=max_size/struct_size;
980 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
983 if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
984 return NT_STATUS_NO_MEMORY;
988 /* Now create reply structure */
989 switch (q_u->switch_level) {
992 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
993 return NT_STATUS_NO_MEMORY;
995 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context, info->disp_info.disp_user_info);
996 if (NT_STATUS_IS_ERR(disp_ret))
1001 if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1002 return NT_STATUS_NO_MEMORY;
1004 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context, info->disp_info.disp_user_info);
1005 if (NT_STATUS_IS_ERR(disp_ret))
1010 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1011 return NT_STATUS_NO_MEMORY;
1013 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1014 if (NT_STATUS_IS_ERR(disp_ret))
1019 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1020 return NT_STATUS_NO_MEMORY;
1022 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1023 if (NT_STATUS_IS_ERR(disp_ret))
1028 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1029 return NT_STATUS_NO_MEMORY;
1031 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1032 if (NT_STATUS_IS_ERR(disp_ret))
1037 ctr->sam.info = NULL;
1038 return NT_STATUS_INVALID_INFO_CLASS;
1041 /* calculate the total size */
1042 total_data_size=num_account*struct_size;
1044 if (enum_context+max_entries < num_account)
1045 r_u->status = STATUS_MORE_ENTRIES;
1047 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1049 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1055 /*******************************************************************
1056 samr_reply_query_aliasinfo
1057 ********************************************************************/
1059 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1061 struct samr_info *info = NULL;
1064 r_u->status = NT_STATUS_OK;
1066 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1068 /* find the policy handle. open a policy on it. */
1069 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1070 return NT_STATUS_INVALID_HANDLE;
1072 if (!sid_check_is_in_our_domain(&info->sid) &&
1073 !sid_check_is_in_builtin(&info->sid))
1074 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1076 if(!get_local_group_from_sid(info->sid, &map, MAPPING_WITHOUT_PRIV))
1077 return NT_STATUS_NO_SUCH_ALIAS;
1079 switch (q_u->switch_level) {
1082 r_u->ctr.switch_value1 = 1;
1083 init_samr_alias_info1(&r_u->ctr.alias.info1, map.nt_name, 1, map.comment);
1087 r_u->ctr.switch_value1 = 3;
1088 init_samr_alias_info3(&r_u->ctr.alias.info3, map.comment);
1091 return NT_STATUS_INVALID_INFO_CLASS;
1094 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1100 /*******************************************************************
1101 samr_reply_lookup_ids
1102 ********************************************************************/
1104 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1106 uint32 rid[MAX_SAM_ENTRIES];
1107 int num_rids = q_u->num_sids1;
1109 r_u->status = NT_STATUS_OK;
1111 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1113 if (num_rids > MAX_SAM_ENTRIES) {
1114 num_rids = MAX_SAM_ENTRIES;
1115 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1120 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1122 for (i = 0; i < num_rids && status == 0; i++)
1124 struct sam_passwd *sam_pass;
1128 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1129 q_u->uni_user_name[i].uni_str_len));
1131 /* find the user account */
1133 sam_pass = get_smb21pwd_entry(user_name, 0);
1136 if (sam_pass == NULL)
1138 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1143 rid[i] = sam_pass->user_rid;
1149 rid[0] = BUILTIN_ALIAS_RID_USERS;
1151 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1153 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1159 /*******************************************************************
1161 ********************************************************************/
1163 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1165 uint32 rid[MAX_SAM_ENTRIES];
1167 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1168 enum SID_NAME_USE local_type;
1170 int num_rids = q_u->num_names2;
1174 r_u->status = NT_STATUS_OK;
1176 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1181 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid)) {
1182 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1186 if (num_rids > MAX_SAM_ENTRIES) {
1187 num_rids = MAX_SAM_ENTRIES;
1188 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1191 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1193 become_root(); /* local_lookup_name can require root privs */
1195 for (i = 0; i < num_rids; i++) {
1199 r_u->status = NT_STATUS_NONE_MAPPED;
1201 rid [i] = 0xffffffff;
1202 type[i] = SID_NAME_UNKNOWN;
1204 rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1207 * we are only looking for a name
1208 * the SID we get back can be outside
1209 * the scope of the pol_sid
1211 * in clear: it prevents to reply to domain\group: yes
1212 * when only builtin\group exists.
1214 * a cleaner code is to add the sid of the domain we're looking in
1215 * to the local_lookup_name function.
1217 if(local_lookup_name(name, &sid, &local_type)) {
1218 sid_split_rid(&sid, &local_rid);
1220 if (sid_equal(&sid, &pol_sid)) {
1223 r_u->status = NT_STATUS_OK;
1230 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1232 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1237 /*******************************************************************
1238 _samr_chgpasswd_user
1239 ********************************************************************/
1241 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1246 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1248 r_u->status = NT_STATUS_OK;
1250 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1251 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1253 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1256 * Pass the user through the NT -> unix user mapping
1260 (void)map_username(user_name);
1263 * UNIX username case mangling not required, pass_oem_change
1264 * is case insensitive.
1267 if (!pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1268 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1269 r_u->status = NT_STATUS_WRONG_PASSWORD;
1271 init_samr_r_chgpasswd_user(r_u, r_u->status);
1273 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1278 /*******************************************************************
1279 makes a SAMR_R_LOOKUP_RIDS structure.
1280 ********************************************************************/
1282 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1283 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1286 UNIHDR *hdr_name=NULL;
1287 UNISTR2 *uni_name=NULL;
1289 *pp_uni_name = NULL;
1290 *pp_hdr_name = NULL;
1292 if (num_names != 0) {
1293 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1294 if (hdr_name == NULL)
1297 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1298 if (uni_name == NULL)
1302 for (i = 0; i < num_names; i++) {
1303 int len = names[i] != NULL ? strlen(names[i]) : 0;
1304 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1305 init_uni_hdr(&hdr_name[i], len);
1306 init_unistr2(&uni_name[i], names[i], len);
1309 *pp_uni_name = uni_name;
1310 *pp_hdr_name = hdr_name;
1315 /*******************************************************************
1317 ********************************************************************/
1319 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1321 fstring group_names[MAX_SAM_ENTRIES];
1322 uint32 *group_attrs = NULL;
1323 UNIHDR *hdr_name = NULL;
1324 UNISTR2 *uni_name = NULL;
1326 int num_rids = q_u->num_rids1;
1329 r_u->status = NT_STATUS_OK;
1331 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1333 /* find the policy handle. open a policy on it. */
1334 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid))
1335 return NT_STATUS_INVALID_HANDLE;
1337 if (num_rids > MAX_SAM_ENTRIES) {
1338 num_rids = MAX_SAM_ENTRIES;
1339 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1343 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1344 return NT_STATUS_NO_MEMORY;
1347 r_u->status = NT_STATUS_NONE_MAPPED;
1349 become_root(); /* lookup_sid can require root privs */
1351 for (i = 0; i < num_rids; i++) {
1355 enum SID_NAME_USE type;
1357 group_attrs[i] = SID_NAME_UNKNOWN;
1358 *group_names[i] = '\0';
1360 if (sid_equal(&pol_sid, &global_sam_sid)) {
1361 sid_copy(&sid, &pol_sid);
1362 sid_append_rid(&sid, q_u->rid[i]);
1364 if (lookup_sid(&sid, domname, tmpname, &type)) {
1365 r_u->status = NT_STATUS_OK;
1366 group_attrs[i] = (uint32)type;
1367 fstrcpy(group_names[i],tmpname);
1368 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1375 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1376 return NT_STATUS_NO_MEMORY;
1378 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1380 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1385 /*******************************************************************
1386 _api_samr_open_user. Safe - gives out no passwd info.
1387 ********************************************************************/
1389 NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1391 SAM_ACCOUNT *sampass=NULL;
1393 POLICY_HND domain_pol = q_u->domain_pol;
1394 uint32 user_rid = q_u->user_rid;
1395 POLICY_HND *user_pol = &r_u->user_pol;
1396 struct samr_info *info = NULL;
1399 r_u->status = NT_STATUS_OK;
1401 /* find the domain policy handle. */
1402 if (!find_policy_by_hnd(p, &domain_pol, NULL))
1403 return NT_STATUS_INVALID_HANDLE;
1405 pdb_init_sam(&sampass);
1408 ret=pdb_getsampwrid(sampass, user_rid);
1411 /* check that the RID exists in our domain. */
1413 pdb_free_sam(&sampass);
1414 return NT_STATUS_NO_SUCH_USER;
1417 pdb_free_sam(&sampass);
1419 /* Get the domain SID stored in the domain policy */
1420 if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
1421 return NT_STATUS_INVALID_HANDLE;
1423 /* append the user's RID to it */
1424 if(!sid_append_rid(&sid, user_rid))
1425 return NT_STATUS_NO_SUCH_USER;
1427 /* associate the user's SID with the new handle. */
1428 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1429 return NT_STATUS_NO_MEMORY;
1431 /* get a (unique) handle. open a policy on it. */
1432 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1433 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1438 /*************************************************************************
1439 get_user_info_10. Safe. Only gives out acb bits.
1440 *************************************************************************/
1442 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1444 SAM_ACCOUNT *smbpass=NULL;
1447 if (!pdb_rid_is_user(user_rid)) {
1448 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1452 pdb_init_sam(&smbpass);
1455 ret = pdb_getsampwrid(smbpass, user_rid);
1459 DEBUG(4,("User 0x%x not found\n", user_rid));
1460 pdb_free_sam(&smbpass);
1464 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1467 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1469 pdb_free_sam(&smbpass);
1474 /*************************************************************************
1475 get_user_info_12. OK - this is the killer as it gives out password info.
1476 Ensure that this is only allowed on an encrypted connection with a root
1478 *************************************************************************/
1480 static NTSTATUS get_user_info_12(pipes_struct *p, SAM_USER_INFO_12 * id12, uint32 user_rid)
1482 SAM_ACCOUNT *smbpass=NULL;
1485 if (!p->ntlmssp_auth_validated)
1486 return NT_STATUS_ACCESS_DENIED;
1488 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1489 return NT_STATUS_ACCESS_DENIED;
1492 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1494 pdb_init_sam(&smbpass);
1496 ret = pdb_getsampwrid(smbpass, user_rid);
1499 DEBUG(4, ("User 0x%x not found\n", user_rid));
1500 pdb_free_sam(&smbpass);
1501 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1504 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1506 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1507 pdb_free_sam(&smbpass);
1508 return NT_STATUS_ACCOUNT_DISABLED;
1512 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1514 pdb_free_sam(&smbpass);
1516 return NT_STATUS_OK;
1519 /*************************************************************************
1521 *************************************************************************/
1523 static BOOL get_user_info_20(SAM_USER_INFO_20 *id20, uint32 user_rid)
1525 SAM_ACCOUNT *sampass=NULL;
1528 if (!pdb_rid_is_user(user_rid)) {
1529 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1533 pdb_init_sam(&sampass);
1536 ret = pdb_getsampwrid(sampass, user_rid);
1540 DEBUG(4,("User 0x%x not found\n", user_rid));
1541 pdb_free_sam(&sampass);
1545 samr_clear_sam_passwd(sampass);
1547 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1550 init_sam_user_info20A(id20, sampass);
1552 pdb_free_sam(&sampass);
1557 /*************************************************************************
1559 *************************************************************************/
1561 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1563 SAM_ACCOUNT *sampass=NULL;
1566 if (!pdb_rid_is_user(user_rid)) {
1567 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1571 pdb_init_sam(&sampass);
1574 ret = pdb_getsampwrid(sampass, user_rid);
1578 DEBUG(4,("User 0x%x not found\n", user_rid));
1579 pdb_free_sam(&sampass);
1583 samr_clear_sam_passwd(sampass);
1585 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1588 init_sam_user_info21A(id21, sampass);
1590 pdb_free_sam(&sampass);
1595 /*******************************************************************
1596 _samr_query_userinfo
1597 ********************************************************************/
1599 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1601 SAM_USERINFO_CTR *ctr;
1603 struct samr_info *info = NULL;
1605 r_u->status=NT_STATUS_OK;
1607 /* search for the handle */
1608 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1609 return NT_STATUS_INVALID_HANDLE;
1611 if (!sid_check_is_in_our_domain(&info->sid))
1612 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1614 sid_peek_rid(&info->sid, &rid);
1616 DEBUG(5,("_samr_query_userinfo: rid:0x%x\n", rid));
1618 ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1620 return NT_STATUS_NO_MEMORY;
1624 /* ok! user info levels (lots: see MSDEV help), off we go... */
1625 ctr->switch_value = q_u->switch_value;
1627 switch (q_u->switch_value) {
1629 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1630 if (ctr->info.id10 == NULL)
1631 return NT_STATUS_NO_MEMORY;
1633 if (!get_user_info_10(ctr->info.id10, rid))
1634 return NT_STATUS_NO_SUCH_USER;
1638 /* whoops - got this wrong. i think. or don't understand what's happening. */
1642 info = (void *)&id11;
1644 expire.low = 0xffffffff;
1645 expire.high = 0x7fffffff;
1647 ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1652 ZERO_STRUCTP(ctr->info.id11);
1653 init_sam_user_info11(ctr->info.id11, &expire,
1654 "BROOKFIELDS$", /* name */
1655 0x03ef, /* user rid */
1656 0x201, /* group rid */
1657 0x0080); /* acb info */
1664 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1665 if (ctr->info.id12 == NULL)
1666 return NT_STATUS_NO_MEMORY;
1668 if (NT_STATUS_IS_ERR(r_u->status = get_user_info_12(p, ctr->info.id12, rid)))
1673 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1674 if (ctr->info.id20 == NULL)
1675 return NT_STATUS_NO_MEMORY;
1676 if (!get_user_info_20(ctr->info.id20, rid))
1677 return NT_STATUS_NO_SUCH_USER;
1681 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1682 if (ctr->info.id21 == NULL)
1683 return NT_STATUS_NO_MEMORY;
1684 if (!get_user_info_21(ctr->info.id21, rid))
1685 return NT_STATUS_NO_SUCH_USER;
1689 return NT_STATUS_INVALID_INFO_CLASS;
1692 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1694 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1699 /*******************************************************************
1700 samr_reply_query_usergroups
1701 ********************************************************************/
1703 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1705 SAM_ACCOUNT *sam_pass=NULL;
1706 DOM_GID *gids = NULL;
1709 struct samr_info *info = NULL;
1713 * from the SID in the request:
1714 * we should send back the list of DOMAIN GROUPS
1715 * the user is a member of
1717 * and only the DOMAIN GROUPS
1718 * no ALIASES !!! neither aliases of the domain
1719 * nor aliases of the builtin SID
1724 r_u->status = NT_STATUS_OK;
1726 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1728 /* find the policy handle. open a policy on it. */
1729 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1730 return NT_STATUS_INVALID_HANDLE;
1732 if (!sid_check_is_in_our_domain(&info->sid))
1733 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1735 sid_peek_rid(&info->sid, &rid);
1737 pdb_init_sam(&sam_pass);
1740 ret = pdb_getsampwrid(sam_pass, rid);
1744 pdb_free_sam(&sam_pass);
1745 return NT_STATUS_NO_SUCH_USER;
1748 if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
1749 pdb_free_sam(&sam_pass);
1750 return NT_STATUS_NO_SUCH_GROUP;
1753 /* construct the response. lkclXXXX: gids are not copied! */
1754 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
1756 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1758 pdb_free_sam(&sam_pass);
1763 /*******************************************************************
1764 _samr_query_dom_info
1765 ********************************************************************/
1767 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
1769 struct samr_info *info = NULL;
1771 uint32 min_pass_len,pass_hist,flag;
1772 time_t u_expire, u_min_age;
1773 NTTIME nt_expire, nt_min_age;
1775 time_t u_lock_duration, u_reset_time;
1776 NTTIME nt_lock_duration, nt_reset_time;
1782 uint32 num_users=0, num_groups=0, num_aliases=0;
1784 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
1785 return NT_STATUS_NO_MEMORY;
1789 r_u->status = NT_STATUS_OK;
1791 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
1793 /* find the policy handle. open a policy on it. */
1794 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1795 return NT_STATUS_INVALID_HANDLE;
1797 switch (q_u->switch_value) {
1799 account_policy_get(AP_MIN_PASSWORD_LEN, &min_pass_len);
1800 account_policy_get(AP_PASSWORD_HISTORY, &pass_hist);
1801 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &flag);
1802 account_policy_get(AP_MAX_PASSWORD_AGE, (int *)&u_expire);
1803 account_policy_get(AP_MIN_PASSWORD_AGE, (int *)&u_min_age);
1805 unix_to_nt_time_abs(&nt_expire, u_expire);
1806 unix_to_nt_time_abs(&nt_min_age, u_min_age);
1808 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
1809 flag, nt_expire, nt_min_age);
1813 r_u->status=load_sampwd_entries(info, ACB_NORMAL);
1815 if (NT_STATUS_IS_ERR(r_u->status)) {
1816 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1819 num_users=info->disp_info.num_user_account;
1822 r_u->status=load_group_domain_entries(info, &global_sam_sid);
1823 if (NT_STATUS_IS_ERR(r_u->status)) {
1824 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
1827 num_groups=info->disp_info.num_group_account;
1830 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
1831 init_unk_info2(&ctr->info.inf2, global_myworkgroup, global_myname, (uint32) time(NULL),
1832 num_users, num_groups, num_aliases);
1835 account_policy_get(AP_TIME_TO_LOGOUT, (int *)&u_logout);
1836 unix_to_nt_time_abs(&nt_logout, u_logout);
1838 init_unk_info3(&ctr->info.inf3, nt_logout);
1841 init_unk_info5(&ctr->info.inf5, global_myname);
1844 init_unk_info6(&ctr->info.inf6);
1847 init_unk_info7(&ctr->info.inf7);
1850 account_policy_get(AP_LOCK_ACCOUNT_DURATION, (int *)&u_lock_duration);
1851 account_policy_get(AP_RESET_COUNT_TIME, (int *)&u_reset_time);
1852 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &lockout);
1854 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
1855 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
1857 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
1860 return NT_STATUS_INVALID_INFO_CLASS;
1863 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
1865 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
1870 /*******************************************************************
1871 _api_samr_create_user
1872 Create an account, can be either a normal user or a machine.
1873 This funcion will need to be updated for bdc/domain trusts.
1874 ********************************************************************/
1876 NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
1878 SAM_ACCOUNT *sam_pass=NULL;
1882 POLICY_HND dom_pol = q_u->domain_pol;
1883 UNISTR2 user_account = q_u->uni_name;
1884 uint16 acb_info = q_u->acb_info;
1885 POLICY_HND *user_pol = &r_u->user_pol;
1886 struct samr_info *info = NULL;
1891 /* find the policy handle. open a policy on it. */
1892 if (!find_policy_by_hnd(p, &dom_pol, NULL))
1893 return NT_STATUS_INVALID_HANDLE;
1895 /* find the account: tell the caller if it exists.
1896 lkclXXXX i have *no* idea if this is a problem or not
1897 or even if you are supposed to construct a different
1898 reply if the account already exists...
1901 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
1904 pdb_init_sam(&sam_pass);
1907 ret = pdb_getsampwnam(sam_pass, account);
1910 /* this account exists: say so */
1911 pdb_free_sam(&sam_pass);
1912 return NT_STATUS_USER_EXISTS;
1915 pdb_free_sam(&sam_pass);
1918 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
1919 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
1920 * that only people with write access to the smbpasswd file will be able
1921 * to create a user. JRA.
1925 * add the user in the /etc/passwd file or the unix authority system.
1926 * We don't check if the smb_create_user() function succed or not for 2 reasons:
1927 * a) local_password_change() checks for us if the /etc/passwd account really exists
1928 * b) smb_create_user() would return an error if the account already exists
1929 * and as it could return an error also if it can't create the account, it would be tricky.
1931 * So we go the easy way, only check after if the account exists.
1932 * JFM (2/3/2001), to clear any possible bad understanding (-:
1934 * We now have seperate script paramaters for adding users/machines so we
1935 * now have some sainity-checking to match.
1938 DEBUG(10,("checking account %s at pos %d for $ termination\n",account, strlen(account)-1));
1940 if ((acb_info & ACB_WSTRUST) && (account[strlen(account)-1] == '$')) {
1941 pstrcpy(add_script, lp_addmachine_script());
1942 } else if ((!(acb_info & ACB_WSTRUST)) && (account[strlen(account)-1] != '$')) {
1943 pstrcpy(add_script, lp_adduser_script());
1945 DEBUG(0, ("_api_samr_create_user: mismatch between trust flags and $ termination\n"));
1946 pdb_free_sam(&sam_pass);
1947 return NT_STATUS_UNSUCCESSFUL;
1952 * we can't check both the ending $ and the acb_info.
1954 * UserManager creates trust accounts (ending in $,
1955 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
1958 if (account[strlen(account)-1] == '$')
1959 pstrcpy(add_script, lp_addmachine_script());
1961 pstrcpy(add_script, lp_adduser_script());
1965 all_string_sub(add_script, "%u", account, sizeof(account));
1966 add_ret = smbrun(add_script,NULL);
1967 DEBUG(3,("_api_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
1970 pw = getpwnam_alloc(account);
1973 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sam_pass, pw))) {
1977 passwd_free(&pw); /* done with this now */
1979 DEBUG(3,("attempting to create non-unix account %s\n", account));
1981 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sam_pass))) {
1985 if (!pdb_set_username(sam_pass, account)) {
1986 pdb_free_sam(&sam_pass);
1987 return NT_STATUS_NO_MEMORY;
1991 pdb_set_acct_ctrl(sam_pass, acb_info);
1993 if (!pdb_add_sam_account(sam_pass)) {
1994 pdb_free_sam(&sam_pass);
1995 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
1997 return NT_STATUS_ACCESS_DENIED;
2000 pdb_reset_sam(sam_pass);
2002 if (!pdb_getsampwnam(sam_pass, account)) {
2003 pdb_free_sam(&sam_pass);
2004 DEBUG(0, ("could not find user/computer %s just added to passdb?!?\n",
2006 return NT_STATUS_ACCESS_DENIED;
2009 /* Get the domain SID stored in the domain policy */
2010 if(!get_lsa_policy_samr_sid(p, &dom_pol, &sid)) {
2011 pdb_free_sam(&sam_pass);
2012 return NT_STATUS_INVALID_HANDLE;
2015 /* append the user's RID to it */
2016 if(!sid_append_rid(&sid, pdb_get_user_rid(sam_pass) )) {
2017 pdb_free_sam(&sam_pass);
2018 return NT_STATUS_NO_SUCH_USER;
2021 /* associate the user's SID with the new handle. */
2022 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2023 pdb_free_sam(&sam_pass);
2024 return NT_STATUS_NO_MEMORY;
2030 /* get a (unique) handle. open a policy on it. */
2031 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2032 pdb_free_sam(&sam_pass);
2033 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2036 r_u->user_rid=pdb_get_user_rid(sam_pass);
2037 r_u->unknown_0 = 0x000703ff;
2039 pdb_free_sam(&sam_pass);
2041 return NT_STATUS_OK;
2044 /*******************************************************************
2045 samr_reply_connect_anon
2046 ********************************************************************/
2048 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2050 struct samr_info *info = NULL;
2052 /* set up the SAMR connect_anon response */
2054 r_u->status = NT_STATUS_OK;
2056 /* associate the user's SID with the new handle. */
2057 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2058 return NT_STATUS_NO_MEMORY;
2060 info->status = q_u->unknown_0;
2062 /* get a (unique) handle. open a policy on it. */
2063 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2064 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2069 /*******************************************************************
2071 ********************************************************************/
2073 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2075 struct samr_info *info = NULL;
2077 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2079 r_u->status = NT_STATUS_OK;
2081 /* associate the user's SID with the new handle. */
2082 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2083 return NT_STATUS_NO_MEMORY;
2085 info->status = q_u->access_mask;
2087 /* get a (unique) handle. open a policy on it. */
2088 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2089 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2091 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2096 /**********************************************************************
2097 api_samr_lookup_domain
2098 **********************************************************************/
2100 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2102 r_u->status = NT_STATUS_OK;
2104 if (!find_policy_by_hnd(p, &q_u->connect_pol, NULL))
2105 return NT_STATUS_INVALID_HANDLE;
2107 /* assume the domain name sent is our global_myname and
2108 send global_sam_sid */
2109 init_samr_r_lookup_domain(r_u, &global_sam_sid, r_u->status);
2114 /******************************************************************
2115 makes a SAMR_R_ENUM_DOMAINS structure.
2116 ********************************************************************/
2118 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2119 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2125 DEBUG(5, ("make_enum_domains\n"));
2128 *pp_uni_name = NULL;
2130 if (num_sam_entries == 0)
2133 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2134 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2136 if (sam == NULL || uni_name == NULL)
2139 for (i = 0; i < num_sam_entries; i++) {
2140 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
2142 init_sam_entry(&sam[i], len, 0);
2143 init_unistr2(&uni_name[i], doms[i], len);
2147 *pp_uni_name = uni_name;
2152 /**********************************************************************
2153 api_samr_enum_domains
2154 **********************************************************************/
2156 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2158 uint32 num_entries = 2;
2161 r_u->status = NT_STATUS_OK;
2163 fstrcpy(dom[0],global_myworkgroup);
2164 fstrcpy(dom[1],"Builtin");
2166 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2167 return NT_STATUS_NO_MEMORY;
2169 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2174 /*******************************************************************
2176 ********************************************************************/
2178 NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2181 POLICY_HND domain_pol = q_u->dom_pol;
2182 uint32 alias_rid = q_u->rid_alias;
2183 POLICY_HND *alias_pol = &r_u->pol;
2184 struct samr_info *info = NULL;
2186 r_u->status = NT_STATUS_OK;
2188 /* get the domain policy. */
2189 if (!find_policy_by_hnd(p, &domain_pol, NULL))
2190 return NT_STATUS_INVALID_HANDLE;
2192 /* Get the domain SID stored in the domain policy */
2193 if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
2194 return NT_STATUS_INVALID_HANDLE;
2196 /* append the alias' RID to it */
2197 if(!sid_append_rid(&sid, alias_rid))
2198 return NT_STATUS_NO_SUCH_USER;
2201 * we should check if the rid really exist !!!
2205 /* associate the user's SID with the new handle. */
2206 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2207 return NT_STATUS_NO_MEMORY;
2209 /* get a (unique) handle. open a policy on it. */
2210 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2211 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2216 /*******************************************************************
2218 ********************************************************************/
2220 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid)
2222 SAM_ACCOUNT *pwd =NULL;
2227 ret = pdb_getsampwrid(pwd, rid);
2235 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2240 if (!pdb_set_acct_ctrl(pwd, id10->acb_info)) {
2245 if(!pdb_update_sam_account(pwd)) {
2255 /*******************************************************************
2257 ********************************************************************/
2259 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, uint32 rid)
2261 SAM_ACCOUNT *pwd = NULL;
2265 if(!pdb_getsampwrid(pwd, rid)) {
2271 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2276 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd)) {
2280 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd)) {
2284 if (!pdb_set_pass_changed_now (pwd)) {
2289 if(!pdb_update_sam_account(pwd)) {
2298 /*******************************************************************
2300 ********************************************************************/
2302 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, uint32 rid)
2304 SAM_ACCOUNT *pwd = NULL;
2307 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2313 if (!pdb_getsampwrid(pwd, rid)) {
2318 copy_id21_to_sam_passwd(pwd, id21);
2321 * The funny part about the previous two calls is
2322 * that pwd still has the password hashes from the
2323 * passdb entry. These have not been updated from
2324 * id21. I don't know if they need to be set. --jerry
2327 /* write the change out */
2328 if(!pdb_update_sam_account(pwd)) {
2338 /*******************************************************************
2340 ********************************************************************/
2342 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
2344 SAM_ACCOUNT *pwd = NULL;
2345 pstring plaintext_buf;
2350 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2356 if (!pdb_getsampwrid(pwd, rid)) {
2361 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2362 pdb_get_username(pwd)));
2364 acct_ctrl = pdb_get_acct_ctrl(pwd);
2366 copy_id23_to_sam_passwd(pwd, id23);
2368 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
2373 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2378 /* if it's a trust account, don't update /etc/passwd */
2379 if ( (!IS_SAM_UNIX_USER(pwd)) ||
2380 ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2381 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2382 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2383 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2385 /* update the UNIX password */
2386 if (lp_unix_password_sync() )
2387 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2393 ZERO_STRUCT(plaintext_buf);
2395 if(!pdb_update_sam_account(pwd)) {
2405 /*******************************************************************
2407 ********************************************************************/
2409 static BOOL set_user_info_pw(char *pass, uint32 rid)
2411 SAM_ACCOUNT *pwd = NULL;
2413 pstring plaintext_buf;
2418 if (!pdb_getsampwrid(pwd, rid)) {
2423 DEBUG(5, ("Attempting administrator password change for user %s\n",
2424 pdb_get_username(pwd)));
2426 acct_ctrl = pdb_get_acct_ctrl(pwd);
2428 ZERO_STRUCT(plaintext_buf);
2430 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) {
2435 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2440 /* if it's a trust account, don't update /etc/passwd */
2441 if ( (!IS_SAM_UNIX_USER(pwd)) ||
2442 ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2443 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2444 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2445 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2447 /* update the UNIX password */
2448 if (lp_unix_password_sync()) {
2449 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2456 ZERO_STRUCT(plaintext_buf);
2458 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2460 /* update the SAMBA password */
2461 if(!pdb_update_sam_account(pwd)) {
2471 /*******************************************************************
2472 samr_reply_set_userinfo
2473 ********************************************************************/
2475 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2479 POLICY_HND *pol = &q_u->pol;
2480 uint16 switch_value = q_u->switch_value;
2481 SAM_USERINFO_CTR *ctr = q_u->ctr;
2483 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2485 r_u->status = NT_STATUS_OK;
2487 /* find the policy handle. open a policy on it. */
2488 if (!get_lsa_policy_samr_sid(p, pol, &sid))
2489 return NT_STATUS_INVALID_HANDLE;
2491 sid_split_rid(&sid, &rid);
2493 DEBUG(5, ("_samr_set_userinfo: rid:0x%x, level:%d\n", rid, switch_value));
2496 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2497 return NT_STATUS_INVALID_INFO_CLASS;
2500 /* ok! user info levels (lots: see MSDEV help), off we go... */
2501 switch (switch_value) {
2503 if (!set_user_info_12(ctr->info.id12, rid))
2504 return NT_STATUS_ACCESS_DENIED;
2508 SamOEMhash(ctr->info.id24->pass, p->session_key, 516);
2510 dump_data(100, (char *)ctr->info.id24->pass, 516);
2512 if (!set_user_info_pw((char *)ctr->info.id24->pass, rid))
2513 return NT_STATUS_ACCESS_DENIED;
2519 * Currently we don't really know how to unmarshall
2520 * the level 25 struct, and the password encryption
2521 * is different. This is a placeholder for when we
2522 * do understand it. In the meantime just return INVALID
2523 * info level and W2K SP2 drops down to level 23... JRA.
2526 SamOEMhash(ctr->info.id25->pass, p->session_key, 532);
2528 dump_data(100, (char *)ctr->info.id25->pass, 532);
2530 if (!set_user_info_pw(ctr->info.id25->pass, rid))
2531 return NT_STATUS_ACCESS_DENIED;
2534 return NT_STATUS_INVALID_INFO_CLASS;
2537 SamOEMhash(ctr->info.id23->pass, p->session_key, 516);
2539 dump_data(100, (char *)ctr->info.id23->pass, 516);
2541 if (!set_user_info_23(ctr->info.id23, rid))
2542 return NT_STATUS_ACCESS_DENIED;
2546 return NT_STATUS_INVALID_INFO_CLASS;
2552 /*******************************************************************
2553 samr_reply_set_userinfo2
2554 ********************************************************************/
2556 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
2560 SAM_USERINFO_CTR *ctr = q_u->ctr;
2561 POLICY_HND *pol = &q_u->pol;
2562 uint16 switch_value = q_u->switch_value;
2564 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
2566 r_u->status = NT_STATUS_OK;
2568 /* find the policy handle. open a policy on it. */
2569 if (!get_lsa_policy_samr_sid(p, pol, &sid))
2570 return NT_STATUS_INVALID_HANDLE;
2572 sid_split_rid(&sid, &rid);
2574 DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid));
2577 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
2578 return NT_STATUS_INVALID_INFO_CLASS;
2581 switch_value=ctr->switch_value;
2583 /* ok! user info levels (lots: see MSDEV help), off we go... */
2584 switch (switch_value) {
2586 if (!set_user_info_21(ctr->info.id21, rid))
2587 return NT_STATUS_ACCESS_DENIED;
2590 if (!set_user_info_10(ctr->info.id10, rid))
2591 return NT_STATUS_ACCESS_DENIED;
2594 /* Used by AS/U JRA. */
2595 if (!set_user_info_12(ctr->info.id12, rid))
2596 return NT_STATUS_ACCESS_DENIED;
2599 return NT_STATUS_INVALID_INFO_CLASS;
2605 /*********************************************************************
2606 _samr_query_aliasmem
2607 *********************************************************************/
2609 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
2611 int num_groups = 0, tmp_num_groups=0;
2612 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
2613 struct samr_info *info = NULL;
2615 /* until i see a real useraliases query, we fack one up */
2617 /* I have seen one, JFM 2/12/2001 */
2619 * Explanation of what this call does:
2620 * for all the SID given in the request:
2621 * return a list of alias (local groups)
2622 * that have those SID as members.
2624 * and that's the alias in the domain specified
2625 * in the policy_handle
2627 * if the policy handle is on an incorrect sid
2628 * for example a user's sid
2629 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
2632 r_u->status = NT_STATUS_OK;
2634 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
2636 /* find the policy handle. open a policy on it. */
2637 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
2638 return NT_STATUS_INVALID_HANDLE;
2640 if (!sid_check_is_domain(&info->sid) &&
2641 !sid_check_is_builtin(&info->sid))
2642 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2645 for (i=0; i<q_u->num_sids1; i++) {
2647 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
2650 * if there is an error, we just continue as
2651 * it can be an unfound user or group
2653 if (NT_STATUS_IS_ERR(r_u->status)) {
2654 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
2658 if (tmp_num_groups==0) {
2659 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
2663 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
2664 if (new_rids==NULL) {
2665 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
2666 return NT_STATUS_NO_MEMORY;
2670 for (j=0; j<tmp_num_groups; j++)
2671 rids[j+num_groups]=tmp_rids[j];
2673 safe_free(tmp_rids);
2675 num_groups+=tmp_num_groups;
2678 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
2679 return NT_STATUS_OK;
2682 /*********************************************************************
2683 _samr_query_aliasmem
2684 *********************************************************************/
2686 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
2698 fstring alias_sid_str;
2702 /* find the policy handle. open a policy on it. */
2703 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid))
2704 return NT_STATUS_INVALID_HANDLE;
2706 sid_copy(&als_sid, &alias_sid);
2707 sid_to_string(alias_sid_str, &alias_sid);
2708 sid_split_rid(&alias_sid, &alias_rid);
2710 DEBUG(10, ("sid is %s\n", alias_sid_str));
2712 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
2713 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
2714 if(!get_local_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
2715 return NT_STATUS_NO_SUCH_ALIAS;
2717 if (sid_equal(&alias_sid, &global_sam_sid)) {
2718 DEBUG(10, ("lookup on Server SID\n"));
2719 if(!get_local_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
2720 return NT_STATUS_NO_SUCH_ALIAS;
2724 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
2725 return NT_STATUS_NO_SUCH_ALIAS;
2727 DEBUG(10, ("sid is %s\n", alias_sid_str));
2728 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
2729 if (num_uids!=0 && sid == NULL)
2730 return NT_STATUS_NO_MEMORY;
2732 for (i = 0; i < num_uids; i++) {
2733 sid_copy(&temp_sid, &global_sam_sid);
2734 sid_append_rid(&temp_sid, pdb_uid_to_user_rid(uid[i]));
2736 init_dom_sid2(&sid[i], &temp_sid);
2739 DEBUG(10, ("sid is %s\n", alias_sid_str));
2740 init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
2742 return NT_STATUS_OK;
2745 /*********************************************************************
2746 _samr_query_groupmem
2747 *********************************************************************/
2749 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
2755 fstring group_sid_str;
2764 /* find the policy handle. open a policy on it. */
2765 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid))
2766 return NT_STATUS_INVALID_HANDLE;
2768 /* todo: change to use sid_compare_front */
2770 sid_split_rid(&group_sid, &group_rid);
2771 sid_to_string(group_sid_str, &group_sid);
2772 DEBUG(10, ("sid is %s\n", group_sid_str));
2774 /* can we get a query for an SID outside our domain ? */
2775 if (!sid_equal(&group_sid, &global_sam_sid))
2776 return NT_STATUS_NO_SUCH_GROUP;
2778 sid_append_rid(&group_sid, group_rid);
2779 DEBUG(10, ("lookup on Domain SID\n"));
2781 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
2782 return NT_STATUS_NO_SUCH_GROUP;
2784 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
2785 return NT_STATUS_NO_SUCH_GROUP;
2787 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
2788 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
2790 if (num_uids!=0 && (rid==NULL || attr==NULL))
2791 return NT_STATUS_NO_MEMORY;
2793 for (i=0; i<num_uids; i++) {
2794 rid[i]=pdb_uid_to_user_rid(uid[i]);
2795 attr[i] = SID_NAME_USER;
2798 init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
2800 return NT_STATUS_OK;
2803 /*********************************************************************
2805 *********************************************************************/
2807 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
2810 fstring alias_sid_str;
2818 /* Find the policy handle. Open a policy on it. */
2819 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid))
2820 return NT_STATUS_INVALID_HANDLE;
2822 sid_to_string(alias_sid_str, &alias_sid);
2823 DEBUG(10, ("sid is %s\n", alias_sid_str));
2825 if (sid_compare(&alias_sid, &global_sam_sid)>0) {
2826 DEBUG(10, ("adding member on Server SID\n"));
2827 if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
2828 return NT_STATUS_NO_SUCH_ALIAS;
2831 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
2832 DEBUG(10, ("adding member on BUILTIN SID\n"));
2833 if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
2834 return NT_STATUS_NO_SUCH_ALIAS;
2837 return NT_STATUS_NO_SUCH_ALIAS;
2840 sid_split_rid(&q_u->sid.sid, &rid);
2841 uid=pdb_user_rid_to_uid(rid);
2843 if ((pwd=getpwuid(uid)) == NULL)
2844 return NT_STATUS_NO_SUCH_USER;
2846 if ((grp=getgrgid(map.gid)) == NULL)
2847 return NT_STATUS_NO_SUCH_ALIAS;
2849 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
2850 fstrcpy(grp_name, grp->gr_name);
2852 /* if the user is already in the group */
2853 if(user_in_group_list(pwd->pw_name, grp_name))
2854 return NT_STATUS_MEMBER_IN_ALIAS;
2857 * ok, the group exist, the user exist, the user is not in the group,
2858 * we can (finally) add it to the group !
2860 smb_add_user_group(grp_name, pwd->pw_name);
2862 /* check if the user has been added then ... */
2863 if(!user_in_group_list(pwd->pw_name, grp_name))
2864 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
2866 return NT_STATUS_OK;
2869 /*********************************************************************
2871 *********************************************************************/
2873 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
2876 fstring alias_sid_str;
2881 SAM_ACCOUNT *sam_pass=NULL;
2883 /* Find the policy handle. Open a policy on it. */
2884 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid))
2885 return NT_STATUS_INVALID_HANDLE;
2887 sid_to_string(alias_sid_str, &alias_sid);
2888 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
2890 if (!sid_check_is_in_our_domain(&alias_sid) &&
2891 !sid_check_is_in_builtin(&alias_sid)) {
2892 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
2893 return NT_STATUS_NO_SUCH_ALIAS;
2896 if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
2897 return NT_STATUS_NO_SUCH_ALIAS;
2899 if ((grp=getgrgid(map.gid)) == NULL)
2900 return NT_STATUS_NO_SUCH_ALIAS;
2902 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
2903 fstrcpy(grp_name, grp->gr_name);
2905 sid_peek_rid(&q_u->sid.sid, &rid);
2907 /* check if the user exists before trying to remove it from the group */
2908 pdb_init_sam(&sam_pass);
2909 if(!pdb_getsampwrid(sam_pass, rid)) {
2910 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
2911 pdb_free_sam(&sam_pass);
2912 return NT_STATUS_NO_SUCH_USER;
2915 /* if the user is not in the group */
2916 if(!user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
2917 pdb_free_sam(&sam_pass);
2918 return NT_STATUS_MEMBER_IN_ALIAS;
2921 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
2923 /* check if the user has been removed then ... */
2924 if(user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
2925 pdb_free_sam(&sam_pass);
2926 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
2929 pdb_free_sam(&sam_pass);
2930 return NT_STATUS_OK;
2933 /*********************************************************************
2935 *********************************************************************/
2937 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
2940 fstring group_sid_str;
2946 /* Find the policy handle. Open a policy on it. */
2947 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid))
2948 return NT_STATUS_INVALID_HANDLE;
2950 sid_to_string(group_sid_str, &group_sid);
2951 DEBUG(10, ("sid is %s\n", group_sid_str));
2953 if (sid_compare(&group_sid, &global_sam_sid)<=0)
2954 return NT_STATUS_NO_SUCH_GROUP;
2956 DEBUG(10, ("lookup on Domain SID\n"));
2958 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
2959 return NT_STATUS_NO_SUCH_GROUP;
2961 if ((pwd=getpwuid(pdb_user_rid_to_uid(q_u->rid))) ==NULL)
2962 return NT_STATUS_NO_SUCH_USER;
2964 if ((grp=getgrgid(map.gid)) == NULL)
2965 return NT_STATUS_NO_SUCH_GROUP;
2967 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
2968 fstrcpy(grp_name, grp->gr_name);
2970 /* if the user is already in the group */
2971 if(user_in_group_list(pwd->pw_name, grp_name))
2972 return NT_STATUS_MEMBER_IN_GROUP;
2975 * ok, the group exist, the user exist, the user is not in the group,
2977 * we can (finally) add it to the group !
2980 smb_add_user_group(grp_name, pwd->pw_name);
2982 /* check if the user has been added then ... */
2983 if(!user_in_group_list(pwd->pw_name, grp_name))
2984 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
2986 return NT_STATUS_OK;
2989 /*********************************************************************
2991 *********************************************************************/
2993 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
2996 SAM_ACCOUNT *sam_pass=NULL;
3003 * delete the group member named q_u->rid
3004 * who is a member of the sid associated with the handle
3005 * the rid is a user's rid as the group is a domain group.
3008 /* Find the policy handle. Open a policy on it. */
3009 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid))
3010 return NT_STATUS_INVALID_HANDLE;
3012 if(!sid_check_is_in_our_domain(&group_sid))
3013 return NT_STATUS_NO_SUCH_GROUP;
3017 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3018 return NT_STATUS_NO_SUCH_GROUP;
3020 if ((grp=getgrgid(map.gid)) == NULL)
3021 return NT_STATUS_NO_SUCH_GROUP;
3023 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3024 fstrcpy(grp_name, grp->gr_name);
3026 /* check if the user exists before trying to remove it from the group */
3027 pdb_init_sam(&sam_pass);
3028 if(!pdb_getsampwrid(sam_pass, rid)) {
3029 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3030 pdb_free_sam(&sam_pass);
3031 return NT_STATUS_NO_SUCH_USER;
3034 /* if the user is not in the group */
3035 if(!user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
3036 pdb_free_sam(&sam_pass);
3037 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3040 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3042 /* check if the user has been removed then ... */
3043 if(user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
3044 pdb_free_sam(&sam_pass);
3045 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3048 pdb_free_sam(&sam_pass);
3049 return NT_STATUS_OK;
3053 /*********************************************************************
3054 _samr_delete_dom_user
3055 *********************************************************************/
3057 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3060 SAM_ACCOUNT *sam_pass=NULL;
3063 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3065 /* Find the policy handle. Open a policy on it. */
3066 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid))
3067 return NT_STATUS_INVALID_HANDLE;
3069 if (!sid_check_is_in_our_domain(&user_sid))
3070 return NT_STATUS_CANNOT_DELETE;
3072 sid_peek_rid(&user_sid, &rid);
3074 /* check if the user exists before trying to delete */
3075 pdb_init_sam(&sam_pass);
3076 if(!pdb_getsampwrid(sam_pass, rid)) {
3077 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3078 pdb_free_sam(&sam_pass);
3079 return NT_STATUS_NO_SUCH_USER;
3082 /* delete the unix side */
3084 * note: we don't check if the delete really happened
3085 * as the script is not necessary present
3086 * and maybe the sysadmin doesn't want to delete the unix side
3088 smb_delete_user(pdb_get_username(sam_pass));
3090 /* and delete the samba side */
3091 if (!pdb_delete_sam_account(sam_pass)) {
3092 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3093 pdb_free_sam(&sam_pass);
3094 return NT_STATUS_CANNOT_DELETE;
3097 pdb_free_sam(&sam_pass);
3099 if (!close_policy_hnd(p, &q_u->user_pol))
3100 return NT_STATUS_OBJECT_NAME_INVALID;
3102 return NT_STATUS_OK;
3105 /*********************************************************************
3106 _samr_delete_dom_group
3107 *********************************************************************/
3109 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3114 fstring group_sid_str;
3119 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3121 /* Find the policy handle. Open a policy on it. */
3122 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid))
3123 return NT_STATUS_INVALID_HANDLE;
3125 sid_copy(&dom_sid, &group_sid);
3126 sid_to_string(group_sid_str, &dom_sid);
3127 sid_split_rid(&dom_sid, &group_rid);
3129 DEBUG(10, ("sid is %s\n", group_sid_str));
3131 /* we check if it's our SID before deleting */
3132 if (!sid_equal(&dom_sid, &global_sam_sid))
3133 return NT_STATUS_NO_SUCH_GROUP;
3135 DEBUG(10, ("lookup on Domain SID\n"));
3137 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3138 return NT_STATUS_NO_SUCH_GROUP;
3142 /* check if group really exists */
3143 if ( (grp=getgrgid(gid)) == NULL)
3144 return NT_STATUS_NO_SUCH_GROUP;
3146 /* we can delete the UNIX group */
3147 smb_delete_group(grp->gr_name);
3149 /* check if the group has been successfully deleted */
3150 if ( (grp=getgrgid(gid)) != NULL)
3151 return NT_STATUS_ACCESS_DENIED;
3153 if(!group_map_remove(group_sid))
3154 return NT_STATUS_ACCESS_DENIED;
3156 if (!close_policy_hnd(p, &q_u->group_pol))
3157 return NT_STATUS_OBJECT_NAME_INVALID;
3159 return NT_STATUS_OK;
3162 /*********************************************************************
3163 _samr_delete_dom_alias
3164 *********************************************************************/
3166 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3171 fstring alias_sid_str;
3176 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3178 /* Find the policy handle. Open a policy on it. */
3179 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid))
3180 return NT_STATUS_INVALID_HANDLE;
3182 sid_copy(&dom_sid, &alias_sid);
3183 sid_to_string(alias_sid_str, &dom_sid);
3184 sid_split_rid(&dom_sid, &alias_rid);
3186 DEBUG(10, ("sid is %s\n", alias_sid_str));
3188 /* we check if it's our SID before deleting */
3189 if (!sid_equal(&dom_sid, &global_sam_sid))
3190 return NT_STATUS_NO_SUCH_ALIAS;
3192 DEBUG(10, ("lookup on Local SID\n"));
3194 if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3195 return NT_STATUS_NO_SUCH_ALIAS;
3199 /* check if group really exists */
3200 if ( (grp=getgrgid(gid)) == NULL)
3201 return NT_STATUS_NO_SUCH_ALIAS;
3203 /* we can delete the UNIX group */
3204 smb_delete_group(grp->gr_name);
3206 /* check if the group has been successfully deleted */
3207 if ( (grp=getgrgid(gid)) != NULL)
3208 return NT_STATUS_ACCESS_DENIED;
3210 /* don't check if we removed it as it could be an un-mapped group */
3211 group_map_remove(alias_sid);
3213 if (!close_policy_hnd(p, &q_u->alias_pol))
3214 return NT_STATUS_OBJECT_NAME_INVALID;
3216 return NT_STATUS_OK;
3219 /*********************************************************************
3220 _samr_create_dom_group
3221 *********************************************************************/
3223 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3230 struct samr_info *info;
3231 PRIVILEGE_SET priv_set;
3233 init_privilege(&priv_set);
3235 /* Find the policy handle. Open a policy on it. */
3236 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid))
3237 return NT_STATUS_INVALID_HANDLE;
3239 if (!sid_equal(&dom_sid, &global_sam_sid))
3240 return NT_STATUS_ACCESS_DENIED;
3242 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3244 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3246 /* check if group already exist */
3247 if ((grp=getgrnam(name)) != NULL)
3248 return NT_STATUS_GROUP_EXISTS;
3250 /* we can create the UNIX group */
3251 smb_create_group(name);
3253 /* check if the group has been successfully created */
3254 if ((grp=getgrnam(name)) == NULL)
3255 return NT_STATUS_ACCESS_DENIED;
3257 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3259 /* add the group to the mapping table */
3260 sid_copy(&info_sid, &global_sam_sid);
3261 sid_append_rid(&info_sid, r_u->rid);
3262 sid_to_string(sid_string, &info_sid);
3264 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
3265 return NT_STATUS_ACCESS_DENIED;
3267 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3268 return NT_STATUS_NO_MEMORY;
3270 /* get a (unique) handle. open a policy on it. */
3271 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3272 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3274 return NT_STATUS_OK;
3277 /*********************************************************************
3278 _samr_create_dom_alias
3279 *********************************************************************/
3281 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3288 struct samr_info *info;
3289 PRIVILEGE_SET priv_set;
3291 init_privilege(&priv_set);
3293 /* Find the policy handle. Open a policy on it. */
3294 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid))
3295 return NT_STATUS_INVALID_HANDLE;
3297 if (!sid_equal(&dom_sid, &global_sam_sid))
3298 return NT_STATUS_ACCESS_DENIED;
3300 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3302 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3304 /* check if group already exists */
3305 if ( (grp=getgrnam(name)) != NULL)
3306 return NT_STATUS_GROUP_EXISTS;
3308 /* we can create the UNIX group */
3309 smb_create_group(name);
3311 /* check if the group has been successfully created */
3312 if ((grp=getgrnam(name)) == NULL)
3313 return NT_STATUS_ACCESS_DENIED;
3315 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3317 sid_copy(&info_sid, &global_sam_sid);
3318 sid_append_rid(&info_sid, r_u->rid);
3319 sid_to_string(sid_string, &info_sid);
3321 /* add the group to the mapping table */
3322 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
3323 return NT_STATUS_ACCESS_DENIED;
3325 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3326 return NT_STATUS_NO_MEMORY;
3328 /* get a (unique) handle. open a policy on it. */
3329 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
3330 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3332 return NT_STATUS_OK;
3335 /*********************************************************************
3336 _samr_query_groupinfo
3338 sends the name/comment pair of a domain group
3339 level 1 send also the number of users of that group
3340 *********************************************************************/
3342 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
3348 GROUP_INFO_CTR *ctr;
3350 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid))
3351 return NT_STATUS_INVALID_HANDLE;
3353 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3354 return NT_STATUS_INVALID_HANDLE;
3356 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
3358 return NT_STATUS_NO_MEMORY;
3360 switch (q_u->switch_level) {
3362 ctr->switch_value1 = 1;
3363 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3364 return NT_STATUS_NO_SUCH_GROUP;
3365 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
3369 ctr->switch_value1 = 3;
3370 init_samr_group_info3(&ctr->group.info3);
3373 ctr->switch_value1 = 4;
3374 init_samr_group_info4(&ctr->group.info4, map.comment);
3377 return NT_STATUS_INVALID_INFO_CLASS;
3380 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
3382 return NT_STATUS_OK;
3385 /*********************************************************************
3388 update a domain group's comment.
3389 *********************************************************************/
3391 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
3395 GROUP_INFO_CTR *ctr;
3397 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid))
3398 return NT_STATUS_INVALID_HANDLE;
3400 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
3401 return NT_STATUS_NO_SUCH_GROUP;
3405 switch (ctr->switch_value1) {
3407 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
3410 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
3413 free_privilege(&map.priv_set);
3414 return NT_STATUS_INVALID_INFO_CLASS;
3417 if(!add_mapping_entry(&map, TDB_REPLACE)) {
3418 free_privilege(&map.priv_set);
3419 return NT_STATUS_NO_SUCH_GROUP;
3422 free_privilege(&map.priv_set);
3424 return NT_STATUS_OK;
3427 /*********************************************************************
3430 update a domain group's comment.
3431 *********************************************************************/
3433 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
3437 ALIAS_INFO_CTR *ctr;
3439 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid))
3440 return NT_STATUS_INVALID_HANDLE;
3442 if (!get_local_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
3443 return NT_STATUS_NO_SUCH_GROUP;
3447 switch (ctr->switch_value1) {
3449 unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
3452 free_privilege(&map.priv_set);
3453 return NT_STATUS_INVALID_INFO_CLASS;
3456 if(!add_mapping_entry(&map, TDB_REPLACE)) {
3457 free_privilege(&map.priv_set);
3458 return NT_STATUS_NO_SUCH_GROUP;
3461 free_privilege(&map.priv_set);
3463 return NT_STATUS_OK;
3466 /*********************************************************************
3467 _samr_get_dom_pwinfo
3468 *********************************************************************/
3470 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
3472 /* Actually, returning zeros here works quite well :-). */
3473 return NT_STATUS_OK;
3476 /*********************************************************************
3478 *********************************************************************/
3480 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
3485 struct samr_info *info;
3488 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid))
3489 return NT_STATUS_INVALID_HANDLE;
3491 /* this should not be hard-coded like this */
3492 if (!sid_equal(&sid, &global_sam_sid))
3493 return NT_STATUS_ACCESS_DENIED;
3495 sid_copy(&info_sid, &global_sam_sid);
3496 sid_append_rid(&info_sid, q_u->rid_group);
3497 sid_to_string(sid_string, &info_sid);
3499 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3500 return NT_STATUS_NO_MEMORY;
3502 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
3504 /* check if that group really exists */
3505 if (!get_domain_group_from_sid(info->sid, &map, MAPPING_WITHOUT_PRIV))
3506 return NT_STATUS_NO_SUCH_GROUP;
3508 /* get a (unique) handle. open a policy on it. */
3509 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3510 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3512 return NT_STATUS_OK;
3515 /*********************************************************************
3517 *********************************************************************/
3519 NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
3521 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
3522 return NT_STATUS_NOT_IMPLEMENTED;
3525 /*******************************************************************
3527 ********************************************************************/
3529 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
3531 struct samr_info *info = NULL;
3533 uint32 min_pass_len,pass_hist,flag;
3534 time_t u_expire, u_min_age;
3535 NTTIME nt_expire, nt_min_age;
3537 time_t u_lock_duration, u_reset_time;
3538 NTTIME nt_lock_duration, nt_reset_time;
3544 uint32 num_users=0, num_groups=0, num_aliases=0;
3546 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
3547 return NT_STATUS_NO_MEMORY;
3551 r_u->status = NT_STATUS_OK;
3553 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
3555 /* find the policy handle. open a policy on it. */
3556 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
3557 return NT_STATUS_INVALID_HANDLE;
3559 switch (q_u->switch_value) {
3561 account_policy_get(AP_MIN_PASSWORD_LEN, &min_pass_len);
3562 account_policy_get(AP_PASSWORD_HISTORY, &pass_hist);
3563 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &flag);
3564 account_policy_get(AP_MAX_PASSWORD_AGE, (int *)&u_expire);
3565 account_policy_get(AP_MIN_PASSWORD_AGE, (int *)&u_min_age);
3567 unix_to_nt_time_abs(&nt_expire, u_expire);
3568 unix_to_nt_time_abs(&nt_min_age, u_min_age);
3570 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
3571 flag, nt_expire, nt_min_age);
3575 r_u->status=load_sampwd_entries(info, ACB_NORMAL);
3577 if (NT_STATUS_IS_ERR(r_u->status)) {
3578 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
3581 num_users=info->disp_info.num_user_account;
3584 r_u->status=load_group_domain_entries(info, &global_sam_sid);
3585 if (NT_STATUS_IS_ERR(r_u->status)) {
3586 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
3589 num_groups=info->disp_info.num_group_account;
3592 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
3593 init_unk_info2(&ctr->info.inf2, global_myworkgroup, global_myname, (uint32) time(NULL),
3594 num_users, num_groups, num_aliases);
3597 account_policy_get(AP_TIME_TO_LOGOUT, (int *)&u_logout);
3598 unix_to_nt_time_abs(&nt_logout, u_logout);
3600 init_unk_info3(&ctr->info.inf3, nt_logout);
3603 init_unk_info5(&ctr->info.inf5, global_myname);
3606 init_unk_info6(&ctr->info.inf6);
3609 init_unk_info7(&ctr->info.inf7);
3612 account_policy_get(AP_LOCK_ACCOUNT_DURATION, (int *)&u_lock_duration);
3613 account_policy_get(AP_RESET_COUNT_TIME, (int *)&u_reset_time);
3614 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &lockout);
3616 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
3617 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
3619 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
3622 return NT_STATUS_INVALID_INFO_CLASS;
3625 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
3627 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
3632 /*******************************************************************
3634 ********************************************************************/
3636 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
3638 time_t u_expire, u_min_age;
3640 time_t u_lock_duration, u_reset_time;
3642 r_u->status = NT_STATUS_OK;
3644 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
3646 /* find the policy handle. open a policy on it. */
3647 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
3648 return NT_STATUS_INVALID_HANDLE;
3650 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
3652 switch (q_u->switch_value) {
3654 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
3655 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
3657 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
3658 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
3659 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
3660 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
3661 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
3666 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
3667 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
3676 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
3677 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count);
3679 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
3680 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
3681 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
3684 return NT_STATUS_INVALID_INFO_CLASS;
3687 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
3689 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));