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 int DEBUGLEVEL;
34 extern fstring global_myworkgroup;
35 extern pstring global_myname;
36 extern DOM_SID global_sam_sid;
37 extern DOM_SID global_sid_Builtin;
39 extern rid_name domain_group_rids[];
40 extern rid_name domain_alias_rids[];
41 extern rid_name builtin_alias_rids[];
44 /* for use by the \PIPE\samr policy */
46 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
49 /*******************************************************************
50 Function to free the per handle data.
51 ********************************************************************/
53 static void free_samr_info(void *ptr)
55 struct samr_info *samr = (struct samr_info *)ptr;
60 /*******************************************************************
61 Ensure password info is never given out. Paranioa... JRA.
62 ********************************************************************/
64 static void samr_clear_passwd_fields( SAM_USER_INFO_21 *pass, int num_entries)
71 for (i = 0; i < num_entries; i++) {
72 memset(&pass[i].lm_pwd, '\0', sizeof(pass[i].lm_pwd));
73 memset(&pass[i].nt_pwd, '\0', sizeof(pass[i].nt_pwd));
77 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
82 if (sam_pass->lm_pw) memset(sam_pass->lm_pw, '\0', 16);
83 if (sam_pass->nt_pw) memset(sam_pass->nt_pw, '\0', 16);
86 /*******************************************************************
87 This next function should be replaced with something that
88 dynamically returns the correct user info..... JRA.
89 ********************************************************************/
91 static uint32 get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx,
92 int *total_entries, int *num_entries,
93 int max_num_entries, uint16 acb_mask)
95 SAM_ACCOUNT *pwd = NULL;
96 BOOL not_finished = True;
102 return NT_STATUS_NO_MEMORY;
106 if (!pdb_setsampwent(False)) {
107 DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n"));
109 return NT_STATUS_ACCESS_DENIED;
112 while (((not_finished = pdb_getsampwent(pwd)) != False)
113 && (*num_entries) < max_num_entries)
118 /* skip the requested number of entries.
119 not very efficient, but hey... */
124 user_name_len = strlen(pdb_get_username(pwd))+1;
125 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pdb_get_username(pwd), user_name_len);
126 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
127 pw_buf[(*num_entries)].user_rid = pwd->user_rid;
128 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
130 /* Now check if the NT compatible password is available. */
131 if (pdb_get_nt_passwd(pwd))
132 memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
134 pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
136 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
137 (*num_entries), pdb_get_username(pwd), pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd) ));
139 if (acb_mask == 0 || (pwd->acct_ctrl & acb_mask)) {
140 DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
144 DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
153 return STATUS_MORE_ENTRIES;
155 return NT_STATUS_NOPROBLEMO;
158 static uint32 jf_get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx,
159 int *total_entries, uint32 *num_entries,
160 int max_num_entries, uint16 acb_mask)
162 SAM_ACCOUNT *pwd = NULL;
163 BOOL not_finished = True;
169 return NT_STATUS_NO_MEMORY;
171 DEBUG(10,("jf_get_sampwd_entries: start index:%d, max entries:%d, mask:%d\n",
172 start_idx, max_num_entries, acb_mask));
174 if (!pdb_setsampwent(False)) {
175 DEBUG(0, ("jf_get_sampwd_entries: Unable to open passdb.\n"));
176 return NT_STATUS_ACCESS_DENIED;
181 while (((not_finished = pdb_getsampwent(pwd)) != False) && (*num_entries) < max_num_entries) {
185 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
191 /* skip the requested number of entries.
192 not very efficient, but hey...
199 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
201 user_name_len = strlen(pdb_get_username(pwd));
202 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pdb_get_username(pwd), user_name_len);
203 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
205 full_name_len = strlen(pdb_get_fullname(pwd));
206 init_unistr2(&pw_buf[(*num_entries)].uni_full_name, pdb_get_fullname(pwd), full_name_len);
207 init_uni_hdr(&pw_buf[(*num_entries)].hdr_full_name, full_name_len);
209 pw_buf[(*num_entries)].user_rid = pdb_get_user_rid(pwd);
210 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
212 /* Now check if the NT compatible password is available. */
213 if (pdb_get_nt_passwd(pwd))
214 memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
216 pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
218 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x\n", (*num_entries),
219 pdb_get_username(pwd), pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd) ));
228 *total_entries = *num_entries;
233 return STATUS_MORE_ENTRIES;
235 return NT_STATUS_NOPROBLEMO;
238 #if 0 /* This function appears to be unused! */
240 /*******************************************************************
241 This function uses the username map file and tries to map a UNIX
242 user name to an DOS name. (Sort of the reverse of the
243 map_username() function.) Since more than one DOS name can map
244 to the UNIX name, to reverse the mapping you have to specify
245 which corresponding DOS name you want; that's where the name_idx
246 parameter comes in. Returns the string requested or NULL if it
247 fails or can't complete the request for any reason. This doesn't
248 handle group names (starting with '@') or names starting with
249 '+' or '&'. If they are encountered, they are skipped.
250 ********************************************************************/
252 static char *unmap_unixname(char *unix_user_name, int name_idx)
254 char *mapfile = lp_username_map();
259 if (!*unix_user_name) return NULL;
260 if (!*mapfile) return NULL;
262 lines = file_lines_load(mapfile, NULL);
264 DEBUG(0,("unmap_unixname: can't open username map %s\n", mapfile));
268 DEBUG(5,("unmap_unixname: scanning username map %s, index: %d\n", mapfile, name_idx));
270 for (i=0; lines[i]; i++) {
271 char *unixname = lines[i];
272 char *dosname = strchr_m(unixname,'=');
279 while (isspace(*unixname))
281 if ('!' == *unixname) {
283 while (*unixname && isspace(*unixname))
287 if (!*unixname || strchr_m("#;",*unixname))
290 if (strncmp(unixname, unix_user_name, strlen(unix_user_name)))
293 /* We have matched the UNIX user name */
295 while(next_token(&dosname, tok, LIST_SEP, sizeof(tok))) {
296 if (!strchr_m("@&+", *tok)) {
305 DEBUG(0,("unmap_unixname: index too high - not that many DOS names\n"));
306 file_lines_free(lines);
309 file_lines_free(lines);
314 DEBUG(0,("unmap_unixname: Couldn't find the UNIX user name\n"));
315 file_lines_free(lines);
319 #endif /* Unused function */
321 #if 0 /* This function seems to be not used anywhere! */
323 /*******************************************************************
324 This function sets up a list of users taken from the list of
325 users that UNIX knows about, as well as all the user names that
326 Samba maps to a valid UNIX user name. (This should work with
328 ********************************************************************/
330 static BOOL get_passwd_entries(SAM_USER_INFO_21 *pw_buf,
332 int *total_entries, int *num_entries,
336 static struct passwd *pwd = NULL;
337 static uint32 pw_rid;
338 static BOOL orig_done = False;
339 static int current_idx = 0;
340 static int mapped_idx = 0;
343 DEBUG(5, ("get_passwd_entries: retrieving a list of UNIX users\n"));
346 (*total_entries) = 0;
348 /* Skip all this stuff if we're in appliance mode */
350 if (lp_hide_local_users()) goto done;
352 if (pw_buf == NULL) return False;
354 if (current_idx == 0) {
358 /* These two cases are inefficient, but should be called very rarely */
359 /* they are the cases where the starting index isn't picking up */
360 /* where we left off last time. It is efficient when it starts over */
361 /* at zero though. */
362 if (start_idx > current_idx) {
363 /* We aren't far enough; advance to start_idx */
364 while (current_idx <= start_idx) {
368 if ((pwd = sys_getpwent()) == NULL) break;
373 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
374 (current_idx < start_idx)) {
379 if (unmap_name == NULL) {
384 } else if (start_idx < current_idx) {
385 /* We are already too far; start over and advance to start_idx */
391 while (current_idx < start_idx) {
395 if ((pwd = sys_getpwent()) == NULL) break;
400 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
401 (current_idx < start_idx)) {
406 if (unmap_name == NULL) {
413 sep = lp_winbind_separator();
415 /* now current_idx == start_idx */
416 while ((*num_entries) < max_num_entries) {
420 /* This does the original UNIX user itself */
422 if ((pwd = sys_getpwent()) == NULL) break;
424 /* Don't enumerate winbind users as they are not local */
426 if (strchr_m(pwd->pw_name, *sep) != NULL) {
430 user_name_len = strlen(pwd->pw_name);
432 /* skip the trust account stored in the /etc/passwd file */
433 if (pwd->pw_name[user_name_len-1]=='$')
436 pw_rid = pdb_uid_to_user_rid(pwd->pw_uid);
437 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
438 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pwd->pw_name, user_name_len);
439 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
440 pw_buf[(*num_entries)].user_rid = pw_rid;
441 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
443 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
445 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
453 /* This does all the user names that map to the UNIX user */
454 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
455 (*num_entries < max_num_entries)) {
456 user_name_len = strlen(unmap_name);
457 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
458 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, unmap_name, user_name_len);
459 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
460 pw_buf[(*num_entries)].user_rid = pw_rid;
461 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
463 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
465 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
473 if (unmap_name == NULL) {
474 /* done with 'aliases', go on to next UNIX user */
481 /* totally done, reset everything */
488 return (*num_entries) > 0;
491 #endif /* Unused function */
493 /*******************************************************************
495 ********************************************************************/
497 uint32 _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
499 r_u->status = NT_STATUS_NOPROBLEMO;
501 /* close the policy handle */
502 if (!close_policy_hnd(p, &q_u->pol))
503 return NT_STATUS_OBJECT_NAME_INVALID;
505 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
510 /*******************************************************************
511 samr_reply_open_domain
512 ********************************************************************/
514 uint32 _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
516 struct samr_info *info;
518 r_u->status = NT_STATUS_NOPROBLEMO;
520 /* find the connection policy handle. */
521 if (!find_policy_by_hnd(p, &q_u->pol, NULL))
522 return NT_STATUS_INVALID_HANDLE;
524 /* associate the domain SID with the (unique) handle. */
525 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
526 return NT_STATUS_NO_MEMORY;
529 info->sid = q_u->dom_sid.sid;
531 /* get a (unique) handle. open a policy on it. */
532 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
533 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
535 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
540 static uint32 get_lsa_policy_samr_rid(struct samr_info *info)
543 DEBUG(3,("Error getting policy\n"));
547 return info->sid.sub_auths[info->sid.num_auths-1];
550 /*******************************************************************
551 _samr_get_usrdom_pwinfo
552 ********************************************************************/
554 uint32 _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
556 struct samr_info *info = NULL;
558 r_u->status = NT_STATUS_NOPROBLEMO;
560 /* find the policy handle. open a policy on it. */
561 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info)) {
562 return NT_STATUS_INVALID_HANDLE;
565 /* find the user's rid */
566 if (get_lsa_policy_samr_rid(info) == 0xffffffff) {
567 return NT_STATUS_OBJECT_TYPE_MISMATCH;
570 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_NOPROBLEMO);
572 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
577 /*******************************************************************
579 ********************************************************************/
581 static uint32 samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC_BUF **buf, DOM_SID *usr_sid)
583 extern DOM_SID global_sid_World;
591 SEC_DESC *psd = NULL;
594 sid_copy(&adm_sid, &global_sid_Builtin);
595 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
597 sid_copy(&act_sid, &global_sid_Builtin);
598 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
600 init_sec_access(&mask, 0x2035b);
601 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
603 init_sec_access(&mask, 0xf07ff);
604 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
605 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
607 init_sec_access(&mask,0x20044);
608 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
610 if((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
611 return NT_STATUS_NO_MEMORY;
613 if((psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, &sd_size)) == NULL)
614 return NT_STATUS_NO_MEMORY;
616 if((*buf = make_sec_desc_buf(ctx, sd_size, psd)) == NULL)
617 return NT_STATUS_NO_MEMORY;
619 return NT_STATUS_NOPROBLEMO;
622 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid)
624 struct samr_info *info = NULL;
626 /* find the policy handle. open a policy on it. */
627 if (!find_policy_by_hnd(p, pol, (void **)&info))
637 /*******************************************************************
639 ********************************************************************/
641 uint32 _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
645 r_u->status = NT_STATUS_NOPROBLEMO;
649 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid))
650 return NT_STATUS_INVALID_HANDLE;
652 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &r_u->buf, &pol_sid);
654 if (r_u->status == NT_STATUS_NOPROBLEMO)
660 /*******************************************************************
661 makes a SAM_ENTRY / UNISTR2* structure from a user list.
662 ********************************************************************/
664 static void make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
665 uint32 num_sam_entries, SAM_USER_INFO_21 *pass)
674 if (num_sam_entries == 0)
677 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
679 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
681 if (sam == NULL || uni_name == NULL) {
682 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
687 ZERO_STRUCTP(uni_name);
689 for (i = 0; i < num_sam_entries; i++) {
690 int len = pass[i].uni_user_name.uni_str_len;
692 init_sam_entry(&sam[i], len, pass[i].user_rid);
693 copy_unistr2(&uni_name[i], &pass[i].uni_user_name);
697 *uni_name_pp = uni_name;
700 /*******************************************************************
701 samr_reply_enum_dom_users
702 ********************************************************************/
704 uint32 _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_ENUM_DOM_USERS *r_u)
706 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
708 int total_entries = 0;
710 r_u->status = NT_STATUS_NOPROBLEMO;
712 /* find the policy handle. open a policy on it. */
713 if (!find_policy_by_hnd(p, &q_u->pol, NULL))
714 return NT_STATUS_INVALID_HANDLE;
716 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
719 r_u->status = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
720 MAX_SAM_ENTRIES, q_u->acb_mask);
723 if (r_u->status != NT_STATUS_NOPROBLEMO && r_u->status != STATUS_MORE_ENTRIES)
726 samr_clear_passwd_fields(pass, num_entries);
729 * Note from JRA. total_entries is not being used here. Currently if there is a
730 * large user base then it looks like NT will enumerate until get_sampwd_entries
731 * returns False due to num_entries being zero. This will cause an access denied
732 * return. I don't think this is right and needs further investigation. Note that
733 * this is also the same in the TNG code (I don't think that has been tested with
734 * a very large user list as MAX_SAM_ENTRIES is set to 600).
736 * I also think that one of the 'num_entries' return parameters is probably
737 * the "max entries" parameter - but in the TNG code they're all currently set to the same
738 * value (again I think this is wrong).
741 make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name, num_entries, pass);
743 init_samr_r_enum_dom_users(r_u, q_u->start_idx + num_entries, num_entries);
745 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
750 /*******************************************************************
751 makes a SAM_ENTRY / UNISTR2* structure from a group list.
752 ********************************************************************/
754 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
755 uint32 num_sam_entries, DOMAIN_GRP *grp)
764 if (num_sam_entries == 0)
767 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
769 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
771 if (sam == NULL || uni_name == NULL) {
772 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
776 for (i = 0; i < num_sam_entries; i++) {
778 * JRA. I think this should include the null. TNG does not.
780 int len = strlen(grp[i].name)+1;
782 init_sam_entry(&sam[i], len, grp[i].rid);
783 init_unistr2(&uni_name[i], grp[i].name, len);
787 *uni_name_pp = uni_name;
790 /*******************************************************************
791 Get the group entries - similar to get_sampwd_entries().
792 ********************************************************************/
794 static BOOL get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
795 uint32 *p_num_entries, uint32 max_entries)
798 uint32 num_entries = 0;
803 sid_to_string(sid_str, sid);
804 DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str));
808 /* well-known aliases */
809 if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
811 enum_group_mapping(SID_NAME_WKN_GRP, &map, (int *)&num_entries, ENUM_ALL_MAPPED);
813 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
815 return NT_STATUS_NO_MEMORY;
817 for(i=0; i<num_entries && i<max_entries; i++) {
818 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
819 sid_split_rid(&map[i].sid, &(*d_grp)[i].rid);
825 } else if (sid_equal(sid, &global_sam_sid) && !lp_hide_local_users()) {
827 struct sys_grent *glist;
828 struct sys_grent *grp;
830 sep = lp_winbind_separator();
833 /* we return the UNIX groups here. This seems to be the right */
834 /* thing to do, since NT member servers return their local */
835 /* groups in the same situation. */
837 /* use getgrent_list() to retrieve the list of groups to avoid
838 * problems with getgrent possible infinite loop by internal
839 * libc grent structures overwrites by called functions */
840 grp = glist = getgrent_list();
842 return NT_STATUS_NO_MEMORY;
844 for (; (num_entries < max_entries) && (grp != NULL); grp = grp->next) {
847 if(!get_group_from_gid(grp->gr_gid, &smap)) {
851 if (smap.sid_name_use!=SID_NAME_ALIAS) {
855 sid_split_rid(&smap.sid, &trid);
857 /* Don't return winbind groups as they are not local! */
858 if (strchr_m(smap.nt_name, *sep) != NULL) {
859 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
863 /* Don't return user private groups... */
864 if (Get_Pwnam(smap.nt_name, False) != 0) {
865 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
869 for( i = 0; i < num_entries; i++)
870 if ( (*d_grp)[i].rid == trid )
873 if ( i < num_entries )
874 continue; /* rid was there, dup! */
876 /* JRA - added this for large group db enumeration... */
879 /* skip the requested number of entries.
880 not very efficient, but hey...
886 *d_grp=talloc_realloc(ctx,*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
889 return NT_STATUS_NO_MEMORY;
892 fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
893 (*d_grp)[num_entries].rid = trid;
895 DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries, trid));
901 *p_num_entries = num_entries;
903 DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries));
905 return NT_STATUS_NOPROBLEMO;
908 /*******************************************************************
909 Get the group entries - similar to get_sampwd_entries().
910 ********************************************************************/
912 static uint32 get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
913 uint32 *p_num_entries, uint32 max_entries)
917 uint32 group_entries = 0;
918 uint32 num_entries = 0;
922 enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
924 num_entries=group_entries-start_idx;
926 /* limit the number of entries */
927 if (num_entries>max_entries) {
928 DEBUG(5,("Limiting to %d entries\n", max_entries));
929 num_entries=max_entries;
932 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
933 if (num_entries!=0 && *d_grp==NULL){
935 return NT_STATUS_NO_MEMORY;
938 for (i=0; i<num_entries; i++) {
939 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
940 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
941 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
942 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
947 *p_num_entries = num_entries;
949 return NT_STATUS_NOPROBLEMO;
952 /*******************************************************************
953 samr_reply_enum_dom_groups
954 Only reply with one group - domain admins. This must be fixed for
956 ********************************************************************/
958 uint32 _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
960 DOMAIN_GRP *grp=NULL;
964 r_u->status = NT_STATUS_NOPROBLEMO;
966 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
967 return NT_STATUS_INVALID_HANDLE;
969 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
971 /* the domain group array is being allocated in the function below */
972 get_group_domain_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES);
974 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
976 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
978 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
984 /*******************************************************************
985 samr_reply_enum_dom_aliases
986 ********************************************************************/
988 uint32 _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
990 DOMAIN_GRP *grp=NULL;
991 uint32 num_entries = 0;
995 r_u->status = NT_STATUS_NOPROBLEMO;
997 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
998 return NT_STATUS_INVALID_HANDLE;
1000 sid_to_string(sid_str, &sid);
1001 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1003 if (get_group_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES)!=NT_STATUS_NOPROBLEMO)
1004 return NT_STATUS_ACCESS_DENIED;
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);
1012 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1017 /*******************************************************************
1018 samr_reply_query_dispinfo
1019 ********************************************************************/
1021 uint32 _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_NOPROBLEMO;
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 (r_u->status!=STATUS_MORE_ENTRIES && r_u->status!=NT_STATUS_NOPROBLEMO) {
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 (r_u->status != NT_STATUS_NOPROBLEMO)
1084 return NT_STATUS_ACCESS_DENIED;
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 (disp_ret != NT_STATUS_NOPROBLEMO)
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 (disp_ret != NT_STATUS_NOPROBLEMO)
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 (disp_ret != NT_STATUS_NOPROBLEMO)
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 (disp_ret != NT_STATUS_NOPROBLEMO)
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 (disp_ret != NT_STATUS_NOPROBLEMO)
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 uint32 _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;
1183 struct samr_info *info = NULL;
1185 r_u->status = NT_STATUS_NOPROBLEMO;
1187 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1189 /* find the policy handle. open a policy on it. */
1190 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1191 return NT_STATUS_INVALID_HANDLE;
1193 alias_rid = get_lsa_policy_samr_rid(info);
1194 if(alias_rid == 0xffffffff)
1195 return NT_STATUS_NO_SUCH_ALIAS;
1197 if(!local_lookup_rid(alias_rid, alias, &type))
1198 return NT_STATUS_NO_SUCH_ALIAS;
1200 switch (q_u->switch_level) {
1203 r_u->ctr.switch_value1 = 3;
1204 init_samr_alias_info3(&r_u->ctr.alias.info3, alias_desc);
1207 return NT_STATUS_INVALID_INFO_CLASS;
1210 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1216 /*******************************************************************
1217 samr_reply_lookup_ids
1218 ********************************************************************/
1220 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1222 uint32 rid[MAX_SAM_ENTRIES];
1223 int num_rids = q_u->num_sids1;
1225 r_u->status = NT_STATUS_NOPROBLEMO;
1227 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1229 if (num_rids > MAX_SAM_ENTRIES) {
1230 num_rids = MAX_SAM_ENTRIES;
1231 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1236 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1238 for (i = 0; i < num_rids && status == 0; i++)
1240 struct sam_passwd *sam_pass;
1244 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1245 q_u->uni_user_name[i].uni_str_len));
1247 /* find the user account */
1249 sam_pass = get_smb21pwd_entry(user_name, 0);
1252 if (sam_pass == NULL)
1254 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1259 rid[i] = sam_pass->user_rid;
1265 rid[0] = BUILTIN_ALIAS_RID_USERS;
1267 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_NOPROBLEMO);
1269 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1275 /*******************************************************************
1277 ********************************************************************/
1279 uint32 _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1281 uint32 rid[MAX_SAM_ENTRIES];
1282 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1284 int num_rids = q_u->num_names2;
1287 r_u->status = NT_STATUS_NOPROBLEMO;
1289 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1294 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid)) {
1295 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1299 if (num_rids > MAX_SAM_ENTRIES) {
1300 num_rids = MAX_SAM_ENTRIES;
1301 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1304 for (i = 0; i < num_rids; i++) {
1307 r_u->status = NT_STATUS_NONE_MAPPED;
1309 rid [i] = 0xffffffff;
1310 type[i] = SID_NAME_UNKNOWN;
1312 rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1314 if(sid_equal(&pol_sid, &global_sam_sid)) {
1316 if(local_lookup_name(global_myname, name, &sid, &type[i])) {
1317 sid_split_rid( &sid, &rid[i]);
1318 r_u->status = NT_STATUS_NOPROBLEMO;
1323 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1325 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1330 /*******************************************************************
1331 _samr_chgpasswd_user
1332 ********************************************************************/
1334 uint32 _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1339 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1341 r_u->status = NT_STATUS_NOPROBLEMO;
1343 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1344 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len,0);
1346 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1349 * Pass the user through the NT -> unix user mapping
1353 (void)map_username(user_name);
1356 * Do any UNIX username case mangling.
1358 (void)Get_Pwnam( user_name, True);
1360 if (!pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1361 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1362 r_u->status = NT_STATUS_WRONG_PASSWORD;
1364 init_samr_r_chgpasswd_user(r_u, r_u->status);
1366 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1371 /*******************************************************************
1372 makes a SAMR_R_LOOKUP_RIDS structure.
1373 ********************************************************************/
1375 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1376 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1379 UNIHDR *hdr_name=NULL;
1380 UNISTR2 *uni_name=NULL;
1382 *pp_uni_name = NULL;
1383 *pp_hdr_name = NULL;
1385 if (num_names != 0) {
1386 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1387 if (hdr_name == NULL)
1390 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1391 if (uni_name == NULL)
1395 for (i = 0; i < num_names; i++) {
1396 int len = names[i] != NULL ? strlen(names[i]) : 0;
1397 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1398 init_uni_hdr(&hdr_name[i], len);
1399 init_unistr2(&uni_name[i], names[i], len);
1402 *pp_uni_name = uni_name;
1403 *pp_hdr_name = hdr_name;
1408 /*******************************************************************
1410 ********************************************************************/
1412 uint32 _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1414 fstring group_names[MAX_SAM_ENTRIES];
1415 uint32 *group_attrs = NULL;
1416 UNIHDR *hdr_name = NULL;
1417 UNISTR2 *uni_name = NULL;
1419 int num_rids = q_u->num_rids1;
1422 r_u->status = NT_STATUS_NOPROBLEMO;
1424 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1426 /* find the policy handle. open a policy on it. */
1427 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid))
1428 return NT_STATUS_INVALID_HANDLE;
1430 if (num_rids > MAX_SAM_ENTRIES) {
1431 num_rids = MAX_SAM_ENTRIES;
1432 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1436 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1437 return NT_STATUS_NO_MEMORY;
1440 r_u->status = NT_STATUS_NONE_MAPPED;
1442 for (i = 0; i < num_rids; i++) {
1446 enum SID_NAME_USE type;
1448 group_attrs[i] = SID_NAME_UNKNOWN;
1449 *group_names[i] = '\0';
1451 if (sid_equal(&pol_sid, &global_sam_sid)) {
1452 sid_copy(&sid, &pol_sid);
1453 sid_append_rid(&sid, q_u->rid[i]);
1455 if (lookup_sid(&sid, domname, tmpname, &type)) {
1456 r_u->status = NT_STATUS_NOPROBLEMO;
1457 group_attrs[i] = (uint32)type;
1458 fstrcpy(group_names[i],tmpname);
1459 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1464 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1465 return NT_STATUS_NO_MEMORY;
1467 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1469 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1474 /*******************************************************************
1475 _api_samr_open_user. Safe - gives out no passwd info.
1476 ********************************************************************/
1478 uint32 _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1480 SAM_ACCOUNT *sampass=NULL;
1482 POLICY_HND domain_pol = q_u->domain_pol;
1483 uint32 user_rid = q_u->user_rid;
1484 POLICY_HND *user_pol = &r_u->user_pol;
1485 struct samr_info *info = NULL;
1488 r_u->status = NT_STATUS_NOPROBLEMO;
1490 /* find the domain policy handle. */
1491 if (!find_policy_by_hnd(p, &domain_pol, NULL))
1492 return NT_STATUS_INVALID_HANDLE;
1494 pdb_init_sam(&sampass);
1497 ret=pdb_getsampwrid(sampass, user_rid);
1500 /* check that the RID exists in our domain. */
1502 pdb_free_sam(sampass);
1503 return NT_STATUS_NO_SUCH_USER;
1506 samr_clear_sam_passwd(sampass);
1507 pdb_free_sam(sampass);
1509 /* Get the domain SID stored in the domain policy */
1510 if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
1511 return NT_STATUS_INVALID_HANDLE;
1513 /* append the user's RID to it */
1514 if(!sid_append_rid(&sid, user_rid))
1515 return NT_STATUS_NO_SUCH_USER;
1517 /* associate the user's SID with the new handle. */
1518 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
1519 return NT_STATUS_NO_MEMORY;
1524 /* get a (unique) handle. open a policy on it. */
1525 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1526 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1531 /*************************************************************************
1532 get_user_info_10. Safe. Only gives out acb bits.
1533 *************************************************************************/
1535 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1537 SAM_ACCOUNT *smbpass=NULL;
1540 if (!pdb_rid_is_user(user_rid)) {
1541 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1545 pdb_init_sam(&smbpass);
1548 ret = pdb_getsampwrid(smbpass, user_rid);
1552 DEBUG(4,("User 0x%x not found\n", user_rid));
1553 pdb_free_sam(smbpass);
1557 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1560 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1562 samr_clear_sam_passwd(smbpass);
1563 pdb_free_sam(smbpass);
1568 /*************************************************************************
1569 get_user_info_12. OK - this is the killer as it gives out password info.
1570 Ensure that this is only allowed on an encrypted connection with a root
1572 *************************************************************************/
1574 static uint32 get_user_info_12(pipes_struct *p, SAM_USER_INFO_12 * id12, uint32 user_rid)
1576 SAM_ACCOUNT *smbpass=NULL;
1579 if (!p->ntlmssp_auth_validated)
1580 return NT_STATUS_ACCESS_DENIED;
1582 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1583 return NT_STATUS_ACCESS_DENIED;
1586 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1588 pdb_init_sam(&smbpass);
1590 ret = pdb_getsampwrid(smbpass, user_rid);
1593 DEBUG(4, ("User 0x%x not found\n", user_rid));
1594 pdb_free_sam(smbpass);
1595 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1598 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1600 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1601 pdb_free_sam(smbpass);
1602 return NT_STATUS_ACCOUNT_DISABLED;
1606 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1608 pdb_free_sam(smbpass);
1610 return NT_STATUS_NOPROBLEMO;
1613 /*************************************************************************
1615 *************************************************************************/
1617 static BOOL get_user_info_20(SAM_USER_INFO_20 *id20, uint32 user_rid)
1619 SAM_ACCOUNT *sampass=NULL;
1622 if (!pdb_rid_is_user(user_rid)) {
1623 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1627 pdb_init_sam(&sampass);
1630 ret = pdb_getsampwrid(sampass, user_rid);
1634 DEBUG(4,("User 0x%x not found\n", user_rid));
1635 pdb_free_sam(sampass);
1639 samr_clear_sam_passwd(sampass);
1641 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1644 init_sam_user_info20A(id20, sampass);
1646 pdb_free_sam(sampass);
1651 /*************************************************************************
1653 *************************************************************************/
1655 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1657 SAM_ACCOUNT *sampass=NULL;
1660 if (!pdb_rid_is_user(user_rid)) {
1661 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1665 pdb_init_sam(&sampass);
1668 ret = pdb_getsampwrid(sampass, user_rid);
1672 DEBUG(4,("User 0x%x not found\n", user_rid));
1673 pdb_free_sam(sampass);
1677 samr_clear_sam_passwd(sampass);
1679 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1682 init_sam_user_info21A(id21, sampass);
1684 pdb_free_sam(sampass);
1689 /*******************************************************************
1690 _samr_query_userinfo
1691 ********************************************************************/
1693 uint32 _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1695 SAM_USERINFO_CTR *ctr;
1697 struct samr_info *info = NULL;
1699 r_u->status=NT_STATUS_NOPROBLEMO;
1701 /* search for the handle */
1702 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1703 return NT_STATUS_INVALID_HANDLE;
1705 /* find the user's rid */
1706 if ((rid = get_lsa_policy_samr_rid(info)) == 0xffffffff)
1707 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1709 DEBUG(5,("_samr_query_userinfo: rid:0x%x\n", rid));
1711 ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1713 return NT_STATUS_NO_MEMORY;
1717 /* ok! user info levels (lots: see MSDEV help), off we go... */
1718 ctr->switch_value = q_u->switch_value;
1720 switch (q_u->switch_value) {
1722 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1723 if (ctr->info.id10 == NULL)
1724 return NT_STATUS_NO_MEMORY;
1726 if (!get_user_info_10(ctr->info.id10, rid))
1727 return NT_STATUS_NO_SUCH_USER;
1731 /* whoops - got this wrong. i think. or don't understand what's happening. */
1735 info = (void *)&id11;
1737 expire.low = 0xffffffff;
1738 expire.high = 0x7fffffff;
1740 ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1745 ZERO_STRUCTP(ctr->info.id11);
1746 init_sam_user_info11(ctr->info.id11, &expire,
1747 "BROOKFIELDS$", /* name */
1748 0x03ef, /* user rid */
1749 0x201, /* group rid */
1750 0x0080); /* acb info */
1757 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1758 if (ctr->info.id12 == NULL)
1759 return NT_STATUS_NO_MEMORY;
1761 if ((r_u->status = get_user_info_12(p, ctr->info.id12, rid)) != NT_STATUS_NOPROBLEMO)
1766 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1767 if (ctr->info.id20 == NULL)
1768 return NT_STATUS_NO_MEMORY;
1769 if (!get_user_info_20(ctr->info.id20, rid))
1770 return NT_STATUS_NO_SUCH_USER;
1774 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1775 if (ctr->info.id21 == NULL)
1776 return NT_STATUS_NO_MEMORY;
1777 if (!get_user_info_21(ctr->info.id21, rid))
1778 return NT_STATUS_NO_SUCH_USER;
1782 return NT_STATUS_INVALID_INFO_CLASS;
1785 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1787 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1792 /*******************************************************************
1793 samr_reply_query_usergroups
1794 ********************************************************************/
1796 uint32 _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1798 SAM_ACCOUNT *sam_pass=NULL;
1799 DOM_GID *gids = NULL;
1803 struct samr_info *info = NULL;
1806 r_u->status = NT_STATUS_NOPROBLEMO;
1808 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1810 /* find the policy handle. open a policy on it. */
1811 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1812 return NT_STATUS_INVALID_HANDLE;
1814 /* find the user's rid */
1815 if ((rid = get_lsa_policy_samr_rid(info)) == 0xffffffff)
1816 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1818 pdb_init_sam(&sam_pass);
1821 ret = pdb_getsampwrid(sam_pass, rid);
1825 samr_clear_sam_passwd(sam_pass);
1826 return NT_STATUS_NO_SUCH_USER;
1829 get_domain_user_groups(groups, pdb_get_username(sam_pass));
1831 num_groups = make_dom_gids(p->mem_ctx, groups, &gids);
1833 /* construct the response. lkclXXXX: gids are not copied! */
1834 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
1836 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1838 samr_clear_sam_passwd(sam_pass);
1843 /*******************************************************************
1844 _samr_query_dom_info
1845 ********************************************************************/
1847 uint32 _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
1851 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
1852 return NT_STATUS_NO_MEMORY;
1856 r_u->status = NT_STATUS_NOPROBLEMO;
1858 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
1860 /* find the policy handle. open a policy on it. */
1861 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
1862 return NT_STATUS_INVALID_HANDLE;
1864 switch (q_u->switch_value) {
1866 init_unk_info1(&ctr->info.inf1);
1869 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
1870 init_unk_info2(&ctr->info.inf2, global_myworkgroup, global_myname, (uint32) time(NULL));
1873 init_unk_info3(&ctr->info.inf3);
1876 init_unk_info5(&ctr->info.inf5, global_myname);
1879 init_unk_info6(&ctr->info.inf6);
1882 init_unk_info7(&ctr->info.inf7);
1885 init_unk_info12(&ctr->info.inf12);
1888 return NT_STATUS_INVALID_INFO_CLASS;
1891 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_NOPROBLEMO);
1893 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
1898 /*******************************************************************
1899 _api_samr_create_user
1900 ********************************************************************/
1902 uint32 _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
1904 SAM_ACCOUNT *sam_pass=NULL;
1911 POLICY_HND dom_pol = q_u->domain_pol;
1912 UNISTR2 user_account = q_u->uni_name;
1913 uint16 acb_info = q_u->acb_info;
1914 POLICY_HND *user_pol = &r_u->user_pol;
1915 struct samr_info *info = NULL;
1918 /* find the policy handle. open a policy on it. */
1919 if (!find_policy_by_hnd(p, &dom_pol, NULL))
1920 return NT_STATUS_INVALID_HANDLE;
1922 /* find the machine account: tell the caller if it exists.
1923 lkclXXXX i have *no* idea if this is a problem or not
1924 or even if you are supposed to construct a different
1925 reply if the account already exists...
1928 rpcstr_pull(mach_acct, user_account.buffer, sizeof(mach_acct), user_account.uni_str_len*2, 0);
1929 strlower(mach_acct);
1931 pdb_init_sam(&sam_pass);
1934 ret = pdb_getsampwnam(sam_pass, mach_acct);
1937 /* machine account exists: say so */
1938 pdb_free_sam(sam_pass);
1939 return NT_STATUS_USER_EXISTS;
1942 local_flags=LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_SET_NO_PASSWORD;
1943 local_flags|= (acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0;
1946 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
1947 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
1948 * that only people with write access to the smbpasswd file will be able
1949 * to create a user. JRA.
1953 * add the user in the /etc/passwd file or the unix authority system.
1954 * We don't check if the smb_create_user() function succed or not for 2 reasons:
1955 * a) local_password_change() checks for us if the /etc/passwd account really exists
1956 * b) smb_create_user() would return an error if the account already exists
1957 * and as it could return an error also if it can't create the account, it would be tricky.
1959 * So we go the easy way, only check after if the account exists.
1960 * JFM (2/3/2001), to clear any possible bad understanding (-:
1963 pstrcpy(add_script, lp_addmachine_script());
1966 pstrcpy(add_script, lp_adduser_script());
1971 all_string_sub(add_script, "%u", mach_acct, sizeof(mach_acct));
1972 add_ret = smbrun(add_script,NULL);
1973 DEBUG(3,("_api_samr_create_user: Running the command `%s' gave %d\n",add_script,add_ret));
1976 /* add the user in the smbpasswd file or the Samba authority database */
1977 if (!local_password_change(mach_acct, local_flags, NULL, err_str,
1978 sizeof(err_str), msg_str, sizeof(msg_str))) {
1979 DEBUG(0, ("%s\n", err_str));
1980 pdb_free_sam(sam_pass);
1981 return NT_STATUS_ACCESS_DENIED;
1985 ret = pdb_getsampwnam(sam_pass, mach_acct);
1988 /* account doesn't exist: say so */
1989 pdb_free_sam(sam_pass);
1990 return NT_STATUS_ACCESS_DENIED;
1993 /* Get the domain SID stored in the domain policy */
1994 if(!get_lsa_policy_samr_sid(p, &dom_pol, &sid)) {
1995 pdb_free_sam(sam_pass);
1996 return NT_STATUS_INVALID_HANDLE;
1999 /* append the user's RID to it */
2000 if(!sid_append_rid(&sid, pdb_get_user_rid(sam_pass) )) {
2001 pdb_free_sam(sam_pass);
2002 return NT_STATUS_NO_SUCH_USER;
2005 /* associate the user's SID with the new handle. */
2006 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL) {
2007 pdb_free_sam(sam_pass);
2008 return NT_STATUS_NO_MEMORY;
2014 /* get a (unique) handle. open a policy on it. */
2015 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2016 pdb_free_sam(sam_pass);
2017 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2020 r_u->user_rid=sam_pass->user_rid;
2021 r_u->unknown_0 = 0x000703ff;
2023 pdb_free_sam(sam_pass);
2025 return NT_STATUS_NOPROBLEMO;
2028 /*******************************************************************
2029 samr_reply_connect_anon
2030 ********************************************************************/
2032 uint32 _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2034 struct samr_info *info = NULL;
2036 /* set up the SAMR connect_anon response */
2038 r_u->status = NT_STATUS_NOPROBLEMO;
2040 /* associate the user's SID with the new handle. */
2041 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
2042 return NT_STATUS_NO_MEMORY;
2045 info->status = q_u->unknown_0;
2047 /* get a (unique) handle. open a policy on it. */
2048 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2049 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2054 /*******************************************************************
2056 ********************************************************************/
2058 uint32 _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2060 struct samr_info *info = NULL;
2062 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2064 r_u->status = NT_STATUS_NOPROBLEMO;
2066 /* associate the user's SID with the new handle. */
2067 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
2068 return NT_STATUS_NO_MEMORY;
2071 info->status = q_u->access_mask;
2073 /* get a (unique) handle. open a policy on it. */
2074 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2075 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2077 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2082 /**********************************************************************
2083 api_samr_lookup_domain
2084 **********************************************************************/
2086 uint32 _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2088 r_u->status = NT_STATUS_NOPROBLEMO;
2090 if (!find_policy_by_hnd(p, &q_u->connect_pol, NULL))
2091 return NT_STATUS_INVALID_HANDLE;
2093 /* assume the domain name sent is our global_myname and
2094 send global_sam_sid */
2095 init_samr_r_lookup_domain(r_u, &global_sam_sid, r_u->status);
2100 /******************************************************************
2101 makes a SAMR_R_ENUM_DOMAINS structure.
2102 ********************************************************************/
2104 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2105 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2111 DEBUG(5, ("make_enum_domains\n"));
2114 *pp_uni_name = NULL;
2116 if (num_sam_entries == 0)
2119 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2120 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2122 if (sam == NULL || uni_name == NULL)
2125 for (i = 0; i < num_sam_entries; i++) {
2126 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
2128 init_sam_entry(&sam[i], len, 0);
2129 init_unistr2(&uni_name[i], doms[i], len);
2133 *pp_uni_name = uni_name;
2138 /**********************************************************************
2139 api_samr_enum_domains
2140 **********************************************************************/
2142 uint32 _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2144 uint32 num_entries = 2;
2147 r_u->status = NT_STATUS_NOPROBLEMO;
2149 fstrcpy(dom[0],global_myworkgroup);
2150 fstrcpy(dom[1],"Builtin");
2152 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2153 return NT_STATUS_NO_MEMORY;
2155 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2160 /*******************************************************************
2162 ********************************************************************/
2164 uint32 _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2167 POLICY_HND domain_pol = q_u->dom_pol;
2168 uint32 alias_rid = q_u->rid_alias;
2169 POLICY_HND *alias_pol = &r_u->pol;
2170 struct samr_info *info = NULL;
2172 r_u->status = NT_STATUS_NOPROBLEMO;
2174 /* get the domain policy. */
2175 if (!find_policy_by_hnd(p, &domain_pol, NULL))
2176 return NT_STATUS_INVALID_HANDLE;
2178 /* Get the domain SID stored in the domain policy */
2179 if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
2180 return NT_STATUS_INVALID_HANDLE;
2182 /* append the alias' RID to it */
2183 if(!sid_append_rid(&sid, alias_rid))
2184 return NT_STATUS_NO_SUCH_USER;
2187 * we should check if the rid really exist !!!
2191 /* associate the user's SID with the new handle. */
2192 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
2193 return NT_STATUS_NO_MEMORY;
2198 /* get a (unique) handle. open a policy on it. */
2199 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2200 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2205 /*******************************************************************
2207 ********************************************************************/
2209 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid)
2211 SAM_ACCOUNT *pwd =NULL;
2216 ret = pdb_getsampwrid(pwd, rid);
2224 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2229 pdb_set_acct_ctrl(pwd, id10->acb_info);
2231 if(!pdb_update_sam_account(pwd, True)) {
2241 /*******************************************************************
2243 ********************************************************************/
2245 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, uint32 rid)
2247 SAM_ACCOUNT *pwd = NULL;
2251 if(!pdb_getsampwrid(pwd, rid)) {
2257 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2262 pdb_set_lanman_passwd (pwd, id12->lm_pwd);
2263 pdb_set_nt_passwd (pwd, id12->nt_pwd);
2265 if(!pdb_update_sam_account(pwd, True)) {
2274 /*******************************************************************
2276 ********************************************************************/
2278 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, uint32 rid)
2280 SAM_ACCOUNT *pwd = NULL;
2281 SAM_ACCOUNT *new_pwd = NULL;
2284 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2289 pdb_init_sam(&new_pwd);
2291 if (!pdb_getsampwrid(pwd, rid)) {
2293 pdb_free_sam(new_pwd);
2297 /* we make a copy so that we can modify stuff */
2298 copy_sam_passwd(new_pwd, pwd);
2299 copy_id21_to_sam_passwd(new_pwd, id21);
2302 * The funny part about the previous two calls is
2303 * that pwd still has the password hashes from the
2304 * passdb entry. These have not been updated from
2305 * id21. I don't know if they need to be set. --jerry
2308 /* write the change out */
2309 if(!pdb_update_sam_account(new_pwd, True)) {
2311 pdb_free_sam(new_pwd);
2316 pdb_free_sam(new_pwd);
2321 /*******************************************************************
2323 ********************************************************************/
2325 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
2327 SAM_ACCOUNT *pwd = NULL;
2328 SAM_ACCOUNT *new_pwd = NULL;
2336 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2341 pdb_init_sam(&new_pwd);
2343 if (!pdb_getsampwrid(pwd, rid)) {
2345 pdb_free_sam(new_pwd);
2349 acct_ctrl = pdb_get_acct_ctrl(pwd);
2351 copy_sam_passwd(new_pwd, pwd);
2354 copy_id23_to_sam_passwd(new_pwd, id23);
2356 if (!decode_pw_buffer((char*)id23->pass, buf, 256, &len, nt_hash, lm_hash)) {
2357 pdb_free_sam(new_pwd);
2361 pdb_set_lanman_passwd (new_pwd, lm_hash);
2362 pdb_set_nt_passwd (new_pwd, nt_hash);
2364 /* if it's a trust account, don't update /etc/passwd */
2365 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2366 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2367 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2368 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2370 /* update the UNIX password */
2371 if (lp_unix_password_sync() )
2372 if(!chgpasswd(pdb_get_username(new_pwd), "", buf, True)) {
2373 pdb_free_sam(new_pwd);
2378 memset(buf, 0, sizeof(buf));
2380 if(!pdb_update_sam_account(new_pwd, True)) {
2381 pdb_free_sam(new_pwd);
2385 pdb_free_sam(new_pwd);
2390 /*******************************************************************
2392 ********************************************************************/
2394 static BOOL set_user_info_pw(char *pass, uint32 rid)
2396 SAM_ACCOUNT *pwd = NULL;
2405 if (!pdb_getsampwrid(pwd, rid)) {
2410 acct_ctrl = pdb_get_acct_ctrl(pwd);
2412 memset(buf, 0, sizeof(buf));
2414 if (!decode_pw_buffer(pass, buf, 256, &len, nt_hash, lm_hash)) {
2419 pdb_set_lanman_passwd (pwd, lm_hash);
2420 pdb_set_nt_passwd (pwd, nt_hash);
2422 /* if it's a trust account, don't update /etc/passwd */
2423 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2424 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2425 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2426 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2428 /* update the UNIX password */
2429 if (lp_unix_password_sync())
2430 if(!chgpasswd(pdb_get_username(pwd), "", buf, True)) {
2436 memset(buf, 0, sizeof(buf));
2438 DEBUG(5,("set_user_info_pw: pdb_update_sam_account()\n"));
2440 /* update the SAMBA password */
2441 if(!pdb_update_sam_account(pwd, True)) {
2451 /*******************************************************************
2452 samr_reply_set_userinfo
2453 ********************************************************************/
2455 uint32 _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2459 struct current_user user;
2460 SAM_ACCOUNT *sam_pass=NULL;
2461 unsigned char sess_key[16];
2462 POLICY_HND *pol = &q_u->pol;
2463 uint16 switch_value = q_u->switch_value;
2464 SAM_USERINFO_CTR *ctr = q_u->ctr;
2467 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2469 r_u->status = NT_STATUS_NOPROBLEMO;
2471 if (p->ntlmssp_auth_validated) {
2472 memcpy(&user, &p->pipe_user, sizeof(user));
2474 extern struct current_user current_user;
2475 memcpy(&user, ¤t_user, sizeof(user));
2478 /* find the policy handle. open a policy on it. */
2479 if (!get_lsa_policy_samr_sid(p, pol, &sid))
2480 return NT_STATUS_INVALID_HANDLE;
2482 sid_split_rid(&sid, &rid);
2484 DEBUG(5, ("_samr_set_userinfo: rid:0x%x, level:%d\n", rid, switch_value));
2487 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2488 return NT_STATUS_INVALID_INFO_CLASS;
2492 pdb_init_sam(&sam_pass);
2495 * We need the NT hash of the user who is changing the user's password.
2496 * This NT hash is used to generate a "user session key"
2497 * This "user session key" is in turn used to encrypt/decrypt the user's password.
2501 ret = pdb_getsampwuid(sam_pass, user.uid);
2504 DEBUG(0,("_samr_set_userinfo: Unable to get smbpasswd entry for uid %u\n", (unsigned int)user.uid ));
2505 pdb_free_sam(sam_pass);
2506 return NT_STATUS_ACCESS_DENIED;
2509 memset(sess_key, '\0', 16);
2510 mdfour(sess_key, pdb_get_nt_passwd(sam_pass), 16);
2512 pdb_free_sam(sam_pass);
2514 /* ok! user info levels (lots: see MSDEV help), off we go... */
2515 switch (switch_value) {
2517 if (!set_user_info_12(ctr->info.id12, rid))
2518 return NT_STATUS_ACCESS_DENIED;
2522 SamOEMhash(ctr->info.id24->pass, sess_key, 516);
2524 dump_data(100, (char *)ctr->info.id24->pass, 516);
2526 if (!set_user_info_pw((char *)ctr->info.id24->pass, rid))
2527 return NT_STATUS_ACCESS_DENIED;
2533 * Currently we don't really know how to unmarshall
2534 * the level 25 struct, and the password encryption
2535 * is different. This is a placeholder for when we
2536 * do understand it. In the meantime just return INVALID
2537 * info level and W2K SP2 drops down to level 23... JRA.
2540 SamOEMhash(ctr->info.id25->pass, sess_key, 532);
2542 dump_data(100, (char *)ctr->info.id25->pass, 532);
2544 if (!set_user_info_pw(ctr->info.id25->pass, rid))
2545 return NT_STATUS_ACCESS_DENIED;
2548 return NT_STATUS_INVALID_INFO_CLASS;
2551 SamOEMhash(ctr->info.id23->pass, sess_key, 516);
2553 dump_data(100, (char *)ctr->info.id23->pass, 516);
2555 if (!set_user_info_23(ctr->info.id23, rid))
2556 return NT_STATUS_ACCESS_DENIED;
2560 return NT_STATUS_INVALID_INFO_CLASS;
2566 /*******************************************************************
2567 samr_reply_set_userinfo2
2568 ********************************************************************/
2570 uint32 _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
2574 SAM_USERINFO_CTR *ctr = q_u->ctr;
2575 POLICY_HND *pol = &q_u->pol;
2576 uint16 switch_value = q_u->switch_value;
2578 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
2580 r_u->status = NT_STATUS_NOPROBLEMO;
2582 /* find the policy handle. open a policy on it. */
2583 if (!get_lsa_policy_samr_sid(p, pol, &sid))
2584 return NT_STATUS_INVALID_HANDLE;
2586 sid_split_rid(&sid, &rid);
2588 DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid));
2591 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
2592 return NT_STATUS_INVALID_INFO_CLASS;
2595 switch_value=ctr->switch_value;
2597 /* ok! user info levels (lots: see MSDEV help), off we go... */
2598 switch (switch_value) {
2600 if (!set_user_info_21(ctr->info.id21, rid))
2601 return NT_STATUS_ACCESS_DENIED;
2604 if (!set_user_info_10(ctr->info.id10, rid))
2605 return NT_STATUS_ACCESS_DENIED;
2608 /* Used by AS/U JRA. */
2609 if (!set_user_info_12(ctr->info.id12, rid))
2610 return NT_STATUS_ACCESS_DENIED;
2613 return NT_STATUS_INVALID_INFO_CLASS;
2619 /*********************************************************************
2620 _samr_query_aliasmem
2621 *********************************************************************/
2623 uint32 _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
2629 rid=(uint32 *)talloc_zero(p->mem_ctx, num_rids*sizeof(uint32));
2631 return NT_STATUS_NO_MEMORY;
2633 /* until i see a real useraliases query, we fack one up */
2635 rid[0] = BUILTIN_ALIAS_RID_USERS;
2637 init_samr_r_query_useraliases(r_u, num_rids, rid, NT_STATUS_NOPROBLEMO);
2639 return NT_STATUS_NOPROBLEMO;
2643 /*********************************************************************
2644 _samr_query_aliasmem
2645 *********************************************************************/
2647 uint32 _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
2659 fstring alias_sid_str;
2663 /* find the policy handle. open a policy on it. */
2664 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid))
2665 return NT_STATUS_INVALID_HANDLE;
2667 sid_copy(&als_sid, &alias_sid);
2668 sid_to_string(alias_sid_str, &alias_sid);
2669 sid_split_rid(&alias_sid, &alias_rid);
2671 DEBUG(10, ("sid is %s\n", alias_sid_str));
2673 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
2674 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
2675 if(!get_builtin_group_from_sid(als_sid, &map))
2676 return NT_STATUS_NO_SUCH_ALIAS;
2678 if (sid_equal(&alias_sid, &global_sam_sid)) {
2679 DEBUG(10, ("lookup on Server SID\n"));
2680 if(!get_local_group_from_sid(als_sid, &map))
2681 return NT_STATUS_NO_SUCH_ALIAS;
2685 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
2686 return NT_STATUS_NO_SUCH_ALIAS;
2688 DEBUG(10, ("sid is %s\n", alias_sid_str));
2689 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
2690 if (num_uids!=0 && sid == NULL)
2691 return NT_STATUS_NO_MEMORY;
2693 for (i = 0; i < num_uids; i++) {
2694 sid_copy(&temp_sid, &global_sam_sid);
2695 sid_append_rid(&temp_sid, pdb_uid_to_user_rid(uid[i]));
2697 init_dom_sid2(&sid[i], &temp_sid);
2700 DEBUG(10, ("sid is %s\n", alias_sid_str));
2701 init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_NOPROBLEMO);
2703 return NT_STATUS_NOPROBLEMO;
2706 /*********************************************************************
2707 _samr_query_groupmem
2708 *********************************************************************/
2710 uint32 _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
2716 fstring group_sid_str;
2725 /* find the policy handle. open a policy on it. */
2726 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid))
2727 return NT_STATUS_INVALID_HANDLE;
2729 /* todo: change to use sid_compare_front */
2731 sid_split_rid(&group_sid, &group_rid);
2732 sid_to_string(group_sid_str, &group_sid);
2733 DEBUG(10, ("sid is %s\n", group_sid_str));
2735 /* can we get a query for an SID outside our domain ? */
2736 if (!sid_equal(&group_sid, &global_sam_sid))
2737 return NT_STATUS_NO_SUCH_GROUP;
2739 sid_append_rid(&group_sid, group_rid);
2740 DEBUG(10, ("lookup on Domain SID\n"));
2742 if(!get_domain_group_from_sid(group_sid, &map))
2743 return NT_STATUS_NO_SUCH_GROUP;
2745 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
2746 return NT_STATUS_NO_SUCH_GROUP;
2748 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
2749 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
2751 if (num_uids!=0 && (rid==NULL || attr==NULL))
2752 return NT_STATUS_NO_MEMORY;
2754 for (i=0; i<num_uids; i++) {
2755 rid[i]=pdb_uid_to_user_rid(uid[i]);
2756 attr[i] = SID_NAME_USER;
2759 init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_NOPROBLEMO);
2761 return NT_STATUS_NOPROBLEMO;
2764 /*********************************************************************
2766 *********************************************************************/
2768 uint32 _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
2771 fstring alias_sid_str;
2779 /* Find the policy handle. Open a policy on it. */
2780 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid))
2781 return NT_STATUS_INVALID_HANDLE;
2783 sid_to_string(alias_sid_str, &alias_sid);
2784 DEBUG(10, ("sid is %s\n", alias_sid_str));
2786 if (sid_compare(&alias_sid, &global_sam_sid)>0) {
2787 DEBUG(10, ("adding member on Server SID\n"));
2788 if(!get_local_group_from_sid(alias_sid, &map))
2789 return NT_STATUS_NO_SUCH_ALIAS;
2792 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
2793 DEBUG(10, ("adding member on BUILTIN SID\n"));
2794 if( !get_builtin_group_from_sid(alias_sid, &map))
2795 return NT_STATUS_NO_SUCH_ALIAS;
2798 return NT_STATUS_NO_SUCH_ALIAS;
2801 sid_split_rid(&q_u->sid.sid, &rid);
2802 uid=pdb_user_rid_to_uid(rid);
2804 if ((pwd=getpwuid(uid)) == NULL)
2805 return NT_STATUS_NO_SUCH_USER;
2807 if ((grp=getgrgid(map.gid)) == NULL)
2808 return NT_STATUS_NO_SUCH_ALIAS;
2810 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
2811 fstrcpy(grp_name, grp->gr_name);
2813 /* if the user is already in the group */
2814 if(user_in_group_list(pwd->pw_name, grp_name))
2815 return NT_STATUS_MEMBER_IN_ALIAS;
2818 * ok, the group exist, the user exist, the user is not in the group,
2819 * we can (finally) add it to the group !
2821 smb_add_user_group(grp_name, pwd->pw_name);
2823 /* check if the user has been added then ... */
2824 if(!user_in_group_list(pwd->pw_name, grp_name))
2825 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
2827 return NT_STATUS_NOPROBLEMO;
2830 /*********************************************************************
2832 *********************************************************************/
2834 uint32 _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
2836 DEBUG(0,("_samr_del_aliasmem: Not yet implemented.\n"));
2840 /*********************************************************************
2842 *********************************************************************/
2844 uint32 _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
2847 fstring group_sid_str;
2853 /* Find the policy handle. Open a policy on it. */
2854 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid))
2855 return NT_STATUS_INVALID_HANDLE;
2857 sid_to_string(group_sid_str, &group_sid);
2858 DEBUG(10, ("sid is %s\n", group_sid_str));
2860 if (sid_compare(&group_sid, &global_sam_sid)<=0)
2861 return NT_STATUS_NO_SUCH_GROUP;
2863 DEBUG(10, ("lookup on Domain SID\n"));
2865 if(!get_domain_group_from_sid(group_sid, &map))
2866 return NT_STATUS_NO_SUCH_GROUP;
2868 if ((pwd=getpwuid(pdb_user_rid_to_uid(q_u->rid))) ==NULL)
2869 return NT_STATUS_NO_SUCH_USER;
2871 if ((grp=getgrgid(map.gid)) == NULL)
2872 return NT_STATUS_NO_SUCH_GROUP;
2874 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
2875 fstrcpy(grp_name, grp->gr_name);
2877 /* if the user is already in the group */
2878 if(user_in_group_list(pwd->pw_name, grp_name))
2879 return NT_STATUS_MEMBER_IN_GROUP;
2882 * ok, the group exist, the user exist, the user is not in the group,
2884 * we can (finally) add it to the group !
2887 smb_add_user_group(grp_name, pwd->pw_name);
2889 /* check if the user has been added then ... */
2890 if(!user_in_group_list(pwd->pw_name, grp_name))
2891 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
2893 return NT_STATUS_NOPROBLEMO;
2896 /*********************************************************************
2898 *********************************************************************/
2900 uint32 _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
2902 DEBUG(0,("_samr_del_groupmem: Not yet implemented.\n"));
2906 /*********************************************************************
2907 _samr_delete_dom_user
2908 *********************************************************************/
2910 uint32 _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
2912 DEBUG(0,("_samr_delete_dom_user: Not yet implemented.\n"));
2916 /*********************************************************************
2917 _samr_delete_dom_group
2918 *********************************************************************/
2920 uint32 _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
2925 fstring group_sid_str;
2930 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
2932 /* Find the policy handle. Open a policy on it. */
2933 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid))
2934 return NT_STATUS_INVALID_HANDLE;
2936 sid_copy(&dom_sid, &group_sid);
2937 sid_to_string(group_sid_str, &dom_sid);
2938 sid_split_rid(&dom_sid, &group_rid);
2940 DEBUG(10, ("sid is %s\n", group_sid_str));
2942 /* we check if it's our SID before deleting */
2943 if (!sid_equal(&dom_sid, &global_sam_sid))
2944 return NT_STATUS_NO_SUCH_GROUP;
2946 DEBUG(10, ("lookup on Domain SID\n"));
2948 if(!get_domain_group_from_sid(group_sid, &map))
2949 return NT_STATUS_NO_SUCH_ALIAS;
2953 /* check if group really exists */
2954 if ( (grp=getgrgid(gid)) == NULL)
2955 return NT_STATUS_NO_SUCH_GROUP;
2957 /* we can delete the UNIX group */
2958 smb_delete_group(grp->gr_name);
2960 /* check if the group has been successfully deleted */
2961 if ( (grp=getgrgid(gid)) != NULL)
2962 return NT_STATUS_ACCESS_DENIED;
2964 if(!group_map_remove(group_sid))
2965 return NT_STATUS_ACCESS_DENIED;
2967 if (!close_policy_hnd(p, &q_u->group_pol))
2968 return NT_STATUS_OBJECT_NAME_INVALID;
2970 return NT_STATUS_NOPROBLEMO;
2973 /*********************************************************************
2974 _samr_delete_dom_alias
2975 *********************************************************************/
2977 uint32 _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
2982 fstring alias_sid_str;
2987 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
2989 /* Find the policy handle. Open a policy on it. */
2990 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid))
2991 return NT_STATUS_INVALID_HANDLE;
2993 sid_copy(&dom_sid, &alias_sid);
2994 sid_to_string(alias_sid_str, &dom_sid);
2995 sid_split_rid(&dom_sid, &alias_rid);
2997 DEBUG(10, ("sid is %s\n", alias_sid_str));
2999 /* we check if it's our SID before deleting */
3000 if (!sid_equal(&dom_sid, &global_sam_sid))
3001 return NT_STATUS_NO_SUCH_ALIAS;
3003 DEBUG(10, ("lookup on Local SID\n"));
3005 if(!get_local_group_from_sid(alias_sid, &map))
3006 return NT_STATUS_NO_SUCH_ALIAS;
3010 /* check if group really exists */
3011 if ( (grp=getgrgid(gid)) == NULL)
3012 return NT_STATUS_NO_SUCH_ALIAS;
3014 /* we can delete the UNIX group */
3015 smb_delete_group(grp->gr_name);
3017 /* check if the group has been successfully deleted */
3018 if ( (grp=getgrgid(gid)) != NULL)
3019 return NT_STATUS_ACCESS_DENIED;
3021 /* don't check if we removed it as it could be an un-mapped group */
3022 group_map_remove(alias_sid);
3024 if (!close_policy_hnd(p, &q_u->alias_pol))
3025 return NT_STATUS_OBJECT_NAME_INVALID;
3027 return NT_STATUS_NOPROBLEMO;
3030 /*********************************************************************
3031 _samr_create_dom_group
3032 *********************************************************************/
3034 uint32 _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3041 struct samr_info *info;
3043 /* Find the policy handle. Open a policy on it. */
3044 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid))
3045 return NT_STATUS_INVALID_HANDLE;
3047 if (!sid_equal(&dom_sid, &global_sam_sid))
3048 return NT_STATUS_ACCESS_DENIED;
3050 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3052 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3054 /* check if group already exist */
3055 if ((grp=getgrnam(name)) != NULL)
3056 return NT_STATUS_GROUP_EXISTS;
3058 /* we can create the UNIX group */
3059 smb_create_group(name);
3061 /* check if the group has been successfully created */
3062 if ((grp=getgrnam(name)) == NULL)
3063 return NT_STATUS_ACCESS_DENIED;
3065 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3067 /* add the group to the mapping table */
3068 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL, SE_PRIV_NONE))
3069 return NT_STATUS_ACCESS_DENIED;
3071 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
3072 return NT_STATUS_NO_MEMORY;
3076 sid_copy(&info_sid, &global_sam_sid);
3077 sid_append_rid(&info->sid, r_u->rid);
3078 sid_to_string(sid_string, &info->sid);
3080 /* get a (unique) handle. open a policy on it. */
3081 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3082 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3084 return NT_STATUS_NOPROBLEMO;
3087 /*********************************************************************
3088 _samr_create_dom_alias
3089 *********************************************************************/
3091 uint32 _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3097 struct samr_info *info;
3099 /* Find the policy handle. Open a policy on it. */
3100 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid))
3101 return NT_STATUS_INVALID_HANDLE;
3103 if (!sid_equal(&dom_sid, &global_sam_sid))
3104 return NT_STATUS_ACCESS_DENIED;
3106 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3108 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3110 /* check if group already exists */
3111 if ( (grp=getgrnam(name)) != NULL)
3112 return NT_STATUS_GROUP_EXISTS;
3114 /* we can create the UNIX group */
3115 smb_create_group(name);
3117 /* check if the group has been successfully created */
3118 if ((grp=getgrnam(name)) == NULL)
3119 return NT_STATUS_ACCESS_DENIED;
3121 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3123 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
3124 return NT_STATUS_NO_MEMORY;
3128 sid_copy(&info->sid, &global_sam_sid);
3129 sid_append_rid(&info->sid, r_u->rid);
3130 sid_to_string(sid_string, &info->sid);
3132 /* add the group to the mapping table */
3133 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL, SE_PRIV_NONE))
3134 return NT_STATUS_ACCESS_DENIED;
3136 /* get a (unique) handle. open a policy on it. */
3137 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
3138 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3140 return NT_STATUS_NOPROBLEMO;
3143 /*********************************************************************
3144 _samr_query_groupinfo
3146 sends the name/comment pair of a domain group
3147 level 1 send also the number of users of that group
3148 *********************************************************************/
3150 uint32 _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
3156 GROUP_INFO_CTR *ctr;
3158 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid))
3159 return NT_STATUS_INVALID_HANDLE;
3161 if (!get_domain_group_from_sid(group_sid, &map))
3162 return NT_STATUS_INVALID_HANDLE;
3164 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
3166 return NT_STATUS_NO_MEMORY;
3168 switch (q_u->switch_level) {
3170 ctr->switch_value1 = 1;
3171 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3172 return NT_STATUS_NO_SUCH_GROUP;
3173 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
3177 ctr->switch_value1 = 4;
3178 init_samr_group_info4(&ctr->group.info4, map.comment);
3181 return NT_STATUS_INVALID_INFO_CLASS;
3184 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_NOPROBLEMO);
3186 return NT_STATUS_NOPROBLEMO;
3189 /*********************************************************************
3192 update a domain group's comment.
3193 *********************************************************************/
3195 uint32 _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
3199 GROUP_INFO_CTR *ctr;
3201 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid))
3202 return NT_STATUS_INVALID_HANDLE;
3204 if (!get_domain_group_from_sid(group_sid, &map))
3205 return NT_STATUS_NO_SUCH_GROUP;
3209 switch (ctr->switch_value1) {
3211 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
3214 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
3217 return NT_STATUS_INVALID_INFO_CLASS;
3220 if(!add_mapping_entry(&map, TDB_REPLACE))
3221 return NT_STATUS_NO_SUCH_GROUP;
3223 return NT_STATUS_NOPROBLEMO;
3226 /*********************************************************************
3229 update a domain group's comment.
3230 *********************************************************************/
3232 uint32 _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
3236 ALIAS_INFO_CTR *ctr;
3238 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid))
3239 return NT_STATUS_INVALID_HANDLE;
3241 if (!get_local_group_from_sid(group_sid, &map))
3242 return NT_STATUS_NO_SUCH_GROUP;
3246 switch (ctr->switch_value1) {
3248 unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
3251 return NT_STATUS_INVALID_INFO_CLASS;
3254 if(!add_mapping_entry(&map, TDB_REPLACE))
3255 return NT_STATUS_NO_SUCH_GROUP;
3257 return NT_STATUS_NOPROBLEMO;
3260 /*********************************************************************
3261 _samr_get_dom_pwinfo
3262 *********************************************************************/
3264 uint32 _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
3266 /* Actually, returning zeros here works quite well :-). */
3267 return NT_STATUS_NOPROBLEMO;
3270 /*********************************************************************
3272 *********************************************************************/
3274 uint32 _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
3278 struct samr_info *info;
3281 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid))
3282 return NT_STATUS_INVALID_HANDLE;
3284 /* this should not be hard-coded like this */
3285 if (!sid_equal(&sid, &global_sam_sid))
3286 return NT_STATUS_ACCESS_DENIED;
3288 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
3289 return NT_STATUS_NO_MEMORY;
3293 sid_copy(&info->sid, &global_sam_sid);
3294 sid_append_rid(&info->sid, q_u->rid_group);
3295 sid_to_string(sid_string, &info->sid);
3297 DEBUG(10, ("Opening SID: %s\n", sid_string));
3299 /* check if that group really exists */
3300 if (!get_domain_group_from_sid(info->sid, &map))
3301 return NT_STATUS_NO_SUCH_USER;
3303 /* get a (unique) handle. open a policy on it. */
3304 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3305 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3307 return NT_STATUS_NOPROBLEMO;
3310 /*********************************************************************
3312 *********************************************************************/
3314 uint32 _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
3316 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));