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.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 * This is the implementation of the SAMR code.
32 extern fstring global_myworkgroup;
33 extern pstring global_myname;
34 extern DOM_SID global_sam_sid;
35 extern DOM_SID global_sid_Builtin;
37 extern rid_name domain_group_rids[];
38 extern rid_name domain_alias_rids[];
39 extern rid_name builtin_alias_rids[];
42 /* for use by the \PIPE\samr policy */
44 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
47 /*******************************************************************
48 Function to free the per handle data.
49 ********************************************************************/
51 static void free_samr_info(void *ptr)
56 /*******************************************************************
57 Ensure password info is never given out. Paranioa... JRA.
58 ********************************************************************/
60 static void samr_clear_passwd_fields( SAM_USER_INFO_21 *pass, int num_entries)
67 for (i = 0; i < num_entries; i++) {
68 memset(&pass[i].lm_pwd, '\0', sizeof(pass[i].lm_pwd));
69 memset(&pass[i].nt_pwd, '\0', sizeof(pass[i].nt_pwd));
73 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
78 if (sam_pass->lm_pw) memset(sam_pass->lm_pw, '\0', 16);
79 if (sam_pass->nt_pw) memset(sam_pass->nt_pw, '\0', 16);
82 /*******************************************************************
83 This next function should be replaced with something that
84 dynamically returns the correct user info..... JRA.
85 ********************************************************************/
87 static NTSTATUS get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx,
88 int *total_entries, int *num_entries,
89 int max_num_entries, uint16 acb_mask)
91 SAM_ACCOUNT *pwd = NULL;
92 BOOL not_finished = True;
98 return NT_STATUS_NO_MEMORY;
102 if (!pdb_setsampwent(False)) {
103 DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n"));
105 return NT_STATUS_ACCESS_DENIED;
108 while (((not_finished = pdb_getsampwent(pwd)) != False)
109 && (*num_entries) < max_num_entries)
117 /* skip the requested number of entries.
118 not very efficient, but hey... */
123 user_name_len = strlen(pdb_get_username(pwd))+1;
124 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pdb_get_username(pwd), user_name_len);
125 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
126 pw_buf[(*num_entries)].user_rid = pwd->user_rid;
127 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
129 /* Now check if the NT compatible password is available. */
130 if (pdb_get_nt_passwd(pwd))
131 memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
133 pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
135 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
136 (*num_entries), pdb_get_username(pwd), pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd) ));
138 if (acb_mask == 0 || (pwd->acct_ctrl & acb_mask)) {
139 DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
142 DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
155 return STATUS_MORE_ENTRIES;
160 static NTSTATUS jf_get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx,
161 int *total_entries, uint32 *num_entries,
162 int max_num_entries, uint16 acb_mask)
164 SAM_ACCOUNT *pwd = NULL;
165 BOOL not_finished = True;
171 return NT_STATUS_NO_MEMORY;
173 DEBUG(10,("jf_get_sampwd_entries: start index:%d, max entries:%d, mask:%d\n",
174 start_idx, max_num_entries, acb_mask));
176 if (!pdb_setsampwent(False)) {
177 DEBUG(0, ("jf_get_sampwd_entries: Unable to open passdb.\n"));
178 return NT_STATUS_ACCESS_DENIED;
183 while (((not_finished = pdb_getsampwent(pwd)) != False) && (*num_entries) < max_num_entries) {
187 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
193 /* skip the requested number of entries.
194 not very efficient, but hey...
201 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
203 user_name_len = strlen(pdb_get_username(pwd));
204 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pdb_get_username(pwd), user_name_len);
205 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
207 full_name_len = strlen(pdb_get_fullname(pwd));
208 init_unistr2(&pw_buf[(*num_entries)].uni_full_name, pdb_get_fullname(pwd), full_name_len);
209 init_uni_hdr(&pw_buf[(*num_entries)].hdr_full_name, full_name_len);
211 pw_buf[(*num_entries)].user_rid = pdb_get_user_rid(pwd);
212 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
214 /* Now check if the NT compatible password is available. */
215 if (pdb_get_nt_passwd(pwd))
216 memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
218 pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
220 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x\n", (*num_entries),
221 pdb_get_username(pwd), pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd) ));
230 *total_entries = *num_entries;
235 return STATUS_MORE_ENTRIES;
240 #if 0 /* This function appears to be unused! */
242 /*******************************************************************
243 This function uses the username map file and tries to map a UNIX
244 user name to an DOS name. (Sort of the reverse of the
245 map_username() function.) Since more than one DOS name can map
246 to the UNIX name, to reverse the mapping you have to specify
247 which corresponding DOS name you want; that's where the name_idx
248 parameter comes in. Returns the string requested or NULL if it
249 fails or can't complete the request for any reason. This doesn't
250 handle group names (starting with '@') or names starting with
251 '+' or '&'. If they are encountered, they are skipped.
252 ********************************************************************/
254 static char *unmap_unixname(char *unix_user_name, int name_idx)
256 char *mapfile = lp_username_map();
261 if (!*unix_user_name) return NULL;
262 if (!*mapfile) return NULL;
264 lines = file_lines_load(mapfile, NULL);
266 DEBUG(0,("unmap_unixname: can't open username map %s\n", mapfile));
270 DEBUG(5,("unmap_unixname: scanning username map %s, index: %d\n", mapfile, name_idx));
272 for (i=0; lines[i]; i++) {
273 char *unixname = lines[i];
274 char *dosname = strchr_m(unixname,'=');
281 while (isspace(*unixname))
283 if ('!' == *unixname) {
285 while (*unixname && isspace(*unixname))
289 if (!*unixname || strchr_m("#;",*unixname))
292 if (strncmp(unixname, unix_user_name, strlen(unix_user_name)))
295 /* We have matched the UNIX user name */
297 while(next_token(&dosname, tok, LIST_SEP, sizeof(tok))) {
298 if (!strchr_m("@&+", *tok)) {
307 DEBUG(0,("unmap_unixname: index too high - not that many DOS names\n"));
308 file_lines_free(lines);
311 file_lines_free(lines);
316 DEBUG(0,("unmap_unixname: Couldn't find the UNIX user name\n"));
317 file_lines_free(lines);
321 #endif /* Unused function */
323 #if 0 /* This function seems to be not used anywhere! */
325 /*******************************************************************
326 This function sets up a list of users taken from the list of
327 users that UNIX knows about, as well as all the user names that
328 Samba maps to a valid UNIX user name. (This should work with
330 ********************************************************************/
332 static BOOL get_passwd_entries(SAM_USER_INFO_21 *pw_buf,
334 int *total_entries, int *num_entries,
338 static struct passwd *pwd = NULL;
339 static uint32 pw_rid;
340 static BOOL orig_done = False;
341 static int current_idx = 0;
342 static int mapped_idx = 0;
345 DEBUG(5, ("get_passwd_entries: retrieving a list of UNIX users\n"));
348 (*total_entries) = 0;
350 /* Skip all this stuff if we're in appliance mode */
352 if (lp_hide_local_users()) goto done;
354 if (pw_buf == NULL) return False;
356 if (current_idx == 0) {
360 /* These two cases are inefficient, but should be called very rarely */
361 /* they are the cases where the starting index isn't picking up */
362 /* where we left off last time. It is efficient when it starts over */
363 /* at zero though. */
364 if (start_idx > current_idx) {
365 /* We aren't far enough; advance to start_idx */
366 while (current_idx <= start_idx) {
370 if ((pwd = sys_getpwent()) == NULL) break;
375 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
376 (current_idx < start_idx)) {
381 if (unmap_name == NULL) {
386 } else if (start_idx < current_idx) {
387 /* We are already too far; start over and advance to start_idx */
393 while (current_idx < start_idx) {
397 if ((pwd = sys_getpwent()) == NULL) break;
402 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
403 (current_idx < start_idx)) {
408 if (unmap_name == NULL) {
415 sep = lp_winbind_separator();
417 /* now current_idx == start_idx */
418 while ((*num_entries) < max_num_entries) {
422 /* This does the original UNIX user itself */
424 if ((pwd = sys_getpwent()) == NULL) break;
426 /* Don't enumerate winbind users as they are not local */
428 if (strchr_m(pwd->pw_name, *sep) != NULL) {
432 user_name_len = strlen(pwd->pw_name);
434 /* skip the trust account stored in the /etc/passwd file */
435 if (pwd->pw_name[user_name_len-1]=='$')
438 pw_rid = pdb_uid_to_user_rid(pwd->pw_uid);
439 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
440 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pwd->pw_name, user_name_len);
441 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
442 pw_buf[(*num_entries)].user_rid = pw_rid;
443 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
445 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
447 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
455 /* This does all the user names that map to the UNIX user */
456 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
457 (*num_entries < max_num_entries)) {
458 user_name_len = strlen(unmap_name);
459 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
460 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, unmap_name, user_name_len);
461 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
462 pw_buf[(*num_entries)].user_rid = pw_rid;
463 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
465 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
467 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
475 if (unmap_name == NULL) {
476 /* done with 'aliases', go on to next UNIX user */
483 /* totally done, reset everything */
490 return (*num_entries) > 0;
493 #endif /* Unused function */
495 /*******************************************************************
497 ********************************************************************/
499 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
501 r_u->status = NT_STATUS_OK;
503 /* close the policy handle */
504 if (!close_policy_hnd(p, &q_u->pol))
505 return NT_STATUS_OBJECT_NAME_INVALID;
507 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
512 /*******************************************************************
513 samr_reply_open_domain
514 ********************************************************************/
516 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
518 struct samr_info *info;
520 r_u->status = NT_STATUS_OK;
522 /* find the connection policy handle. */
523 if (!find_policy_by_hnd(p, &q_u->pol, NULL))
524 return NT_STATUS_INVALID_HANDLE;
526 /* associate the domain SID with the (unique) handle. */
527 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
528 return NT_STATUS_NO_MEMORY;
531 info->sid = q_u->dom_sid.sid;
533 /* get a (unique) handle. open a policy on it. */
534 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
535 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
537 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
542 /*******************************************************************
543 _samr_get_usrdom_pwinfo
544 ********************************************************************/
546 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
548 struct samr_info *info = NULL;
550 r_u->status = NT_STATUS_OK;
552 /* find the policy handle. open a policy on it. */
553 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
554 return NT_STATUS_INVALID_HANDLE;
556 if (!sid_check_is_in_our_domain(&info->sid))
557 return NT_STATUS_OBJECT_TYPE_MISMATCH;
559 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
561 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
566 /*******************************************************************
568 ********************************************************************/
570 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC_BUF **buf, DOM_SID *usr_sid)
572 extern DOM_SID global_sid_World;
580 SEC_DESC *psd = NULL;
583 sid_copy(&adm_sid, &global_sid_Builtin);
584 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
586 sid_copy(&act_sid, &global_sid_Builtin);
587 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
589 init_sec_access(&mask, 0x2035b);
590 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
592 init_sec_access(&mask, 0xf07ff);
593 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
594 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
596 init_sec_access(&mask,0x20044);
597 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
599 if((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
600 return NT_STATUS_NO_MEMORY;
602 if((psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, &sd_size)) == NULL)
603 return NT_STATUS_NO_MEMORY;
605 if((*buf = make_sec_desc_buf(ctx, sd_size, psd)) == NULL)
606 return NT_STATUS_NO_MEMORY;
611 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid)
613 struct samr_info *info = NULL;
615 /* find the policy handle. open a policy on it. */
616 if (!find_policy_by_hnd(p, pol, (void **)&info))
626 /*******************************************************************
628 ********************************************************************/
630 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
635 r_u->status = NT_STATUS_OK;
639 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid))
640 return NT_STATUS_INVALID_HANDLE;
642 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
644 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &r_u->buf, &pol_sid);
646 if (NT_STATUS_IS_OK(r_u->status))
652 /*******************************************************************
653 makes a SAM_ENTRY / UNISTR2* structure from a user list.
654 ********************************************************************/
656 static void make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
657 uint32 num_sam_entries, SAM_USER_INFO_21 *pass)
666 if (num_sam_entries == 0)
669 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
671 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
673 if (sam == NULL || uni_name == NULL) {
674 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
679 ZERO_STRUCTP(uni_name);
681 for (i = 0; i < num_sam_entries; i++) {
682 int len = pass[i].uni_user_name.uni_str_len;
684 init_sam_entry(&sam[i], len, pass[i].user_rid);
685 copy_unistr2(&uni_name[i], &pass[i].uni_user_name);
689 *uni_name_pp = uni_name;
692 /*******************************************************************
693 samr_reply_enum_dom_users
694 ********************************************************************/
696 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_ENUM_DOM_USERS *r_u)
698 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
700 int total_entries = 0;
702 r_u->status = NT_STATUS_OK;
704 /* find the policy handle. open a policy on it. */
705 if (!find_policy_by_hnd(p, &q_u->pol, NULL))
706 return NT_STATUS_INVALID_HANDLE;
708 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
711 r_u->status = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
712 MAX_SAM_ENTRIES, q_u->acb_mask);
715 if (NT_STATUS_IS_ERR(r_u->status))
718 samr_clear_passwd_fields(pass, num_entries);
721 * Note from JRA. total_entries is not being used here. Currently if there is a
722 * large user base then it looks like NT will enumerate until get_sampwd_entries
723 * returns False due to num_entries being zero. This will cause an access denied
724 * return. I don't think this is right and needs further investigation. Note that
725 * this is also the same in the TNG code (I don't think that has been tested with
726 * a very large user list as MAX_SAM_ENTRIES is set to 600).
728 * I also think that one of the 'num_entries' return parameters is probably
729 * the "max entries" parameter - but in the TNG code they're all currently set to the same
730 * value (again I think this is wrong).
733 make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name, num_entries, pass);
735 init_samr_r_enum_dom_users(r_u, q_u->start_idx + num_entries, num_entries);
737 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
742 /*******************************************************************
743 makes a SAM_ENTRY / UNISTR2* structure from a group list.
744 ********************************************************************/
746 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
747 uint32 num_sam_entries, DOMAIN_GRP *grp)
756 if (num_sam_entries == 0)
759 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
761 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
763 if (sam == NULL || uni_name == NULL) {
764 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
768 for (i = 0; i < num_sam_entries; i++) {
770 * JRA. I think this should include the null. TNG does not.
772 int len = strlen(grp[i].name)+1;
774 init_sam_entry(&sam[i], len, grp[i].rid);
775 init_unistr2(&uni_name[i], grp[i].name, len);
779 *uni_name_pp = uni_name;
782 /*******************************************************************
783 Get the group entries - similar to get_sampwd_entries().
784 ********************************************************************/
786 static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
787 uint32 *p_num_entries, uint32 max_entries)
790 uint32 num_entries = 0;
795 sid_to_string(sid_str, sid);
796 DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str));
800 /* well-known aliases */
801 if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
803 enum_group_mapping(SID_NAME_ALIAS, &map, (int *)&num_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
805 if (num_entries != 0) {
806 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
808 return NT_STATUS_NO_MEMORY;
810 for(i=0; i<num_entries && i<max_entries; i++) {
811 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
812 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
818 } else if (sid_equal(sid, &global_sam_sid) && !lp_hide_local_users()) {
820 struct sys_grent *glist;
821 struct sys_grent *grp;
823 sep = lp_winbind_separator();
826 /* we return the UNIX groups here. This seems to be the right */
827 /* thing to do, since NT member servers return their local */
828 /* groups in the same situation. */
830 /* use getgrent_list() to retrieve the list of groups to avoid
831 * problems with getgrent possible infinite loop by internal
832 * libc grent structures overwrites by called functions */
833 grp = glist = getgrent_list();
835 return NT_STATUS_NO_MEMORY;
837 for (; (num_entries < max_entries) && (grp != NULL); grp = grp->next) {
840 if(!get_group_from_gid(grp->gr_gid, &smap, MAPPING_WITHOUT_PRIV))
843 if (smap.sid_name_use!=SID_NAME_ALIAS) {
847 sid_split_rid(&smap.sid, &trid);
849 if (!sid_equal(sid, &smap.sid))
852 /* Don't return winbind groups as they are not local! */
853 if (strchr_m(smap.nt_name, *sep) != NULL) {
854 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
858 /* Don't return user private groups... */
859 if (Get_Pwnam(smap.nt_name) != 0) {
860 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
864 for( i = 0; i < num_entries; i++)
865 if ( (*d_grp)[i].rid == trid )
868 if ( i < num_entries ) {
869 continue; /* rid was there, dup! */
872 /* JRA - added this for large group db enumeration... */
875 /* skip the requested number of entries.
876 not very efficient, but hey...
882 *d_grp=talloc_realloc(ctx,*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
885 return NT_STATUS_NO_MEMORY;
888 fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
889 (*d_grp)[num_entries].rid = trid;
891 DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries, trid));
897 *p_num_entries = num_entries;
899 DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries));
901 if (num_entries >= max_entries)
902 return STATUS_MORE_ENTRIES;
906 /*******************************************************************
907 Get the group entries - similar to get_sampwd_entries().
908 ********************************************************************/
910 static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
911 uint32 *p_num_entries, uint32 max_entries)
915 uint32 group_entries = 0;
916 uint32 num_entries = 0;
920 enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
922 num_entries=group_entries-start_idx;
924 /* limit the number of entries */
925 if (num_entries>max_entries) {
926 DEBUG(5,("Limiting to %d entries\n", max_entries));
927 num_entries=max_entries;
930 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
931 if (num_entries!=0 && *d_grp==NULL){
933 return NT_STATUS_NO_MEMORY;
936 for (i=0; i<num_entries; i++) {
937 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
938 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
939 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
940 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
945 *p_num_entries = num_entries;
950 /*******************************************************************
951 samr_reply_enum_dom_groups
952 Only reply with one group - domain admins. This must be fixed for
954 ********************************************************************/
956 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
958 DOMAIN_GRP *grp=NULL;
962 r_u->status = NT_STATUS_OK;
964 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
965 return NT_STATUS_INVALID_HANDLE;
967 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
969 /* the domain group array is being allocated in the function below */
970 get_group_domain_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES);
972 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
974 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
976 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
982 /*******************************************************************
983 samr_reply_enum_dom_aliases
984 ********************************************************************/
986 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
988 DOMAIN_GRP *grp=NULL;
989 uint32 num_entries = 0;
994 r_u->status = NT_STATUS_OK;
996 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
997 return NT_STATUS_INVALID_HANDLE;
999 sid_to_string(sid_str, &sid);
1000 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1002 status = get_group_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1003 &num_entries, MAX_SAM_ENTRIES);
1004 if (NT_STATUS_IS_ERR(status)) return status;
1006 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1010 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1012 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1017 /*******************************************************************
1018 samr_reply_query_dispinfo
1019 ********************************************************************/
1021 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_QUERY_DISPINFO *r_u)
1023 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
1024 DOMAIN_GRP *grps=NULL;
1025 uint16 acb_mask = ACB_NORMAL;
1026 uint32 num_entries = 0;
1027 int orig_num_entries = 0;
1028 int total_entries = 0;
1029 uint32 data_size = 0;
1032 SAM_DISPINFO_CTR *ctr;
1034 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1036 r_u->status = NT_STATUS_OK;
1038 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid))
1039 return NT_STATUS_INVALID_HANDLE;
1041 /* decide how many entries to get depending on the max_entries
1042 and max_size passed by client */
1044 DEBUG(5, ("samr_reply_query_dispinfo: max_entries before %d\n", q_u->max_entries));
1046 if(q_u->max_entries > MAX_SAM_ENTRIES)
1047 q_u->max_entries = MAX_SAM_ENTRIES;
1049 DEBUG(5, ("samr_reply_query_dispinfo: max_entries after %d\n", q_u->max_entries));
1051 /* Get what we need from the password database */
1052 switch (q_u->switch_level) {
1054 acb_mask = ACB_WSTRUST;
1060 r_u->status = get_passwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
1061 MAX_SAM_ENTRIES, acb_mask);
1065 * Which should we use here ? JRA.
1067 r_u->status = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
1068 MAX_SAM_ENTRIES, acb_mask);
1071 r_u->status = jf_get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
1072 MAX_SAM_ENTRIES, acb_mask);
1075 if (NT_STATUS_IS_ERR(r_u->status)) {
1076 DEBUG(5, ("get_sampwd_entries: failed\n"));
1082 r_u->status = get_group_domain_entries(p->mem_ctx, &grps, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES);
1083 if (NT_STATUS_IS_ERR(r_u->status))
1087 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1088 return NT_STATUS_INVALID_INFO_CLASS;
1091 orig_num_entries = num_entries;
1093 if (num_entries > q_u->max_entries)
1094 num_entries = q_u->max_entries;
1096 if (num_entries > MAX_SAM_ENTRIES) {
1097 num_entries = MAX_SAM_ENTRIES;
1098 DEBUG(5, ("limiting number of entries to %d\n", num_entries));
1101 /* Ensure password info is never given out here. PARANOIA... JRA */
1102 samr_clear_passwd_fields(pass, num_entries);
1104 data_size = q_u->max_size;
1106 if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1107 return NT_STATUS_NO_MEMORY;
1111 /* Now create reply structure */
1112 switch (q_u->switch_level) {
1115 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_1))))
1116 return NT_STATUS_NO_MEMORY;
1118 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, &num_entries, &data_size, q_u->start_idx, pass);
1119 if (NT_STATUS_IS_ERR(disp_ret))
1124 if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_2))))
1125 return NT_STATUS_NO_MEMORY;
1127 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, &num_entries, &data_size, q_u->start_idx, pass);
1128 if (NT_STATUS_IS_ERR(disp_ret))
1133 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_3))))
1134 return NT_STATUS_NO_MEMORY;
1136 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, &num_entries, &data_size, q_u->start_idx, grps);
1137 if (NT_STATUS_IS_ERR(disp_ret))
1142 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_4))))
1143 return NT_STATUS_NO_MEMORY;
1145 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, &num_entries, &data_size, q_u->start_idx, pass);
1146 if (NT_STATUS_IS_ERR(disp_ret))
1151 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_5))))
1152 return NT_STATUS_NO_MEMORY;
1154 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, &num_entries, &data_size, q_u->start_idx, grps);
1155 if (NT_STATUS_IS_ERR(disp_ret))
1159 ctr->sam.info = NULL;
1160 return NT_STATUS_INVALID_INFO_CLASS;
1163 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1165 if (num_entries < orig_num_entries)
1166 return STATUS_MORE_ENTRIES;
1168 init_samr_r_query_dispinfo(r_u, num_entries, data_size, q_u->switch_level, ctr, r_u->status);
1173 /*******************************************************************
1174 samr_reply_query_aliasinfo
1175 ********************************************************************/
1177 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1179 fstring alias_desc = "Local Unix group";
1181 enum SID_NAME_USE type;
1182 struct samr_info *info = NULL;
1184 r_u->status = NT_STATUS_OK;
1186 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1188 /* find the policy handle. open a policy on it. */
1189 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1190 return NT_STATUS_INVALID_HANDLE;
1192 if (!sid_check_is_in_our_domain(&info->sid) &&
1193 !sid_check_is_in_builtin(&info->sid))
1194 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1196 if(!local_lookup_sid(&info->sid, alias, &type))
1197 return NT_STATUS_NO_SUCH_ALIAS;
1199 switch (q_u->switch_level) {
1202 r_u->ctr.switch_value1 = 3;
1203 init_samr_alias_info3(&r_u->ctr.alias.info3, alias_desc);
1206 return NT_STATUS_INVALID_INFO_CLASS;
1209 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1215 /*******************************************************************
1216 samr_reply_lookup_ids
1217 ********************************************************************/
1219 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1221 uint32 rid[MAX_SAM_ENTRIES];
1222 int num_rids = q_u->num_sids1;
1224 r_u->status = NT_STATUS_OK;
1226 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1228 if (num_rids > MAX_SAM_ENTRIES) {
1229 num_rids = MAX_SAM_ENTRIES;
1230 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1235 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1237 for (i = 0; i < num_rids && status == 0; i++)
1239 struct sam_passwd *sam_pass;
1243 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1244 q_u->uni_user_name[i].uni_str_len));
1246 /* find the user account */
1248 sam_pass = get_smb21pwd_entry(user_name, 0);
1251 if (sam_pass == NULL)
1253 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1258 rid[i] = sam_pass->user_rid;
1264 rid[0] = BUILTIN_ALIAS_RID_USERS;
1266 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1268 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1274 /*******************************************************************
1276 ********************************************************************/
1278 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1280 uint32 rid[MAX_SAM_ENTRIES];
1282 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1283 enum SID_NAME_USE local_type;
1285 int num_rids = q_u->num_names2;
1289 r_u->status = NT_STATUS_OK;
1291 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1296 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid)) {
1297 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1301 if (num_rids > MAX_SAM_ENTRIES) {
1302 num_rids = MAX_SAM_ENTRIES;
1303 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1306 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1308 for (i = 0; i < num_rids; i++) {
1312 r_u->status = NT_STATUS_NONE_MAPPED;
1314 rid [i] = 0xffffffff;
1315 type[i] = SID_NAME_UNKNOWN;
1317 rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1320 * we are only looking for a name
1321 * the SID we get back can be outside
1322 * the scope of the pol_sid
1324 * in clear: it prevents to reply to domain\group: yes
1325 * when only builtin\group exists.
1327 * a cleaner code is to add the sid of the domain we're looking in
1328 * to the local_lookup_name function.
1330 if(local_lookup_name(global_myname, name, &sid, &local_type)) {
1331 sid_split_rid(&sid, &local_rid);
1333 if (sid_equal(&sid, &pol_sid)) {
1336 r_u->status = NT_STATUS_OK;
1341 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1343 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1348 /*******************************************************************
1349 _samr_chgpasswd_user
1350 ********************************************************************/
1352 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1357 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1359 r_u->status = NT_STATUS_OK;
1361 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1362 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1364 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1367 * Pass the user through the NT -> unix user mapping
1371 (void)map_username(user_name);
1374 * Do any UNIX username case mangling.
1376 (void)Get_Pwnam_Modify( user_name);
1378 if (!pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1379 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1380 r_u->status = NT_STATUS_WRONG_PASSWORD;
1382 init_samr_r_chgpasswd_user(r_u, r_u->status);
1384 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1389 /*******************************************************************
1390 makes a SAMR_R_LOOKUP_RIDS structure.
1391 ********************************************************************/
1393 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1394 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1397 UNIHDR *hdr_name=NULL;
1398 UNISTR2 *uni_name=NULL;
1400 *pp_uni_name = NULL;
1401 *pp_hdr_name = NULL;
1403 if (num_names != 0) {
1404 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1405 if (hdr_name == NULL)
1408 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1409 if (uni_name == NULL)
1413 for (i = 0; i < num_names; i++) {
1414 int len = names[i] != NULL ? strlen(names[i]) : 0;
1415 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1416 init_uni_hdr(&hdr_name[i], len);
1417 init_unistr2(&uni_name[i], names[i], len);
1420 *pp_uni_name = uni_name;
1421 *pp_hdr_name = hdr_name;
1426 /*******************************************************************
1428 ********************************************************************/
1430 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1432 fstring group_names[MAX_SAM_ENTRIES];
1433 uint32 *group_attrs = NULL;
1434 UNIHDR *hdr_name = NULL;
1435 UNISTR2 *uni_name = NULL;
1437 int num_rids = q_u->num_rids1;
1440 r_u->status = NT_STATUS_OK;
1442 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1444 /* find the policy handle. open a policy on it. */
1445 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid))
1446 return NT_STATUS_INVALID_HANDLE;
1448 if (num_rids > MAX_SAM_ENTRIES) {
1449 num_rids = MAX_SAM_ENTRIES;
1450 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1454 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1455 return NT_STATUS_NO_MEMORY;
1458 r_u->status = NT_STATUS_NONE_MAPPED;
1460 for (i = 0; i < num_rids; i++) {
1464 enum SID_NAME_USE type;
1466 group_attrs[i] = SID_NAME_UNKNOWN;
1467 *group_names[i] = '\0';
1469 if (sid_equal(&pol_sid, &global_sam_sid)) {
1470 sid_copy(&sid, &pol_sid);
1471 sid_append_rid(&sid, q_u->rid[i]);
1473 if (lookup_sid(&sid, domname, tmpname, &type)) {
1474 r_u->status = NT_STATUS_OK;
1475 group_attrs[i] = (uint32)type;
1476 fstrcpy(group_names[i],tmpname);
1477 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1482 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1483 return NT_STATUS_NO_MEMORY;
1485 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1487 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1492 /*******************************************************************
1493 _api_samr_open_user. Safe - gives out no passwd info.
1494 ********************************************************************/
1496 NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1498 SAM_ACCOUNT *sampass=NULL;
1500 POLICY_HND domain_pol = q_u->domain_pol;
1501 uint32 user_rid = q_u->user_rid;
1502 POLICY_HND *user_pol = &r_u->user_pol;
1503 struct samr_info *info = NULL;
1506 r_u->status = NT_STATUS_OK;
1508 /* find the domain policy handle. */
1509 if (!find_policy_by_hnd(p, &domain_pol, NULL))
1510 return NT_STATUS_INVALID_HANDLE;
1512 pdb_init_sam(&sampass);
1515 ret=pdb_getsampwrid(sampass, user_rid);
1518 /* check that the RID exists in our domain. */
1520 pdb_free_sam(&sampass);
1521 return NT_STATUS_NO_SUCH_USER;
1524 samr_clear_sam_passwd(sampass);
1525 pdb_free_sam(&sampass);
1527 /* Get the domain SID stored in the domain policy */
1528 if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
1529 return NT_STATUS_INVALID_HANDLE;
1531 /* append the user's RID to it */
1532 if(!sid_append_rid(&sid, user_rid))
1533 return NT_STATUS_NO_SUCH_USER;
1535 /* associate the user's SID with the new handle. */
1536 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
1537 return NT_STATUS_NO_MEMORY;
1542 /* get a (unique) handle. open a policy on it. */
1543 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1544 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1549 /*************************************************************************
1550 get_user_info_10. Safe. Only gives out acb bits.
1551 *************************************************************************/
1553 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1555 SAM_ACCOUNT *smbpass=NULL;
1558 if (!pdb_rid_is_user(user_rid)) {
1559 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1563 pdb_init_sam(&smbpass);
1566 ret = pdb_getsampwrid(smbpass, user_rid);
1570 DEBUG(4,("User 0x%x not found\n", user_rid));
1571 pdb_free_sam(&smbpass);
1575 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1578 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1580 samr_clear_sam_passwd(smbpass);
1581 pdb_free_sam(&smbpass);
1586 /*************************************************************************
1587 get_user_info_12. OK - this is the killer as it gives out password info.
1588 Ensure that this is only allowed on an encrypted connection with a root
1590 *************************************************************************/
1592 static NTSTATUS get_user_info_12(pipes_struct *p, SAM_USER_INFO_12 * id12, uint32 user_rid)
1594 SAM_ACCOUNT *smbpass=NULL;
1597 if (!p->ntlmssp_auth_validated)
1598 return NT_STATUS_ACCESS_DENIED;
1600 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1601 return NT_STATUS_ACCESS_DENIED;
1604 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1606 pdb_init_sam(&smbpass);
1608 ret = pdb_getsampwrid(smbpass, user_rid);
1611 DEBUG(4, ("User 0x%x not found\n", user_rid));
1612 pdb_free_sam(&smbpass);
1613 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1616 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1618 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1619 pdb_free_sam(&smbpass);
1620 return NT_STATUS_ACCOUNT_DISABLED;
1624 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1626 pdb_free_sam(&smbpass);
1628 return NT_STATUS_OK;
1631 /*************************************************************************
1633 *************************************************************************/
1635 static BOOL get_user_info_20(SAM_USER_INFO_20 *id20, uint32 user_rid)
1637 SAM_ACCOUNT *sampass=NULL;
1640 if (!pdb_rid_is_user(user_rid)) {
1641 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1645 pdb_init_sam(&sampass);
1648 ret = pdb_getsampwrid(sampass, user_rid);
1652 DEBUG(4,("User 0x%x not found\n", user_rid));
1653 pdb_free_sam(&sampass);
1657 samr_clear_sam_passwd(sampass);
1659 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1662 init_sam_user_info20A(id20, sampass);
1664 pdb_free_sam(&sampass);
1669 /*************************************************************************
1671 *************************************************************************/
1673 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1675 SAM_ACCOUNT *sampass=NULL;
1678 if (!pdb_rid_is_user(user_rid)) {
1679 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1683 pdb_init_sam(&sampass);
1686 ret = pdb_getsampwrid(sampass, user_rid);
1690 DEBUG(4,("User 0x%x not found\n", user_rid));
1691 pdb_free_sam(&sampass);
1695 samr_clear_sam_passwd(sampass);
1697 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1700 init_sam_user_info21A(id21, sampass);
1702 pdb_free_sam(&sampass);
1707 /*******************************************************************
1708 _samr_query_userinfo
1709 ********************************************************************/
1711 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1713 SAM_USERINFO_CTR *ctr;
1715 struct samr_info *info = NULL;
1717 r_u->status=NT_STATUS_OK;
1719 /* search for the handle */
1720 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1721 return NT_STATUS_INVALID_HANDLE;
1723 if (!sid_check_is_in_our_domain(&info->sid))
1724 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1726 sid_peek_rid(&info->sid, &rid);
1728 DEBUG(5,("_samr_query_userinfo: rid:0x%x\n", rid));
1730 ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1732 return NT_STATUS_NO_MEMORY;
1736 /* ok! user info levels (lots: see MSDEV help), off we go... */
1737 ctr->switch_value = q_u->switch_value;
1739 switch (q_u->switch_value) {
1741 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1742 if (ctr->info.id10 == NULL)
1743 return NT_STATUS_NO_MEMORY;
1745 if (!get_user_info_10(ctr->info.id10, rid))
1746 return NT_STATUS_NO_SUCH_USER;
1750 /* whoops - got this wrong. i think. or don't understand what's happening. */
1754 info = (void *)&id11;
1756 expire.low = 0xffffffff;
1757 expire.high = 0x7fffffff;
1759 ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1764 ZERO_STRUCTP(ctr->info.id11);
1765 init_sam_user_info11(ctr->info.id11, &expire,
1766 "BROOKFIELDS$", /* name */
1767 0x03ef, /* user rid */
1768 0x201, /* group rid */
1769 0x0080); /* acb info */
1776 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1777 if (ctr->info.id12 == NULL)
1778 return NT_STATUS_NO_MEMORY;
1780 if (NT_STATUS_IS_ERR(r_u->status = get_user_info_12(p, ctr->info.id12, rid)))
1785 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1786 if (ctr->info.id20 == NULL)
1787 return NT_STATUS_NO_MEMORY;
1788 if (!get_user_info_20(ctr->info.id20, rid))
1789 return NT_STATUS_NO_SUCH_USER;
1793 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1794 if (ctr->info.id21 == NULL)
1795 return NT_STATUS_NO_MEMORY;
1796 if (!get_user_info_21(ctr->info.id21, rid))
1797 return NT_STATUS_NO_SUCH_USER;
1801 return NT_STATUS_INVALID_INFO_CLASS;
1804 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1806 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1811 /*******************************************************************
1812 samr_reply_query_usergroups
1813 ********************************************************************/
1815 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1817 SAM_ACCOUNT *sam_pass=NULL;
1818 DOM_GID *gids = NULL;
1821 struct samr_info *info = NULL;
1825 * from the SID in the request:
1826 * we should send back the list of DOMAIN GROUPS
1827 * the user is a member of
1829 * and only the DOMAIN GROUPS
1830 * no ALIASES !!! neither aliases of the domain
1831 * nor aliases of the builtin SID
1836 r_u->status = NT_STATUS_OK;
1838 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1840 /* find the policy handle. open a policy on it. */
1841 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1842 return NT_STATUS_INVALID_HANDLE;
1844 if (!sid_check_is_in_our_domain(&info->sid))
1845 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1847 sid_peek_rid(&info->sid, &rid);
1849 pdb_init_sam(&sam_pass);
1852 ret = pdb_getsampwrid(sam_pass, rid);
1856 samr_clear_sam_passwd(sam_pass);
1857 pdb_free_sam(&sam_pass);
1858 return NT_STATUS_NO_SUCH_USER;
1861 if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
1862 samr_clear_sam_passwd(sam_pass);
1863 pdb_free_sam(&sam_pass);
1864 return NT_STATUS_NO_SUCH_GROUP;
1867 /* construct the response. lkclXXXX: gids are not copied! */
1868 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
1870 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1872 samr_clear_sam_passwd(sam_pass);
1873 pdb_free_sam(&sam_pass);
1878 /*******************************************************************
1879 _samr_query_dom_info
1880 ********************************************************************/
1882 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
1885 uint32 min_pass_len,pass_hist,flag;
1886 time_t u_expire, u_min_age;
1887 NTTIME nt_expire, nt_min_age;
1889 time_t u_lock_duration, u_reset_time;
1890 NTTIME nt_lock_duration, nt_reset_time;
1897 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
1898 return NT_STATUS_NO_MEMORY;
1902 r_u->status = NT_STATUS_OK;
1904 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
1906 /* find the policy handle. open a policy on it. */
1907 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
1908 return NT_STATUS_INVALID_HANDLE;
1910 switch (q_u->switch_value) {
1912 account_policy_get(AP_MIN_PASSWORD_LEN, &min_pass_len);
1913 account_policy_get(AP_PASSWORD_HISTORY, &pass_hist);
1914 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &flag);
1915 account_policy_get(AP_MAX_PASSWORD_AGE, (int *)&u_expire);
1916 account_policy_get(AP_MIN_PASSWORD_AGE, (int *)&u_min_age);
1918 unix_to_nt_time_abs(&nt_expire, u_expire);
1919 unix_to_nt_time_abs(&nt_min_age, u_min_age);
1921 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
1922 flag, nt_expire, nt_min_age);
1925 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
1926 init_unk_info2(&ctr->info.inf2, global_myworkgroup, global_myname, (uint32) time(NULL));
1929 account_policy_get(AP_TIME_TO_LOGOUT, (int *)&u_logout);
1930 unix_to_nt_time_abs(&nt_logout, u_logout);
1932 init_unk_info3(&ctr->info.inf3, nt_logout);
1935 init_unk_info5(&ctr->info.inf5, global_myname);
1938 init_unk_info6(&ctr->info.inf6);
1941 init_unk_info7(&ctr->info.inf7);
1944 account_policy_get(AP_LOCK_ACCOUNT_DURATION, (int *)&u_lock_duration);
1945 account_policy_get(AP_RESET_COUNT_TIME, (int *)&u_reset_time);
1946 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &lockout);
1948 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
1949 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
1951 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
1954 return NT_STATUS_INVALID_INFO_CLASS;
1957 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
1959 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
1964 /*******************************************************************
1965 _api_samr_create_user
1966 Create an account, can be either a normal user or a machine.
1967 This funcion will need to be updated for bdc/domain trusts.
1968 ********************************************************************/
1970 NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
1972 SAM_ACCOUNT *sam_pass=NULL;
1979 POLICY_HND dom_pol = q_u->domain_pol;
1980 UNISTR2 user_account = q_u->uni_name;
1981 uint16 acb_info = q_u->acb_info;
1982 POLICY_HND *user_pol = &r_u->user_pol;
1983 struct samr_info *info = NULL;
1986 /* find the policy handle. open a policy on it. */
1987 if (!find_policy_by_hnd(p, &dom_pol, NULL))
1988 return NT_STATUS_INVALID_HANDLE;
1990 /* find the account: tell the caller if it exists.
1991 lkclXXXX i have *no* idea if this is a problem or not
1992 or even if you are supposed to construct a different
1993 reply if the account already exists...
1996 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
1999 pdb_init_sam(&sam_pass);
2002 ret = pdb_getsampwnam(sam_pass, account);
2005 /* this account exists: say so */
2006 pdb_free_sam(&sam_pass);
2007 return NT_STATUS_USER_EXISTS;
2010 local_flags=LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_SET_NO_PASSWORD;
2011 local_flags|= (acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0;
2014 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2015 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2016 * that only people with write access to the smbpasswd file will be able
2017 * to create a user. JRA.
2021 * add the user in the /etc/passwd file or the unix authority system.
2022 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2023 * a) local_password_change() checks for us if the /etc/passwd account really exists
2024 * b) smb_create_user() would return an error if the account already exists
2025 * and as it could return an error also if it can't create the account, it would be tricky.
2027 * So we go the easy way, only check after if the account exists.
2028 * JFM (2/3/2001), to clear any possible bad understanding (-:
2030 * We now have seperate script paramaters for adding users/machines so we
2031 * now have some sainity-checking to match.
2034 DEBUG(10,("checking account %s at pos %d for $ termination\n",account, strlen(account)-1));
2036 if ((acb_info & ACB_WSTRUST) && (account[strlen(account)-1] == '$')) {
2037 pstrcpy(add_script, lp_addmachine_script());
2038 } else if ((!(acb_info & ACB_WSTRUST)) && (account[strlen(account)-1] != '$')) {
2039 pstrcpy(add_script, lp_adduser_script());
2041 DEBUG(0, ("_api_samr_create_user: mismatch between trust flags and $ termination\n"));
2042 pdb_free_sam(&sam_pass);
2043 return NT_STATUS_UNSUCCESSFUL;
2048 * we can't check both the ending $ and the acb_info.
2050 * UserManager creates trust accounts (ending in $,
2051 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2054 if (account[strlen(account)-1] == '$')
2055 pstrcpy(add_script, lp_addmachine_script());
2057 pstrcpy(add_script, lp_adduser_script());
2061 all_string_sub(add_script, "%u", account, sizeof(account));
2062 add_ret = smbrun(add_script,NULL);
2063 DEBUG(3,("_api_samr_create_user: Running the command `%s' gave %d\n",add_script,add_ret));
2066 /* add the user in the smbpasswd file or the Samba authority database */
2067 if (!local_password_change(account, local_flags, NULL, err_str,
2068 sizeof(err_str), msg_str, sizeof(msg_str))) {
2069 DEBUG(0, ("%s\n", err_str));
2070 pdb_free_sam(&sam_pass);
2071 return NT_STATUS_ACCESS_DENIED;
2075 ret = pdb_getsampwnam(sam_pass, account);
2078 /* account doesn't exist: say so */
2079 pdb_free_sam(&sam_pass);
2080 return NT_STATUS_ACCESS_DENIED;
2083 /* Get the domain SID stored in the domain policy */
2084 if(!get_lsa_policy_samr_sid(p, &dom_pol, &sid)) {
2085 pdb_free_sam(&sam_pass);
2086 return NT_STATUS_INVALID_HANDLE;
2089 /* append the user's RID to it */
2090 if(!sid_append_rid(&sid, pdb_get_user_rid(sam_pass) )) {
2091 pdb_free_sam(&sam_pass);
2092 return NT_STATUS_NO_SUCH_USER;
2095 /* associate the user's SID with the new handle. */
2096 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL) {
2097 pdb_free_sam(&sam_pass);
2098 return NT_STATUS_NO_MEMORY;
2104 /* get a (unique) handle. open a policy on it. */
2105 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2106 pdb_free_sam(&sam_pass);
2107 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2110 r_u->user_rid=sam_pass->user_rid;
2111 r_u->unknown_0 = 0x000703ff;
2113 pdb_free_sam(&sam_pass);
2115 return NT_STATUS_OK;
2118 /*******************************************************************
2119 samr_reply_connect_anon
2120 ********************************************************************/
2122 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2124 struct samr_info *info = NULL;
2126 /* set up the SAMR connect_anon response */
2128 r_u->status = NT_STATUS_OK;
2130 /* associate the user's SID with the new handle. */
2131 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
2132 return NT_STATUS_NO_MEMORY;
2135 info->status = q_u->unknown_0;
2137 /* get a (unique) handle. open a policy on it. */
2138 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2139 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2144 /*******************************************************************
2146 ********************************************************************/
2148 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2150 struct samr_info *info = NULL;
2152 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2154 r_u->status = NT_STATUS_OK;
2156 /* associate the user's SID with the new handle. */
2157 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
2158 return NT_STATUS_NO_MEMORY;
2161 info->status = q_u->access_mask;
2163 /* get a (unique) handle. open a policy on it. */
2164 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2165 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2167 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2172 /**********************************************************************
2173 api_samr_lookup_domain
2174 **********************************************************************/
2176 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2178 r_u->status = NT_STATUS_OK;
2180 if (!find_policy_by_hnd(p, &q_u->connect_pol, NULL))
2181 return NT_STATUS_INVALID_HANDLE;
2183 /* assume the domain name sent is our global_myname and
2184 send global_sam_sid */
2185 init_samr_r_lookup_domain(r_u, &global_sam_sid, r_u->status);
2190 /******************************************************************
2191 makes a SAMR_R_ENUM_DOMAINS structure.
2192 ********************************************************************/
2194 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2195 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2201 DEBUG(5, ("make_enum_domains\n"));
2204 *pp_uni_name = NULL;
2206 if (num_sam_entries == 0)
2209 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2210 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2212 if (sam == NULL || uni_name == NULL)
2215 for (i = 0; i < num_sam_entries; i++) {
2216 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
2218 init_sam_entry(&sam[i], len, 0);
2219 init_unistr2(&uni_name[i], doms[i], len);
2223 *pp_uni_name = uni_name;
2228 /**********************************************************************
2229 api_samr_enum_domains
2230 **********************************************************************/
2232 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2234 uint32 num_entries = 2;
2237 r_u->status = NT_STATUS_OK;
2239 fstrcpy(dom[0],global_myworkgroup);
2240 fstrcpy(dom[1],"Builtin");
2242 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2243 return NT_STATUS_NO_MEMORY;
2245 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2250 /*******************************************************************
2252 ********************************************************************/
2254 NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2257 POLICY_HND domain_pol = q_u->dom_pol;
2258 uint32 alias_rid = q_u->rid_alias;
2259 POLICY_HND *alias_pol = &r_u->pol;
2260 struct samr_info *info = NULL;
2262 r_u->status = NT_STATUS_OK;
2264 /* get the domain policy. */
2265 if (!find_policy_by_hnd(p, &domain_pol, NULL))
2266 return NT_STATUS_INVALID_HANDLE;
2268 /* Get the domain SID stored in the domain policy */
2269 if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
2270 return NT_STATUS_INVALID_HANDLE;
2272 /* append the alias' RID to it */
2273 if(!sid_append_rid(&sid, alias_rid))
2274 return NT_STATUS_NO_SUCH_USER;
2277 * we should check if the rid really exist !!!
2281 /* associate the user's SID with the new handle. */
2282 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
2283 return NT_STATUS_NO_MEMORY;
2288 /* get a (unique) handle. open a policy on it. */
2289 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2290 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2295 /*******************************************************************
2297 ********************************************************************/
2299 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid)
2301 SAM_ACCOUNT *pwd =NULL;
2306 ret = pdb_getsampwrid(pwd, rid);
2314 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2319 if (!pdb_set_acct_ctrl(pwd, id10->acb_info)) {
2324 if(!pdb_update_sam_account(pwd, True)) {
2334 /*******************************************************************
2336 ********************************************************************/
2338 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, uint32 rid)
2340 SAM_ACCOUNT *pwd = NULL;
2344 if(!pdb_getsampwrid(pwd, rid)) {
2350 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2355 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd)) {
2359 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd)) {
2363 if (!pdb_set_pass_changed_now (pwd)) {
2368 if(!pdb_update_sam_account(pwd, True)) {
2377 /*******************************************************************
2379 ********************************************************************/
2381 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, uint32 rid)
2383 SAM_ACCOUNT *pwd = NULL;
2386 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2392 if (!pdb_getsampwrid(pwd, rid)) {
2397 copy_id21_to_sam_passwd(pwd, id21);
2400 * The funny part about the previous two calls is
2401 * that pwd still has the password hashes from the
2402 * passdb entry. These have not been updated from
2403 * id21. I don't know if they need to be set. --jerry
2406 /* write the change out */
2407 if(!pdb_update_sam_account(pwd, True)) {
2417 /*******************************************************************
2419 ********************************************************************/
2421 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
2423 SAM_ACCOUNT *pwd = NULL;
2424 pstring plaintext_buf;
2429 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2435 if (!pdb_getsampwrid(pwd, rid)) {
2440 acct_ctrl = pdb_get_acct_ctrl(pwd);
2442 copy_id23_to_sam_passwd(pwd, id23);
2444 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
2449 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2454 /* if it's a trust account, don't update /etc/passwd */
2455 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2456 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2457 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2458 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2460 /* update the UNIX password */
2461 if (lp_unix_password_sync() )
2462 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2468 ZERO_STRUCT(plaintext_buf);
2470 if(!pdb_update_sam_account(pwd, True)) {
2480 /*******************************************************************
2482 ********************************************************************/
2484 static BOOL set_user_info_pw(char *pass, uint32 rid)
2486 SAM_ACCOUNT *pwd = NULL;
2488 pstring plaintext_buf;
2493 if (!pdb_getsampwrid(pwd, rid)) {
2498 acct_ctrl = pdb_get_acct_ctrl(pwd);
2500 ZERO_STRUCT(plaintext_buf);
2502 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) {
2507 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2512 /* if it's a trust account, don't update /etc/passwd */
2513 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2514 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2515 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2516 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2518 /* update the UNIX password */
2519 if (lp_unix_password_sync())
2520 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2526 ZERO_STRUCT(plaintext_buf);
2528 DEBUG(5,("set_user_info_pw: pdb_update_sam_account()\n"));
2530 /* update the SAMBA password */
2531 if(!pdb_update_sam_account(pwd, True)) {
2541 /*******************************************************************
2542 samr_reply_set_userinfo
2543 ********************************************************************/
2545 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2549 struct current_user user;
2550 SAM_ACCOUNT *sam_pass=NULL;
2551 unsigned char sess_key[16];
2552 POLICY_HND *pol = &q_u->pol;
2553 uint16 switch_value = q_u->switch_value;
2554 SAM_USERINFO_CTR *ctr = q_u->ctr;
2557 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2559 r_u->status = NT_STATUS_OK;
2561 if (p->ntlmssp_auth_validated) {
2562 memcpy(&user, &p->pipe_user, sizeof(user));
2564 extern struct current_user current_user;
2565 memcpy(&user, ¤t_user, sizeof(user));
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_set_userinfo: rid:0x%x, level:%d\n", rid, switch_value));
2577 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2578 return NT_STATUS_INVALID_INFO_CLASS;
2582 pdb_init_sam(&sam_pass);
2585 * We need the NT hash of the user who is changing the user's password.
2586 * This NT hash is used to generate a "user session key"
2587 * This "user session key" is in turn used to encrypt/decrypt the user's password.
2591 ret = pdb_getsampwuid(sam_pass, user.uid);
2594 DEBUG(0,("_samr_set_userinfo: Unable to get smbpasswd entry for uid %u\n", (unsigned int)user.uid ));
2595 pdb_free_sam(&sam_pass);
2596 return NT_STATUS_ACCESS_DENIED;
2599 memset(sess_key, '\0', 16);
2600 mdfour(sess_key, pdb_get_nt_passwd(sam_pass), 16);
2602 pdb_free_sam(&sam_pass);
2604 /* ok! user info levels (lots: see MSDEV help), off we go... */
2605 switch (switch_value) {
2607 if (!set_user_info_12(ctr->info.id12, rid))
2608 return NT_STATUS_ACCESS_DENIED;
2612 SamOEMhash(ctr->info.id24->pass, sess_key, 516);
2614 dump_data(100, (char *)ctr->info.id24->pass, 516);
2616 if (!set_user_info_pw((char *)ctr->info.id24->pass, rid))
2617 return NT_STATUS_ACCESS_DENIED;
2623 * Currently we don't really know how to unmarshall
2624 * the level 25 struct, and the password encryption
2625 * is different. This is a placeholder for when we
2626 * do understand it. In the meantime just return INVALID
2627 * info level and W2K SP2 drops down to level 23... JRA.
2630 SamOEMhash(ctr->info.id25->pass, sess_key, 532);
2632 dump_data(100, (char *)ctr->info.id25->pass, 532);
2634 if (!set_user_info_pw(ctr->info.id25->pass, rid))
2635 return NT_STATUS_ACCESS_DENIED;
2638 return NT_STATUS_INVALID_INFO_CLASS;
2641 SamOEMhash(ctr->info.id23->pass, sess_key, 516);
2643 dump_data(100, (char *)ctr->info.id23->pass, 516);
2645 if (!set_user_info_23(ctr->info.id23, rid))
2646 return NT_STATUS_ACCESS_DENIED;
2650 return NT_STATUS_INVALID_INFO_CLASS;
2656 /*******************************************************************
2657 samr_reply_set_userinfo2
2658 ********************************************************************/
2660 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
2664 SAM_USERINFO_CTR *ctr = q_u->ctr;
2665 POLICY_HND *pol = &q_u->pol;
2666 uint16 switch_value = q_u->switch_value;
2668 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
2670 r_u->status = NT_STATUS_OK;
2672 /* find the policy handle. open a policy on it. */
2673 if (!get_lsa_policy_samr_sid(p, pol, &sid))
2674 return NT_STATUS_INVALID_HANDLE;
2676 sid_split_rid(&sid, &rid);
2678 DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid));
2681 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
2682 return NT_STATUS_INVALID_INFO_CLASS;
2685 switch_value=ctr->switch_value;
2687 /* ok! user info levels (lots: see MSDEV help), off we go... */
2688 switch (switch_value) {
2690 if (!set_user_info_21(ctr->info.id21, rid))
2691 return NT_STATUS_ACCESS_DENIED;
2694 if (!set_user_info_10(ctr->info.id10, rid))
2695 return NT_STATUS_ACCESS_DENIED;
2698 /* Used by AS/U JRA. */
2699 if (!set_user_info_12(ctr->info.id12, rid))
2700 return NT_STATUS_ACCESS_DENIED;
2703 return NT_STATUS_INVALID_INFO_CLASS;
2709 /*********************************************************************
2710 _samr_query_aliasmem
2711 *********************************************************************/
2713 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
2715 int num_groups = 0, tmp_num_groups=0;
2716 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
2717 struct samr_info *info = NULL;
2719 /* until i see a real useraliases query, we fack one up */
2721 /* I have seen one, JFM 2/12/2001 */
2723 * Explanation of what this call does:
2724 * for all the SID given in the request:
2725 * return a list of alias (local groups)
2726 * that have those SID as members.
2728 * and that's the alias in the domain specified
2729 * in the policy_handle
2731 * if the policy handle is on an incorrect sid
2732 * for example a user's sid
2733 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
2736 r_u->status = NT_STATUS_OK;
2738 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
2740 /* find the policy handle. open a policy on it. */
2741 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
2742 return NT_STATUS_INVALID_HANDLE;
2744 if (!sid_check_is_domain(&info->sid) &&
2745 !sid_check_is_builtin(&info->sid))
2746 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2749 for (i=0; i<q_u->num_sids1; i++) {
2751 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
2754 * if there is an error, we just continue as
2755 * it can be an unfound user or group
2757 if (NT_STATUS_IS_ERR(r_u->status)) {
2758 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
2762 if (tmp_num_groups==0) {
2763 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
2767 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
2768 if (new_rids==NULL) {
2769 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
2770 return NT_STATUS_NO_MEMORY;
2774 for (j=0; j<tmp_num_groups; j++)
2775 rids[j+num_groups]=tmp_rids[j];
2777 safe_free(tmp_rids);
2779 num_groups+=tmp_num_groups;
2782 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
2783 return NT_STATUS_OK;
2786 /*********************************************************************
2787 _samr_query_aliasmem
2788 *********************************************************************/
2790 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
2802 fstring alias_sid_str;
2806 /* find the policy handle. open a policy on it. */
2807 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid))
2808 return NT_STATUS_INVALID_HANDLE;
2810 sid_copy(&als_sid, &alias_sid);
2811 sid_to_string(alias_sid_str, &alias_sid);
2812 sid_split_rid(&alias_sid, &alias_rid);
2814 DEBUG(10, ("sid is %s\n", alias_sid_str));
2816 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
2817 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
2818 if(!get_local_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
2819 return NT_STATUS_NO_SUCH_ALIAS;
2821 if (sid_equal(&alias_sid, &global_sam_sid)) {
2822 DEBUG(10, ("lookup on Server SID\n"));
2823 if(!get_local_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
2824 return NT_STATUS_NO_SUCH_ALIAS;
2828 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
2829 return NT_STATUS_NO_SUCH_ALIAS;
2831 DEBUG(10, ("sid is %s\n", alias_sid_str));
2832 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
2833 if (num_uids!=0 && sid == NULL)
2834 return NT_STATUS_NO_MEMORY;
2836 for (i = 0; i < num_uids; i++) {
2837 sid_copy(&temp_sid, &global_sam_sid);
2838 sid_append_rid(&temp_sid, pdb_uid_to_user_rid(uid[i]));
2840 init_dom_sid2(&sid[i], &temp_sid);
2843 DEBUG(10, ("sid is %s\n", alias_sid_str));
2844 init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
2846 return NT_STATUS_OK;
2849 /*********************************************************************
2850 _samr_query_groupmem
2851 *********************************************************************/
2853 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
2859 fstring group_sid_str;
2868 /* find the policy handle. open a policy on it. */
2869 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid))
2870 return NT_STATUS_INVALID_HANDLE;
2872 /* todo: change to use sid_compare_front */
2874 sid_split_rid(&group_sid, &group_rid);
2875 sid_to_string(group_sid_str, &group_sid);
2876 DEBUG(10, ("sid is %s\n", group_sid_str));
2878 /* can we get a query for an SID outside our domain ? */
2879 if (!sid_equal(&group_sid, &global_sam_sid))
2880 return NT_STATUS_NO_SUCH_GROUP;
2882 sid_append_rid(&group_sid, group_rid);
2883 DEBUG(10, ("lookup on Domain SID\n"));
2885 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
2886 return NT_STATUS_NO_SUCH_GROUP;
2888 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
2889 return NT_STATUS_NO_SUCH_GROUP;
2891 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
2892 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
2894 if (num_uids!=0 && (rid==NULL || attr==NULL))
2895 return NT_STATUS_NO_MEMORY;
2897 for (i=0; i<num_uids; i++) {
2898 rid[i]=pdb_uid_to_user_rid(uid[i]);
2899 attr[i] = SID_NAME_USER;
2902 init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
2904 return NT_STATUS_OK;
2907 /*********************************************************************
2909 *********************************************************************/
2911 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
2914 fstring alias_sid_str;
2922 /* Find the policy handle. Open a policy on it. */
2923 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid))
2924 return NT_STATUS_INVALID_HANDLE;
2926 sid_to_string(alias_sid_str, &alias_sid);
2927 DEBUG(10, ("sid is %s\n", alias_sid_str));
2929 if (sid_compare(&alias_sid, &global_sam_sid)>0) {
2930 DEBUG(10, ("adding member on Server SID\n"));
2931 if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
2932 return NT_STATUS_NO_SUCH_ALIAS;
2935 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
2936 DEBUG(10, ("adding member on BUILTIN SID\n"));
2937 if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
2938 return NT_STATUS_NO_SUCH_ALIAS;
2941 return NT_STATUS_NO_SUCH_ALIAS;
2944 sid_split_rid(&q_u->sid.sid, &rid);
2945 uid=pdb_user_rid_to_uid(rid);
2947 if ((pwd=getpwuid(uid)) == NULL)
2948 return NT_STATUS_NO_SUCH_USER;
2950 if ((grp=getgrgid(map.gid)) == NULL)
2951 return NT_STATUS_NO_SUCH_ALIAS;
2953 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
2954 fstrcpy(grp_name, grp->gr_name);
2956 /* if the user is already in the group */
2957 if(user_in_group_list(pwd->pw_name, grp_name))
2958 return NT_STATUS_MEMBER_IN_ALIAS;
2961 * ok, the group exist, the user exist, the user is not in the group,
2962 * we can (finally) add it to the group !
2964 smb_add_user_group(grp_name, pwd->pw_name);
2966 /* check if the user has been added then ... */
2967 if(!user_in_group_list(pwd->pw_name, grp_name))
2968 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
2970 return NT_STATUS_OK;
2973 /*********************************************************************
2975 *********************************************************************/
2977 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
2979 DEBUG(0,("_samr_del_aliasmem: Not yet implemented.\n"));
2980 return NT_STATUS_NOT_IMPLEMENTED;
2983 /*********************************************************************
2985 *********************************************************************/
2987 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
2990 fstring group_sid_str;
2996 /* Find the policy handle. Open a policy on it. */
2997 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid))
2998 return NT_STATUS_INVALID_HANDLE;
3000 sid_to_string(group_sid_str, &group_sid);
3001 DEBUG(10, ("sid is %s\n", group_sid_str));
3003 if (sid_compare(&group_sid, &global_sam_sid)<=0)
3004 return NT_STATUS_NO_SUCH_GROUP;
3006 DEBUG(10, ("lookup on Domain SID\n"));
3008 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3009 return NT_STATUS_NO_SUCH_GROUP;
3011 if ((pwd=getpwuid(pdb_user_rid_to_uid(q_u->rid))) ==NULL)
3012 return NT_STATUS_NO_SUCH_USER;
3014 if ((grp=getgrgid(map.gid)) == NULL)
3015 return NT_STATUS_NO_SUCH_GROUP;
3017 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3018 fstrcpy(grp_name, grp->gr_name);
3020 /* if the user is already in the group */
3021 if(user_in_group_list(pwd->pw_name, grp_name))
3022 return NT_STATUS_MEMBER_IN_GROUP;
3025 * ok, the group exist, the user exist, the user is not in the group,
3027 * we can (finally) add it to the group !
3030 smb_add_user_group(grp_name, pwd->pw_name);
3032 /* check if the user has been added then ... */
3033 if(!user_in_group_list(pwd->pw_name, grp_name))
3034 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3036 return NT_STATUS_OK;
3039 /*********************************************************************
3041 *********************************************************************/
3043 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3045 DEBUG(0,("_samr_del_groupmem: Not yet implemented.\n"));
3046 return NT_STATUS_NOT_IMPLEMENTED;
3049 /*********************************************************************
3050 _samr_delete_dom_user
3051 *********************************************************************/
3053 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3055 DEBUG(0,("_samr_delete_dom_user: Not yet implemented.\n"));
3056 return NT_STATUS_NOT_IMPLEMENTED;
3059 /*********************************************************************
3060 _samr_delete_dom_group
3061 *********************************************************************/
3063 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3068 fstring group_sid_str;
3073 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3075 /* Find the policy handle. Open a policy on it. */
3076 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid))
3077 return NT_STATUS_INVALID_HANDLE;
3079 sid_copy(&dom_sid, &group_sid);
3080 sid_to_string(group_sid_str, &dom_sid);
3081 sid_split_rid(&dom_sid, &group_rid);
3083 DEBUG(10, ("sid is %s\n", group_sid_str));
3085 /* we check if it's our SID before deleting */
3086 if (!sid_equal(&dom_sid, &global_sam_sid))
3087 return NT_STATUS_NO_SUCH_GROUP;
3089 DEBUG(10, ("lookup on Domain SID\n"));
3091 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3092 return NT_STATUS_NO_SUCH_ALIAS;
3096 /* check if group really exists */
3097 if ( (grp=getgrgid(gid)) == NULL)
3098 return NT_STATUS_NO_SUCH_GROUP;
3100 /* we can delete the UNIX group */
3101 smb_delete_group(grp->gr_name);
3103 /* check if the group has been successfully deleted */
3104 if ( (grp=getgrgid(gid)) != NULL)
3105 return NT_STATUS_ACCESS_DENIED;
3107 if(!group_map_remove(group_sid))
3108 return NT_STATUS_ACCESS_DENIED;
3110 if (!close_policy_hnd(p, &q_u->group_pol))
3111 return NT_STATUS_OBJECT_NAME_INVALID;
3113 return NT_STATUS_OK;
3116 /*********************************************************************
3117 _samr_delete_dom_alias
3118 *********************************************************************/
3120 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3125 fstring alias_sid_str;
3130 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3132 /* Find the policy handle. Open a policy on it. */
3133 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid))
3134 return NT_STATUS_INVALID_HANDLE;
3136 sid_copy(&dom_sid, &alias_sid);
3137 sid_to_string(alias_sid_str, &dom_sid);
3138 sid_split_rid(&dom_sid, &alias_rid);
3140 DEBUG(10, ("sid is %s\n", alias_sid_str));
3142 /* we check if it's our SID before deleting */
3143 if (!sid_equal(&dom_sid, &global_sam_sid))
3144 return NT_STATUS_NO_SUCH_ALIAS;
3146 DEBUG(10, ("lookup on Local SID\n"));
3148 if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3149 return NT_STATUS_NO_SUCH_ALIAS;
3153 /* check if group really exists */
3154 if ( (grp=getgrgid(gid)) == NULL)
3155 return NT_STATUS_NO_SUCH_ALIAS;
3157 /* we can delete the UNIX group */
3158 smb_delete_group(grp->gr_name);
3160 /* check if the group has been successfully deleted */
3161 if ( (grp=getgrgid(gid)) != NULL)
3162 return NT_STATUS_ACCESS_DENIED;
3164 /* don't check if we removed it as it could be an un-mapped group */
3165 group_map_remove(alias_sid);
3167 if (!close_policy_hnd(p, &q_u->alias_pol))
3168 return NT_STATUS_OBJECT_NAME_INVALID;
3170 return NT_STATUS_OK;
3173 /*********************************************************************
3174 _samr_create_dom_group
3175 *********************************************************************/
3177 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3184 struct samr_info *info;
3185 PRIVILEGE_SET priv_set;
3187 init_privilege(&priv_set);
3189 /* Find the policy handle. Open a policy on it. */
3190 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid))
3191 return NT_STATUS_INVALID_HANDLE;
3193 if (!sid_equal(&dom_sid, &global_sam_sid))
3194 return NT_STATUS_ACCESS_DENIED;
3196 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3198 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3200 /* check if group already exist */
3201 if ((grp=getgrnam(name)) != NULL)
3202 return NT_STATUS_GROUP_EXISTS;
3204 /* we can create the UNIX group */
3205 smb_create_group(name);
3207 /* check if the group has been successfully created */
3208 if ((grp=getgrnam(name)) == NULL)
3209 return NT_STATUS_ACCESS_DENIED;
3211 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3213 /* add the group to the mapping table */
3214 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
3215 return NT_STATUS_ACCESS_DENIED;
3217 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
3218 return NT_STATUS_NO_MEMORY;
3222 sid_copy(&info_sid, &global_sam_sid);
3223 sid_append_rid(&info->sid, r_u->rid);
3224 sid_to_string(sid_string, &info->sid);
3226 /* get a (unique) handle. open a policy on it. */
3227 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3228 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3230 return NT_STATUS_OK;
3233 /*********************************************************************
3234 _samr_create_dom_alias
3235 *********************************************************************/
3237 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3243 struct samr_info *info;
3244 PRIVILEGE_SET priv_set;
3246 init_privilege(&priv_set);
3248 /* Find the policy handle. Open a policy on it. */
3249 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid))
3250 return NT_STATUS_INVALID_HANDLE;
3252 if (!sid_equal(&dom_sid, &global_sam_sid))
3253 return NT_STATUS_ACCESS_DENIED;
3255 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3257 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3259 /* check if group already exists */
3260 if ( (grp=getgrnam(name)) != NULL)
3261 return NT_STATUS_GROUP_EXISTS;
3263 /* we can create the UNIX group */
3264 smb_create_group(name);
3266 /* check if the group has been successfully created */
3267 if ((grp=getgrnam(name)) == NULL)
3268 return NT_STATUS_ACCESS_DENIED;
3270 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3272 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
3273 return NT_STATUS_NO_MEMORY;
3277 sid_copy(&info->sid, &global_sam_sid);
3278 sid_append_rid(&info->sid, r_u->rid);
3279 sid_to_string(sid_string, &info->sid);
3281 /* add the group to the mapping table */
3282 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
3283 return NT_STATUS_ACCESS_DENIED;
3285 /* get a (unique) handle. open a policy on it. */
3286 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
3287 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3289 return NT_STATUS_OK;
3292 /*********************************************************************
3293 _samr_query_groupinfo
3295 sends the name/comment pair of a domain group
3296 level 1 send also the number of users of that group
3297 *********************************************************************/
3299 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
3305 GROUP_INFO_CTR *ctr;
3307 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid))
3308 return NT_STATUS_INVALID_HANDLE;
3310 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3311 return NT_STATUS_INVALID_HANDLE;
3313 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
3315 return NT_STATUS_NO_MEMORY;
3317 switch (q_u->switch_level) {
3319 ctr->switch_value1 = 1;
3320 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3321 return NT_STATUS_NO_SUCH_GROUP;
3322 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
3326 ctr->switch_value1 = 4;
3327 init_samr_group_info4(&ctr->group.info4, map.comment);
3330 return NT_STATUS_INVALID_INFO_CLASS;
3333 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
3335 return NT_STATUS_OK;
3338 /*********************************************************************
3341 update a domain group's comment.
3342 *********************************************************************/
3344 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_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_WITH_PRIV))
3354 return NT_STATUS_NO_SUCH_GROUP;
3358 switch (ctr->switch_value1) {
3360 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
3363 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
3366 free_privilege(&map.priv_set);
3367 return NT_STATUS_INVALID_INFO_CLASS;
3370 if(!add_mapping_entry(&map, TDB_REPLACE)) {
3371 free_privilege(&map.priv_set);
3372 return NT_STATUS_NO_SUCH_GROUP;
3375 free_privilege(&map.priv_set);
3377 return NT_STATUS_OK;
3380 /*********************************************************************
3383 update a domain group's comment.
3384 *********************************************************************/
3386 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
3390 ALIAS_INFO_CTR *ctr;
3392 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid))
3393 return NT_STATUS_INVALID_HANDLE;
3395 if (!get_local_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
3396 return NT_STATUS_NO_SUCH_GROUP;
3400 switch (ctr->switch_value1) {
3402 unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
3405 free_privilege(&map.priv_set);
3406 return NT_STATUS_INVALID_INFO_CLASS;
3409 if(!add_mapping_entry(&map, TDB_REPLACE)) {
3410 free_privilege(&map.priv_set);
3411 return NT_STATUS_NO_SUCH_GROUP;
3414 free_privilege(&map.priv_set);
3416 return NT_STATUS_OK;
3419 /*********************************************************************
3420 _samr_get_dom_pwinfo
3421 *********************************************************************/
3423 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
3425 /* Actually, returning zeros here works quite well :-). */
3426 return NT_STATUS_OK;
3429 /*********************************************************************
3431 *********************************************************************/
3433 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
3437 struct samr_info *info;
3440 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid))
3441 return NT_STATUS_INVALID_HANDLE;
3443 /* this should not be hard-coded like this */
3444 if (!sid_equal(&sid, &global_sam_sid))
3445 return NT_STATUS_ACCESS_DENIED;
3447 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
3448 return NT_STATUS_NO_MEMORY;
3452 sid_copy(&info->sid, &global_sam_sid);
3453 sid_append_rid(&info->sid, q_u->rid_group);
3454 sid_to_string(sid_string, &info->sid);
3456 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
3458 /* check if that group really exists */
3459 if (!get_domain_group_from_sid(info->sid, &map, MAPPING_WITHOUT_PRIV))
3460 return NT_STATUS_NO_SUCH_GROUP;
3462 /* get a (unique) handle. open a policy on it. */
3463 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3464 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3466 return NT_STATUS_OK;
3469 /*********************************************************************
3471 *********************************************************************/
3473 NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
3475 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
3476 return NT_STATUS_NOT_IMPLEMENTED;
3479 /*******************************************************************
3481 ********************************************************************/
3483 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
3486 uint32 min_pass_len,pass_hist,flag;
3487 time_t u_expire, u_min_age;
3488 NTTIME nt_expire, nt_min_age;
3490 time_t u_lock_duration, u_reset_time;
3491 NTTIME nt_lock_duration, nt_reset_time;
3497 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
3498 return NT_STATUS_NO_MEMORY;
3502 r_u->status = NT_STATUS_OK;
3504 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
3506 /* find the policy handle. open a policy on it. */
3507 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
3508 return NT_STATUS_INVALID_HANDLE;
3510 switch (q_u->switch_value) {
3512 account_policy_get(AP_MIN_PASSWORD_LEN, &min_pass_len);
3513 account_policy_get(AP_PASSWORD_HISTORY, &pass_hist);
3514 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &flag);
3515 account_policy_get(AP_MAX_PASSWORD_AGE, (int *)&u_expire);
3516 account_policy_get(AP_MIN_PASSWORD_AGE, (int *)&u_min_age);
3518 unix_to_nt_time_abs(&nt_expire, u_expire);
3519 unix_to_nt_time_abs(&nt_min_age, u_min_age);
3521 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
3522 flag, nt_expire, nt_min_age);
3525 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
3526 init_unk_info2(&ctr->info.inf2, global_myworkgroup, global_myname, (uint32) time(NULL));
3529 account_policy_get(AP_TIME_TO_LOGOUT, (int *)&u_logout);
3530 unix_to_nt_time_abs(&nt_logout, u_logout);
3532 init_unk_info3(&ctr->info.inf3, nt_logout);
3535 init_unk_info5(&ctr->info.inf5, global_myname);
3538 init_unk_info6(&ctr->info.inf6);
3541 init_unk_info7(&ctr->info.inf7);
3544 account_policy_get(AP_LOCK_ACCOUNT_DURATION, (int *)&u_lock_duration);
3545 account_policy_get(AP_RESET_COUNT_TIME, (int *)&u_reset_time);
3546 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &lockout);
3548 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
3549 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
3551 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
3554 return NT_STATUS_INVALID_INFO_CLASS;
3557 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
3559 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
3564 /*******************************************************************
3566 ********************************************************************/
3568 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
3570 time_t u_expire, u_min_age;
3572 time_t u_lock_duration, u_reset_time;
3574 r_u->status = NT_STATUS_OK;
3576 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
3578 /* find the policy handle. open a policy on it. */
3579 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
3580 return NT_STATUS_INVALID_HANDLE;
3582 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
3584 switch (q_u->switch_value) {
3586 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
3587 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
3589 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
3590 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
3591 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
3592 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
3593 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
3598 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
3599 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
3608 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
3609 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count);
3611 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
3612 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
3613 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
3616 return NT_STATUS_INVALID_INFO_CLASS;
3619 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
3621 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));