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 BOOL 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;
106 if (!pdb_setsampwent(False)) {
107 DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n"));
112 while (((ret = pdb_getsampwent(pwd)) != False) && (*num_entries) < max_num_entries) {
116 /* skip the requested number of entries.
117 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));
143 DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
151 return (*num_entries) > 0;
154 static BOOL jf_get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx,
155 int *total_entries, uint32 *num_entries,
156 int max_num_entries, uint16 acb_mask)
158 SAM_ACCOUNT *pwd = NULL;
166 DEBUG(10,("jf_get_sampwd_entries: start index:%d, max entries:%d, mask:%d\n",
167 start_idx, max_num_entries, acb_mask));
169 if (!pdb_setsampwent(False)) {
170 DEBUG(0, ("jf_get_sampwd_entries: Unable to open passdb.\n"));
176 while ((pdb_getsampwent(pwd) != False) && (*num_entries) < max_num_entries) {
180 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask))
184 /* skip the requested number of entries.
185 not very efficient, but hey...
191 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
193 user_name_len = strlen(pdb_get_username(pwd));
194 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pdb_get_username(pwd), user_name_len);
195 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
197 full_name_len = strlen(pdb_get_fullname(pwd));
198 init_unistr2(&pw_buf[(*num_entries)].uni_full_name, pdb_get_fullname(pwd), full_name_len);
199 init_uni_hdr(&pw_buf[(*num_entries)].hdr_full_name, full_name_len);
201 pw_buf[(*num_entries)].user_rid = pdb_get_user_rid(pwd);
202 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
204 /* Now check if the NT compatible password is available. */
205 if (pdb_get_nt_passwd(pwd))
206 memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
208 pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
210 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x\n", (*num_entries),
211 pdb_get_username(pwd), pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd) ));
220 *total_entries = *num_entries;
227 /*******************************************************************
228 This function uses the username map file and tries to map a UNIX
229 user name to an DOS name. (Sort of the reverse of the
230 map_username() function.) Since more than one DOS name can map
231 to the UNIX name, to reverse the mapping you have to specify
232 which corresponding DOS name you want; that's where the name_idx
233 parameter comes in. Returns the string requested or NULL if it
234 fails or can't complete the request for any reason. This doesn't
235 handle group names (starting with '@') or names starting with
236 '+' or '&'. If they are encountered, they are skipped.
237 ********************************************************************/
239 static char *unmap_unixname(char *unix_user_name, int name_idx)
241 char *mapfile = lp_username_map();
246 if (!*unix_user_name) return NULL;
247 if (!*mapfile) return NULL;
249 lines = file_lines_load(mapfile, NULL);
251 DEBUG(0,("unmap_unixname: can't open username map %s\n", mapfile));
255 DEBUG(5,("unmap_unixname: scanning username map %s, index: %d\n", mapfile, name_idx));
257 for (i=0; lines[i]; i++) {
258 char *unixname = lines[i];
259 char *dosname = strchr(unixname,'=');
266 while (isspace(*unixname))
268 if ('!' == *unixname) {
270 while (*unixname && isspace(*unixname))
274 if (!*unixname || strchr("#;",*unixname))
277 if (strncmp(unixname, unix_user_name, strlen(unix_user_name)))
280 /* We have matched the UNIX user name */
282 while(next_token(&dosname, tok, LIST_SEP, sizeof(tok))) {
283 if (!strchr("@&+", *tok)) {
292 DEBUG(0,("unmap_unixname: index too high - not that many DOS names\n"));
293 file_lines_free(lines);
296 file_lines_free(lines);
301 DEBUG(0,("unmap_unixname: Couldn't find the UNIX user name\n"));
302 file_lines_free(lines);
306 /*******************************************************************
307 This function sets up a list of users taken from the list of
308 users that UNIX knows about, as well as all the user names that
309 Samba maps to a valid UNIX user name. (This should work with
311 ********************************************************************/
313 static BOOL get_passwd_entries(SAM_USER_INFO_21 *pw_buf,
315 int *total_entries, int *num_entries,
319 static struct passwd *pwd = NULL;
320 static uint32 pw_rid;
321 static BOOL orig_done = False;
322 static int current_idx = 0;
323 static int mapped_idx = 0;
326 DEBUG(5, ("get_passwd_entries: retrieving a list of UNIX users\n"));
329 (*total_entries) = 0;
331 /* Skip all this stuff if we're in appliance mode */
333 if (lp_hide_local_users()) goto done;
335 if (pw_buf == NULL) return False;
337 if (current_idx == 0) {
341 /* These two cases are inefficient, but should be called very rarely */
342 /* they are the cases where the starting index isn't picking up */
343 /* where we left off last time. It is efficient when it starts over */
344 /* at zero though. */
345 if (start_idx > current_idx) {
346 /* We aren't far enough; advance to start_idx */
347 while (current_idx <= start_idx) {
351 if ((pwd = sys_getpwent()) == NULL) break;
356 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
357 (current_idx < start_idx)) {
362 if (unmap_name == NULL) {
367 } else if (start_idx < current_idx) {
368 /* We are already too far; start over and advance to start_idx */
374 while (current_idx < start_idx) {
378 if ((pwd = sys_getpwent()) == NULL) break;
383 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
384 (current_idx < start_idx)) {
389 if (unmap_name == NULL) {
396 sep = lp_winbind_separator();
398 /* now current_idx == start_idx */
399 while ((*num_entries) < max_num_entries) {
403 /* This does the original UNIX user itself */
405 if ((pwd = sys_getpwent()) == NULL) break;
407 /* Don't enumerate winbind users as they are not local */
409 if (strchr(pwd->pw_name, *sep) != NULL) {
413 user_name_len = strlen(pwd->pw_name);
415 /* skip the trust account stored in the /etc/passwd file */
416 if (pwd->pw_name[user_name_len-1]=='$')
419 pw_rid = pdb_uid_to_user_rid(pwd->pw_uid);
420 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
421 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pwd->pw_name, user_name_len);
422 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
423 pw_buf[(*num_entries)].user_rid = pw_rid;
424 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
426 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
428 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
436 /* This does all the user names that map to the UNIX user */
437 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
438 (*num_entries < max_num_entries)) {
439 user_name_len = strlen(unmap_name);
440 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
441 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, unmap_name, user_name_len);
442 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
443 pw_buf[(*num_entries)].user_rid = pw_rid;
444 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
446 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
448 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
456 if (unmap_name == NULL) {
457 /* done with 'aliases', go on to next UNIX user */
464 /* totally done, reset everything */
471 return (*num_entries) > 0;
474 /*******************************************************************
476 ********************************************************************/
478 uint32 _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
480 r_u->status = NT_STATUS_NOPROBLEMO;
482 /* close the policy handle */
483 if (!close_policy_hnd(p, &q_u->pol))
484 return NT_STATUS_OBJECT_NAME_INVALID;
486 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
491 /*******************************************************************
492 samr_reply_open_domain
493 ********************************************************************/
495 uint32 _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
497 struct samr_info *info;
499 r_u->status = NT_STATUS_NOPROBLEMO;
501 /* find the connection policy handle. */
502 if (!find_policy_by_hnd(p, &q_u->pol, NULL))
503 return NT_STATUS_INVALID_HANDLE;
505 /* associate the domain SID with the (unique) handle. */
506 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
507 return NT_STATUS_NO_MEMORY;
510 info->sid = q_u->dom_sid.sid;
512 /* get a (unique) handle. open a policy on it. */
513 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
514 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
516 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
521 static uint32 get_lsa_policy_samr_rid(struct samr_info *info)
524 DEBUG(3,("Error getting policy\n"));
528 return info->sid.sub_auths[info->sid.num_auths-1];
531 /*******************************************************************
532 _samr_get_usrdom_pwinfo
533 ********************************************************************/
535 uint32 _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
537 struct samr_info *info = NULL;
539 r_u->status = NT_STATUS_NOPROBLEMO;
541 /* find the policy handle. open a policy on it. */
542 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info)) {
543 return NT_STATUS_INVALID_HANDLE;
546 /* find the user's rid */
547 if (get_lsa_policy_samr_rid(info) == 0xffffffff) {
548 return NT_STATUS_OBJECT_TYPE_MISMATCH;
551 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_NOPROBLEMO);
553 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
558 /*******************************************************************
560 ********************************************************************/
562 static uint32 samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC_BUF **buf, DOM_SID *usr_sid)
564 extern DOM_SID global_sid_World;
572 SEC_DESC *psd = NULL;
575 sid_copy(&adm_sid, &global_sid_Builtin);
576 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
578 sid_copy(&act_sid, &global_sid_Builtin);
579 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
581 init_sec_access(&mask, 0x2035b);
582 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
584 init_sec_access(&mask, 0xf07ff);
585 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
586 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
588 init_sec_access(&mask,0x20044);
589 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
591 if((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
592 return NT_STATUS_NO_MEMORY;
594 if((psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, &sd_size)) == NULL)
595 return NT_STATUS_NO_MEMORY;
597 if((*buf = make_sec_desc_buf(ctx, sd_size, psd)) == NULL)
598 return NT_STATUS_NO_MEMORY;
600 return NT_STATUS_NOPROBLEMO;
603 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid)
605 struct samr_info *info = NULL;
607 /* find the policy handle. open a policy on it. */
608 if (!find_policy_by_hnd(p, pol, (void **)&info))
618 /*******************************************************************
620 ********************************************************************/
622 uint32 _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
626 r_u->status = NT_STATUS_NOPROBLEMO;
630 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid))
631 return NT_STATUS_INVALID_HANDLE;
633 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &r_u->buf, &pol_sid);
635 if (r_u->status == NT_STATUS_NOPROBLEMO)
641 /*******************************************************************
642 makes a SAM_ENTRY / UNISTR2* structure from a user list.
643 ********************************************************************/
645 static void make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
646 uint32 num_sam_entries, SAM_USER_INFO_21 *pass)
655 if (num_sam_entries == 0)
658 sam = (SAM_ENTRY *)talloc(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
660 uni_name = (UNISTR2 *)talloc(ctx, sizeof(UNISTR2)*num_sam_entries);
662 if (sam == NULL || uni_name == NULL) {
663 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
667 for (i = 0; i < num_sam_entries; i++) {
668 int len = pass[i].uni_user_name.uni_str_len;
670 init_sam_entry(&sam[i], len, pass[i].user_rid);
671 copy_unistr2(&uni_name[i], &pass[i].uni_user_name);
675 *uni_name_pp = uni_name;
678 /*******************************************************************
679 samr_reply_enum_dom_users
680 ********************************************************************/
682 uint32 _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_ENUM_DOM_USERS *r_u)
684 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
686 int total_entries = 0;
689 r_u->status = NT_STATUS_NOPROBLEMO;
691 /* find the policy handle. open a policy on it. */
692 if (!find_policy_by_hnd(p, &q_u->pol, NULL))
693 return NT_STATUS_INVALID_HANDLE;
695 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
698 ret = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
699 MAX_SAM_ENTRIES, q_u->acb_mask);
703 return NT_STATUS_ACCESS_DENIED;
705 samr_clear_passwd_fields(pass, num_entries);
708 * Note from JRA. total_entries is not being used here. Currently if there is a
709 * large user base then it looks like NT will enumerate until get_sampwd_entries
710 * returns False due to num_entries being zero. This will cause an access denied
711 * return. I don't think this is right and needs further investigation. Note that
712 * this is also the same in the TNG code (I don't think that has been tested with
713 * a very large user list as MAX_SAM_ENTRIES is set to 600).
715 * I also think that one of the 'num_entries' return parameters is probably
716 * the "max entries" parameter - but in the TNG code they're all currently set to the same
717 * value (again I think this is wrong).
720 make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name, num_entries, pass);
722 init_samr_r_enum_dom_users(r_u, q_u->start_idx + num_entries, num_entries);
724 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
729 /*******************************************************************
730 makes a SAM_ENTRY / UNISTR2* structure from a group list.
731 ********************************************************************/
733 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
734 uint32 num_sam_entries, DOMAIN_GRP *grp)
743 if (num_sam_entries == 0)
746 sam = (SAM_ENTRY *)talloc(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
748 uni_name = (UNISTR2 *)talloc(ctx, sizeof(UNISTR2)*num_sam_entries);
750 if (sam == NULL || uni_name == NULL) {
751 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
755 for (i = 0; i < num_sam_entries; i++) {
757 * JRA. I think this should include the null. TNG does not.
759 int len = strlen(grp[i].name)+1;
761 init_sam_entry(&sam[i], len, grp[i].rid);
762 init_unistr2(&uni_name[i], grp[i].name, len);
766 *uni_name_pp = uni_name;
769 /*******************************************************************
770 Get the group entries - similar to get_sampwd_entries().
771 ********************************************************************/
773 static BOOL get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
774 uint32 *p_num_entries, uint32 max_entries)
777 uint32 num_entries = 0;
782 sid_to_string(sid_str, sid);
783 DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str));
787 /* well-known aliases */
788 if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
790 enum_group_mapping(SID_NAME_WKN_GRP, &map, &num_entries, ENUM_ONLY_MAPPED);
792 *d_grp=(DOMAIN_GRP *)talloc(ctx, num_entries*sizeof(DOMAIN_GRP));
794 return NT_STATUS_NO_MEMORY;
796 for(i=0; i<num_entries && i<max_entries; i++) {
797 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
798 sid_split_rid(&map[i].sid, &(*d_grp)[i].rid);
804 } else if (sid_equal(sid, &global_sam_sid) && !lp_hide_local_users()) {
806 struct sys_grent *glist;
807 struct sys_grent *grp;
809 sep = lp_winbind_separator();
812 /* we return the UNIX groups here. This seems to be the right */
813 /* thing to do, since NT member servers return their local */
814 /* groups in the same situation. */
816 /* use getgrent_list() to retrieve the list of groups to avoid
817 * problems with getgrent possible infinite loop by internal
818 * libc grent structures overwrites by called functions */
819 grp = glist = getgrent_list();
821 return NT_STATUS_NO_MEMORY;
823 for (; (num_entries < max_entries) && (grp != NULL); grp = grp->next) {
826 if(!get_group_from_gid(grp->gr_gid, &smap)) {
830 if (smap.sid_name_use!=SID_NAME_ALIAS) {
834 sid_split_rid(&smap.sid, &trid);
836 /* Don't return winbind groups as they are not local! */
837 if (strchr(smap.nt_name, *sep) != NULL) {
838 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
842 /* Don't return user private groups... */
843 if (Get_Pwnam(smap.nt_name, False) != 0) {
844 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
848 for( i = 0; i < num_entries; i++)
849 if ( (*d_grp)[i].rid == trid )
852 if ( i < num_entries )
853 continue; /* rid was there, dup! */
855 /* JRA - added this for large group db enumeration... */
858 /* skip the requested number of entries.
859 not very efficient, but hey...
865 *d_grp=talloc_realloc(ctx,*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
868 return NT_STATUS_NO_MEMORY;
871 fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
872 (*d_grp)[num_entries].rid = trid;
879 *p_num_entries = num_entries;
884 /*******************************************************************
885 Get the group entries - similar to get_sampwd_entries().
886 ********************************************************************/
888 static BOOL get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
889 uint32 *p_num_entries, uint32 max_entries)
893 uint32 num_entries = 0;
897 enum_group_mapping(SID_NAME_DOM_GRP, &map, &num_entries, ENUM_ONLY_MAPPED);
899 *d_grp=(DOMAIN_GRP *)talloc(ctx, num_entries*sizeof(DOMAIN_GRP));
903 for (i=0; i<num_entries; i++) {
904 fstrcpy((*d_grp)[i].name, map[i].nt_name);
905 fstrcpy((*d_grp)[i].comment, map[i].comment);
906 sid_split_rid(&map[i].sid, &(*d_grp)[i].rid);
907 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
912 *p_num_entries = num_entries;
917 /*******************************************************************
918 samr_reply_enum_dom_groups
919 Only reply with one group - domain admins. This must be fixed for
921 ********************************************************************/
923 uint32 _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
925 DOMAIN_GRP *grp=NULL;
929 r_u->status = NT_STATUS_NOPROBLEMO;
931 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
932 return NT_STATUS_INVALID_HANDLE;
934 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
936 /* the domain group array is being allocated in the function below */
937 get_group_domain_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES);
939 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
943 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
945 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
951 /*******************************************************************
952 samr_reply_enum_dom_aliases
953 ********************************************************************/
955 uint32 _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
957 DOMAIN_GRP *grp=NULL;
958 uint32 num_entries = 0;
962 r_u->status = NT_STATUS_NOPROBLEMO;
964 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
965 return NT_STATUS_INVALID_HANDLE;
967 sid_to_string(sid_str, &sid);
968 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
970 if (!get_group_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES))
971 return NT_STATUS_ACCESS_DENIED;
973 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
977 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx, num_entries);
979 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
984 /*******************************************************************
985 samr_reply_query_dispinfo
986 ********************************************************************/
988 uint32 _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_QUERY_DISPINFO *r_u)
990 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
991 DOMAIN_GRP *grps=NULL;
992 uint16 acb_mask = ACB_NORMAL;
993 uint32 num_entries = 0;
994 int orig_num_entries = 0;
995 int total_entries = 0;
996 uint32 data_size = 0;
999 SAM_DISPINFO_CTR *ctr;
1001 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1003 r_u->status = NT_STATUS_NOPROBLEMO;
1005 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid))
1006 return NT_STATUS_INVALID_HANDLE;
1008 /* decide how many entries to get depending on the max_entries
1009 and max_size passed by client */
1011 if(q_u->max_entries > MAX_SAM_ENTRIES)
1012 q_u->max_entries = MAX_SAM_ENTRIES;
1014 /* Get what we need from the password database */
1015 switch (q_u->switch_level) {
1017 acb_mask = ACB_WSTRUST;
1023 ret = get_passwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
1024 MAX_SAM_ENTRIES, acb_mask);
1028 * Which should we use here ? JRA.
1030 ret = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
1031 MAX_SAM_ENTRIES, acb_mask);
1034 ret = jf_get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
1035 MAX_SAM_ENTRIES, acb_mask);
1039 DEBUG(5, ("get_sampwd_entries: failed\n"));
1040 return NT_STATUS_ACCESS_DENIED;
1045 ret = get_group_domain_entries(p->mem_ctx, &grps, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES);
1047 return NT_STATUS_ACCESS_DENIED;
1050 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1051 return NT_STATUS_INVALID_INFO_CLASS;
1055 if (num_entries > q_u->max_entries)
1056 num_entries = q_u->max_entries;
1058 if (num_entries > MAX_SAM_ENTRIES) {
1059 num_entries = MAX_SAM_ENTRIES;
1060 DEBUG(5, ("limiting number of entries to %d\n", num_entries));
1063 /* Ensure password info is never given out here. PARANOIA... JRA */
1064 samr_clear_passwd_fields(pass, num_entries);
1066 data_size = q_u->max_size;
1067 orig_num_entries = num_entries;
1069 if (!(ctr = (SAM_DISPINFO_CTR *)talloc(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1070 return NT_STATUS_NO_MEMORY;
1072 /* Now create reply structure */
1073 switch (q_u->switch_level) {
1075 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc(p->mem_ctx,sizeof(SAM_DISPINFO_1))))
1076 return NT_STATUS_NO_MEMORY;
1077 init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, &num_entries, &data_size, q_u->start_idx, pass);
1080 if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc(p->mem_ctx,sizeof(SAM_DISPINFO_2))))
1081 return NT_STATUS_NO_MEMORY;
1082 init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, &num_entries, &data_size, q_u->start_idx, pass);
1085 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc(p->mem_ctx,sizeof(SAM_DISPINFO_3))))
1086 return NT_STATUS_NO_MEMORY;
1087 init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, &num_entries, &data_size, q_u->start_idx, grps);
1091 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc(p->mem_ctx,sizeof(SAM_DISPINFO_4))))
1092 return NT_STATUS_NO_MEMORY;
1093 init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, &num_entries, &data_size, q_u->start_idx, pass);
1096 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc(p->mem_ctx,sizeof(SAM_DISPINFO_5))))
1097 return NT_STATUS_NO_MEMORY;
1098 init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, &num_entries, &data_size, q_u->start_idx, grps);
1102 ctr->sam.info = NULL;
1103 return NT_STATUS_INVALID_INFO_CLASS;
1106 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1108 init_samr_r_query_dispinfo(r_u, num_entries, data_size, q_u->switch_level, ctr, r_u->status);
1110 if (num_entries < orig_num_entries) {
1111 return STATUS_MORE_ENTRIES;
1117 /*******************************************************************
1118 samr_reply_query_aliasinfo
1119 ********************************************************************/
1121 uint32 _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1123 fstring alias_desc = "Local Unix group";
1125 enum SID_NAME_USE type;
1127 struct samr_info *info = NULL;
1129 r_u->status = NT_STATUS_NOPROBLEMO;
1131 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1133 /* find the policy handle. open a policy on it. */
1134 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1135 return NT_STATUS_INVALID_HANDLE;
1137 alias_rid = get_lsa_policy_samr_rid(info);
1138 if(alias_rid == 0xffffffff)
1139 return NT_STATUS_NO_SUCH_ALIAS;
1141 if(!local_lookup_rid(alias_rid, alias, &type))
1142 return NT_STATUS_NO_SUCH_ALIAS;
1144 switch (q_u->switch_level) {
1147 r_u->ctr.switch_value1 = 3;
1148 init_samr_alias_info3(&r_u->ctr.alias.info3, alias_desc);
1151 return NT_STATUS_INVALID_INFO_CLASS;
1154 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1160 /*******************************************************************
1161 samr_reply_lookup_ids
1162 ********************************************************************/
1164 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1166 uint32 rid[MAX_SAM_ENTRIES];
1167 int num_rids = q_u->num_sids1;
1169 r_u->status = NT_STATUS_NOPROBLEMO;
1171 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1173 if (num_rids > MAX_SAM_ENTRIES) {
1174 num_rids = MAX_SAM_ENTRIES;
1175 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1180 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1182 for (i = 0; i < num_rids && status == 0; i++)
1184 struct sam_passwd *sam_pass;
1188 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1189 q_u->uni_user_name[i].uni_str_len));
1191 /* find the user account */
1193 sam_pass = get_smb21pwd_entry(user_name, 0);
1196 if (sam_pass == NULL)
1198 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1203 rid[i] = sam_pass->user_rid;
1209 rid[0] = BUILTIN_ALIAS_RID_USERS;
1211 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_NOPROBLEMO);
1213 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1219 /*******************************************************************
1221 ********************************************************************/
1223 uint32 _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1225 uint32 rid[MAX_SAM_ENTRIES];
1226 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1228 int num_rids = q_u->num_names2;
1231 r_u->status = NT_STATUS_NOPROBLEMO;
1233 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1238 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid)) {
1239 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1243 if (num_rids > MAX_SAM_ENTRIES) {
1244 num_rids = MAX_SAM_ENTRIES;
1245 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1248 for (i = 0; i < num_rids; i++) {
1251 r_u->status = NT_STATUS_NONE_MAPPED;
1253 rid [i] = 0xffffffff;
1254 type[i] = SID_NAME_UNKNOWN;
1256 rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1258 if(sid_equal(&pol_sid, &global_sam_sid)) {
1260 if(local_lookup_name(global_myname, name, &sid, &type[i])) {
1261 sid_split_rid( &sid, &rid[i]);
1262 r_u->status = NT_STATUS_NOPROBLEMO;
1267 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1269 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1274 /*******************************************************************
1275 _samr_chgpasswd_user
1276 ********************************************************************/
1278 uint32 _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1283 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1285 r_u->status = NT_STATUS_NOPROBLEMO;
1287 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1288 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len,0);
1290 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1293 * Pass the user through the NT -> unix user mapping
1297 (void)map_username(user_name);
1300 * Do any UNIX username case mangling.
1302 (void)Get_Pwnam( user_name, True);
1304 if (!pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1305 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1306 r_u->status = NT_STATUS_WRONG_PASSWORD;
1308 init_samr_r_chgpasswd_user(r_u, r_u->status);
1310 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1315 /*******************************************************************
1316 makes a SAMR_R_LOOKUP_RIDS structure.
1317 ********************************************************************/
1319 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1320 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1323 UNIHDR *hdr_name=NULL;
1324 UNISTR2 *uni_name=NULL;
1326 *pp_uni_name = NULL;
1327 *pp_hdr_name = NULL;
1329 if (num_names != 0) {
1330 hdr_name = (UNIHDR *)talloc(ctx, sizeof(UNIHDR)*num_names);
1331 if (hdr_name == NULL)
1334 uni_name = (UNISTR2 *)talloc(ctx,sizeof(UNISTR2)*num_names);
1335 if (uni_name == NULL)
1339 for (i = 0; i < num_names; i++) {
1340 int len = names[i] != NULL ? strlen(names[i]) : 0;
1341 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1342 init_uni_hdr(&hdr_name[i], len);
1343 init_unistr2(&uni_name[i], names[i], len);
1346 *pp_uni_name = uni_name;
1347 *pp_hdr_name = hdr_name;
1352 /*******************************************************************
1354 ********************************************************************/
1356 uint32 _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1358 fstring group_names[MAX_SAM_ENTRIES];
1359 uint32 group_attrs[MAX_SAM_ENTRIES];
1360 UNIHDR *hdr_name = NULL;
1361 UNISTR2 *uni_name = NULL;
1363 int num_rids = q_u->num_rids1;
1366 r_u->status = NT_STATUS_NOPROBLEMO;
1368 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1370 /* find the policy handle. open a policy on it. */
1371 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid))
1372 return NT_STATUS_INVALID_HANDLE;
1374 if (num_rids > MAX_SAM_ENTRIES) {
1375 num_rids = MAX_SAM_ENTRIES;
1376 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1379 r_u->status = NT_STATUS_NONE_MAPPED;
1381 for (i = 0; i < num_rids; i++) {
1385 enum SID_NAME_USE type;
1387 group_attrs[i] = SID_NAME_UNKNOWN;
1388 *group_names[i] = '\0';
1390 if (sid_equal(&pol_sid, &global_sam_sid)) {
1391 sid_copy(&sid, &pol_sid);
1392 sid_append_rid(&sid, q_u->rid[i]);
1394 if (lookup_sid(&sid, domname, tmpname, &type)) {
1395 r_u->status = NT_STATUS_NOPROBLEMO;
1396 group_attrs[i] = (uint32)type;
1397 fstrcpy(group_names[i],tmpname);
1402 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1403 return NT_STATUS_NO_MEMORY;
1405 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1407 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1412 /*******************************************************************
1413 _api_samr_open_user. Safe - gives out no passwd info.
1414 ********************************************************************/
1416 uint32 _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1418 SAM_ACCOUNT *sampass=NULL;
1420 POLICY_HND domain_pol = q_u->domain_pol;
1421 uint32 user_rid = q_u->user_rid;
1422 POLICY_HND *user_pol = &r_u->user_pol;
1423 struct samr_info *info = NULL;
1426 r_u->status = NT_STATUS_NO_PROBLEMO;
1428 /* find the domain policy handle. */
1429 if (!find_policy_by_hnd(p, &domain_pol, NULL))
1430 return NT_STATUS_INVALID_HANDLE;
1432 pdb_init_sam(&sampass);
1435 ret=pdb_getsampwrid(sampass, user_rid);
1438 /* check that the RID exists in our domain. */
1440 pdb_free_sam(sampass);
1441 return NT_STATUS_NO_SUCH_USER;
1444 samr_clear_sam_passwd(sampass);
1445 pdb_free_sam(sampass);
1447 /* Get the domain SID stored in the domain policy */
1448 if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
1449 return NT_STATUS_INVALID_HANDLE;
1451 /* append the user's RID to it */
1452 if(!sid_append_rid(&sid, user_rid))
1453 return NT_STATUS_NO_SUCH_USER;
1455 /* associate the user's SID with the new handle. */
1456 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
1457 return NT_STATUS_NO_MEMORY;
1462 /* get a (unique) handle. open a policy on it. */
1463 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1464 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1469 /*************************************************************************
1470 get_user_info_10. Safe. Only gives out acb bits.
1471 *************************************************************************/
1473 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1475 SAM_ACCOUNT *smbpass=NULL;
1478 if (!pdb_rid_is_user(user_rid)) {
1479 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1483 pdb_init_sam(&smbpass);
1486 ret = pdb_getsampwrid(smbpass, user_rid);
1490 DEBUG(4,("User 0x%x not found\n", user_rid));
1491 pdb_free_sam(smbpass);
1495 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1497 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1499 samr_clear_sam_passwd(smbpass);
1500 pdb_free_sam(smbpass);
1505 /*************************************************************************
1506 get_user_info_12. OK - this is the killer as it gives out password info.
1507 Ensure that this is only allowed on an encrypted connection with a root
1509 *************************************************************************/
1511 static uint32 get_user_info_12(pipes_struct *p, SAM_USER_INFO_12 * id12, uint32 user_rid)
1513 SAM_ACCOUNT *smbpass=NULL;
1516 if (!p->ntlmssp_auth_validated)
1517 return NT_STATUS_ACCESS_DENIED;
1519 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1520 return NT_STATUS_ACCESS_DENIED;
1523 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1525 pdb_init_sam(&smbpass);
1527 ret = pdb_getsampwrid(smbpass, user_rid);
1530 DEBUG(4, ("User 0x%x not found\n", user_rid));
1531 pdb_free_sam(smbpass);
1532 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1535 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1537 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1538 pdb_free_sam(smbpass);
1539 return NT_STATUS_ACCOUNT_DISABLED;
1542 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1544 pdb_free_sam(smbpass);
1546 return NT_STATUS_NOPROBLEMO;
1549 /*************************************************************************
1551 *************************************************************************/
1553 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1555 SAM_ACCOUNT *sampass=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(&sampass);
1566 ret = pdb_getsampwrid(sampass, user_rid);
1570 DEBUG(4,("User 0x%x not found\n", user_rid));
1571 pdb_free_sam(sampass);
1575 samr_clear_sam_passwd(sampass);
1577 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1579 init_sam_user_info21A(id21, sampass);
1581 pdb_free_sam(sampass);
1586 /*******************************************************************
1587 _samr_query_userinfo
1588 ********************************************************************/
1590 uint32 _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1592 SAM_USERINFO_CTR *ctr;
1594 struct samr_info *info = NULL;
1596 r_u->status=NT_STATUS_NO_PROBLEMO;
1598 /* search for the handle */
1599 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1600 return NT_STATUS_INVALID_HANDLE;
1602 /* find the user's rid */
1603 if ((rid = get_lsa_policy_samr_rid(info)) == 0xffffffff)
1604 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1606 DEBUG(5,("_samr_query_userinfo: rid:0x%x\n", rid));
1608 ctr = (SAM_USERINFO_CTR *)talloc(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1610 return NT_STATUS_NO_MEMORY;
1614 /* ok! user info levels (lots: see MSDEV help), off we go... */
1615 ctr->switch_value = q_u->switch_value;
1617 switch (q_u->switch_value) {
1619 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1620 if (ctr->info.id10 == NULL)
1621 return NT_STATUS_NO_MEMORY;
1623 if (!get_user_info_10(ctr->info.id10, rid))
1624 return NT_STATUS_NO_SUCH_USER;
1628 /* whoops - got this wrong. i think. or don't understand what's happening. */
1632 info = (void *)&id11;
1634 expire.low = 0xffffffff;
1635 expire.high = 0x7fffffff;
1637 ctr->info.id = (SAM_USER_INFO_11 *)talloc(p->mem_ctx,
1642 init_sam_user_info11(ctr->info.id11, &expire,
1643 "BROOKFIELDS$", /* name */
1644 0x03ef, /* user rid */
1645 0x201, /* group rid */
1646 0x0080); /* acb info */
1653 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1654 if (ctr->info.id12 == NULL)
1655 return NT_STATUS_NO_MEMORY;
1657 if ((r_u->status = get_user_info_12(p, ctr->info.id12, rid)) != NT_STATUS_NOPROBLEMO)
1662 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1663 if (ctr->info.id21 == NULL)
1664 return NT_STATUS_NO_MEMORY;
1665 if (!get_user_info_21(ctr->info.id21, rid))
1666 return NT_STATUS_NO_SUCH_USER;
1670 return NT_STATUS_INVALID_INFO_CLASS;
1673 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1675 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1680 /*******************************************************************
1681 samr_reply_query_usergroups
1682 ********************************************************************/
1684 uint32 _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1686 struct sam_passwd *sam_pass=NULL;
1687 DOM_GID *gids = NULL;
1691 struct samr_info *info = NULL;
1694 r_u->status = NT_STATUS_NO_PROBLEMO;
1696 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1698 /* find the policy handle. open a policy on it. */
1699 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1700 return NT_STATUS_INVALID_HANDLE;
1702 /* find the user's rid */
1703 if ((rid = get_lsa_policy_samr_rid(info)) == 0xffffffff)
1704 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1706 pdb_init_sam(&sam_pass);
1709 ret = pdb_getsampwrid(sam_pass, rid);
1713 samr_clear_sam_passwd(sam_pass);
1714 return NT_STATUS_NO_SUCH_USER;
1717 get_domain_user_groups(groups, pdb_get_username(sam_pass));
1719 num_groups = make_dom_gids(p->mem_ctx, groups, &gids);
1721 /* construct the response. lkclXXXX: gids are not copied! */
1722 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
1724 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1726 samr_clear_sam_passwd(sam_pass);
1731 /*******************************************************************
1732 _samr_query_dom_info
1733 ********************************************************************/
1735 uint32 _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
1739 if ((ctr = (SAM_UNK_CTR *)talloc(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
1740 return NT_STATUS_NO_MEMORY;
1744 r_u->status = NT_STATUS_NO_PROBLEMO;
1746 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
1748 /* find the policy handle. open a policy on it. */
1749 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
1750 return NT_STATUS_INVALID_HANDLE;
1752 switch (q_u->switch_value) {
1754 init_unk_info1(&ctr->info.inf1);
1757 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
1758 init_unk_info2(&ctr->info.inf2, global_myworkgroup, global_myname, (uint32) time(NULL));
1761 init_unk_info3(&ctr->info.inf3);
1764 init_unk_info6(&ctr->info.inf6);
1767 init_unk_info7(&ctr->info.inf7);
1770 init_unk_info12(&ctr->info.inf12);
1773 return NT_STATUS_INVALID_INFO_CLASS;
1776 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_NOPROBLEMO);
1778 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
1783 /*******************************************************************
1784 _api_samr_create_user
1785 ********************************************************************/
1787 uint32 _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
1789 SAM_ACCOUNT *sam_pass=NULL;
1796 POLICY_HND dom_pol = q_u->domain_pol;
1797 UNISTR2 user_account = q_u->uni_name;
1798 uint16 acb_info = q_u->acb_info;
1799 POLICY_HND *user_pol = &r_u->user_pol;
1800 struct samr_info *info = NULL;
1803 /* find the policy handle. open a policy on it. */
1804 if (!find_policy_by_hnd(p, &dom_pol, NULL))
1805 return NT_STATUS_INVALID_HANDLE;
1807 /* find the machine account: tell the caller if it exists.
1808 lkclXXXX i have *no* idea if this is a problem or not
1809 or even if you are supposed to construct a different
1810 reply if the account already exists...
1813 rpcstr_pull(mach_acct, user_account.buffer, sizeof(mach_acct), user_account.uni_str_len*2, 0);
1814 strlower(mach_acct);
1816 pdb_init_sam(&sam_pass);
1819 ret = pdb_getsampwnam(sam_pass, mach_acct);
1822 /* machine account exists: say so */
1823 pdb_free_sam(sam_pass);
1824 return NT_STATUS_USER_EXISTS;
1827 local_flags=LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_SET_NO_PASSWORD;
1828 local_flags|= (acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0;
1831 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
1832 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
1833 * that only people with write access to the smbpasswd file will be able
1834 * to create a user. JRA.
1838 * add the user in the /etc/passwd file or the unix authority system.
1839 * We don't check if the smb_create_user() function succed or not for 2 reasons:
1840 * a) local_password_change() checks for us if the /etc/passwd account really exists
1841 * b) smb_create_user() would return an error if the account already exists
1842 * and as it could return an error also if it can't create the account, it would be tricky.
1844 * So we go the easy way, only check after if the account exists.
1845 * JFM (2/3/2001), to clear any possible bad understanding (-:
1848 pstrcpy(add_script, lp_adduser_script());
1851 smb_create_user(mach_acct, NULL);
1853 /* add the user in the smbpasswd file or the Samba authority database */
1854 if (!local_password_change(mach_acct, local_flags, NULL, err_str,
1855 sizeof(err_str), msg_str, sizeof(msg_str))) {
1856 DEBUG(0, ("%s\n", err_str));
1857 pdb_free_sam(sam_pass);
1858 return NT_STATUS_ACCESS_DENIED;
1862 ret = pdb_getsampwnam(sam_pass, mach_acct);
1865 /* account doesn't exist: say so */
1866 pdb_free_sam(sam_pass);
1867 return NT_STATUS_ACCESS_DENIED;
1870 /* Get the domain SID stored in the domain policy */
1871 if(!get_lsa_policy_samr_sid(p, &dom_pol, &sid)) {
1872 pdb_free_sam(sam_pass);
1873 return NT_STATUS_INVALID_HANDLE;
1876 /* append the user's RID to it */
1877 if(!sid_append_rid(&sid, pdb_get_user_rid(sam_pass) )) {
1878 pdb_free_sam(sam_pass);
1879 return NT_STATUS_NO_SUCH_USER;
1882 /* associate the user's SID with the new handle. */
1883 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL) {
1884 pdb_free_sam(sam_pass);
1885 return NT_STATUS_NO_MEMORY;
1891 /* get a (unique) handle. open a policy on it. */
1892 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
1893 pdb_free_sam(sam_pass);
1894 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1897 r_u->user_rid=sam_pass->user_rid;
1898 r_u->unknown_0 = 0x000703ff;
1900 pdb_free_sam(sam_pass);
1902 return NT_STATUS_NO_PROBLEMO;
1905 /*******************************************************************
1906 samr_reply_connect_anon
1907 ********************************************************************/
1909 uint32 _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
1911 struct samr_info *info = NULL;
1913 /* set up the SAMR connect_anon response */
1915 r_u->status = NT_STATUS_NO_PROBLEMO;
1917 /* associate the user's SID with the new handle. */
1918 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
1919 return NT_STATUS_NO_MEMORY;
1922 info->status = q_u->unknown_0;
1924 /* get a (unique) handle. open a policy on it. */
1925 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
1926 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1931 /*******************************************************************
1933 ********************************************************************/
1935 uint32 _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
1937 struct samr_info *info = NULL;
1939 DEBUG(5,("_samr_connect: %d\n", __LINE__));
1941 r_u->status = NT_STATUS_NO_PROBLEMO;
1943 /* associate the user's SID with the new handle. */
1944 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
1945 return NT_STATUS_NO_MEMORY;
1948 info->status = q_u->access_mask;
1950 /* get a (unique) handle. open a policy on it. */
1951 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
1952 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1954 DEBUG(5,("_samr_connect: %d\n", __LINE__));
1959 /**********************************************************************
1960 api_samr_lookup_domain
1961 **********************************************************************/
1963 uint32 _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
1965 r_u->status = NT_STATUS_NO_PROBLEMO;
1967 if (!find_policy_by_hnd(p, &q_u->connect_pol, NULL))
1968 return NT_STATUS_INVALID_HANDLE;
1970 /* assume the domain name sent is our global_myname and
1971 send global_sam_sid */
1972 init_samr_r_lookup_domain(r_u, &global_sam_sid, r_u->status);
1977 /******************************************************************
1978 makes a SAMR_R_ENUM_DOMAINS structure.
1979 ********************************************************************/
1981 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
1982 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
1988 DEBUG(5, ("make_enum_domains\n"));
1991 *pp_uni_name = NULL;
1993 if (num_sam_entries == 0)
1996 sam = (SAM_ENTRY *)talloc(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
1997 uni_name = (UNISTR2 *)talloc(ctx, sizeof(UNISTR2)*num_sam_entries);
1999 if (sam == NULL || uni_name == NULL)
2002 for (i = 0; i < num_sam_entries; i++) {
2003 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
2005 init_sam_entry(&sam[i], len, 0);
2006 init_unistr2(&uni_name[i], doms[i], len);
2010 *pp_uni_name = uni_name;
2015 /**********************************************************************
2016 api_samr_enum_domains
2017 **********************************************************************/
2019 uint32 _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2021 uint32 num_entries = 2;
2024 r_u->status = NT_STATUS_NO_PROBLEMO;
2026 fstrcpy(dom[0],global_myworkgroup);
2027 fstrcpy(dom[1],"Builtin");
2029 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2030 return NT_STATUS_NO_MEMORY;
2032 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2037 /*******************************************************************
2039 ********************************************************************/
2041 uint32 _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2044 POLICY_HND domain_pol = q_u->dom_pol;
2045 uint32 alias_rid = q_u->rid_alias;
2046 POLICY_HND *alias_pol = &r_u->pol;
2047 struct samr_info *info = NULL;
2049 r_u->status = NT_STATUS_NO_PROBLEMO;
2051 /* get the domain policy. */
2052 if (!find_policy_by_hnd(p, &domain_pol, NULL))
2053 return NT_STATUS_INVALID_HANDLE;
2055 /* Get the domain SID stored in the domain policy */
2056 if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
2057 return NT_STATUS_INVALID_HANDLE;
2059 /* append the alias' RID to it */
2060 if(!sid_append_rid(&sid, alias_rid))
2061 return NT_STATUS_NO_SUCH_USER;
2064 * we should check if the rid really exist !!!
2068 /* associate the user's SID with the new handle. */
2069 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
2070 return NT_STATUS_NO_MEMORY;
2075 /* get a (unique) handle. open a policy on it. */
2076 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2077 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2082 /*******************************************************************
2084 ********************************************************************/
2086 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid)
2088 SAM_ACCOUNT *pwd =NULL;
2093 ret = pdb_getsampwrid(pwd, rid);
2101 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2106 pdb_set_acct_ctrl(pwd, id10->acb_info);
2108 if(!pdb_update_sam_account(pwd, True)) {
2118 /*******************************************************************
2120 ********************************************************************/
2122 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, uint32 rid)
2124 SAM_ACCOUNT *pwd = NULL;
2128 if(!pdb_getsampwrid(pwd, rid)) {
2134 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2139 pdb_set_lanman_passwd (pwd, id12->lm_pwd);
2140 pdb_set_nt_passwd (pwd, id12->nt_pwd);
2142 if(!pdb_update_sam_account(pwd, True)) {
2151 /*******************************************************************
2153 ********************************************************************/
2155 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, uint32 rid)
2157 SAM_ACCOUNT *pwd = NULL;
2158 SAM_ACCOUNT *new_pwd = NULL;
2161 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2166 pdb_init_sam(&new_pwd);
2168 if (!pdb_getsampwrid(pwd, rid)) {
2170 pdb_free_sam(new_pwd);
2174 /* we make a copy so that we can modify stuff */
2175 copy_sam_passwd(new_pwd, pwd);
2176 copy_id21_to_sam_passwd(new_pwd, id21);
2179 * The funny part about the previous two calls is
2180 * that pwd still has the password hashes from the
2181 * passdb entry. These have not been updated from
2182 * id21. I don't know if they need to be set. --jerry
2185 /* write the change out */
2186 if(!pdb_update_sam_account(new_pwd, True)) {
2188 pdb_free_sam(new_pwd);
2193 pdb_free_sam(new_pwd);
2198 /*******************************************************************
2200 ********************************************************************/
2202 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
2204 SAM_ACCOUNT *pwd = NULL;
2205 SAM_ACCOUNT *new_pwd = NULL;
2213 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2218 pdb_init_sam(&new_pwd);
2220 if (!pdb_getsampwrid(pwd, rid)) {
2222 pdb_free_sam(new_pwd);
2226 acct_ctrl = pdb_get_acct_ctrl(pwd);
2228 copy_sam_passwd(new_pwd, pwd);
2231 copy_id23_to_sam_passwd(new_pwd, id23);
2233 if (!decode_pw_buffer((char*)id23->pass, buf, 256, &len, nt_hash, lm_hash)) {
2234 pdb_free_sam(new_pwd);
2238 pdb_set_lanman_passwd (new_pwd, lm_hash);
2239 pdb_set_nt_passwd (new_pwd, nt_hash);
2241 /* if it's a trust account, don't update /etc/passwd */
2242 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2243 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2244 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2245 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2247 /* update the UNIX password */
2248 if (lp_unix_password_sync() )
2249 if(!chgpasswd(pdb_get_username(new_pwd), "", buf, True)) {
2250 pdb_free_sam(new_pwd);
2255 memset(buf, 0, sizeof(buf));
2257 if(!pdb_update_sam_account(new_pwd, True)) {
2258 pdb_free_sam(new_pwd);
2262 pdb_free_sam(new_pwd);
2267 /*******************************************************************
2269 ********************************************************************/
2271 static BOOL set_user_info_pw(char *pass, uint32 rid)
2273 SAM_ACCOUNT *pwd = NULL;
2282 if (!pdb_getsampwrid(pwd, rid)) {
2287 acct_ctrl = pdb_get_acct_ctrl(pwd);
2289 memset(buf, 0, sizeof(buf));
2291 if (!decode_pw_buffer(pass, buf, 256, &len, nt_hash, lm_hash)) {
2296 pdb_set_lanman_passwd (pwd, lm_hash);
2297 pdb_set_nt_passwd (pwd, nt_hash);
2299 /* if it's a trust account, don't update /etc/passwd */
2300 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2301 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2302 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2303 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2305 /* update the UNIX password */
2306 if (lp_unix_password_sync())
2307 if(!chgpasswd(pdb_get_username(pwd), "", buf, True)) {
2313 memset(buf, 0, sizeof(buf));
2315 DEBUG(5,("set_user_info_pw: pdb_update_sam_account()\n"));
2317 /* update the SAMBA password */
2318 if(!pdb_update_sam_account(pwd, True)) {
2328 /*******************************************************************
2329 samr_reply_set_userinfo
2330 ********************************************************************/
2332 uint32 _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2336 struct current_user user;
2337 SAM_ACCOUNT *sam_pass=NULL;
2338 unsigned char sess_key[16];
2339 POLICY_HND *pol = &q_u->pol;
2340 uint16 switch_value = q_u->switch_value;
2341 SAM_USERINFO_CTR *ctr = q_u->ctr;
2344 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2346 r_u->status = NT_STATUS_NOPROBLEMO;
2348 if (p->ntlmssp_auth_validated) {
2349 memcpy(&user, &p->pipe_user, sizeof(user));
2351 extern struct current_user current_user;
2352 memcpy(&user, ¤t_user, sizeof(user));
2355 /* find the policy handle. open a policy on it. */
2356 if (!get_lsa_policy_samr_sid(p, pol, &sid))
2357 return NT_STATUS_INVALID_HANDLE;
2359 sid_split_rid(&sid, &rid);
2361 DEBUG(5, ("_samr_set_userinfo: rid:0x%x, level:%d\n", rid, switch_value));
2364 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2365 return NT_STATUS_INVALID_INFO_CLASS;
2369 pdb_init_sam(&sam_pass);
2372 * We need the NT hash of the user who is changing the user's password.
2373 * This NT hash is used to generate a "user session key"
2374 * This "user session key" is in turn used to encrypt/decrypt the user's password.
2378 ret = pdb_getsampwuid(sam_pass, user.uid);
2381 DEBUG(0,("_samr_set_userinfo: Unable to get smbpasswd entry for uid %u\n", (unsigned int)user.uid ));
2382 pdb_free_sam(sam_pass);
2383 return NT_STATUS_ACCESS_DENIED;
2386 memset(sess_key, '\0', 16);
2387 mdfour(sess_key, pdb_get_nt_passwd(sam_pass), 16);
2389 pdb_free_sam(sam_pass);
2391 /* ok! user info levels (lots: see MSDEV help), off we go... */
2392 switch (switch_value) {
2394 if (!set_user_info_12(ctr->info.id12, rid))
2395 return NT_STATUS_ACCESS_DENIED;
2399 SamOEMhash(ctr->info.id24->pass, sess_key, 516);
2401 dump_data(100, (char *)ctr->info.id24->pass, 516);
2403 if (!set_user_info_pw(ctr->info.id24->pass, rid))
2404 return NT_STATUS_ACCESS_DENIED;
2410 * Currently we don't really know how to unmarshall
2411 * the level 25 struct, and the password encryption
2412 * is different. This is a placeholder for when we
2413 * do understand it. In the meantime just return INVALID
2414 * info level and W2K SP2 drops down to level 23... JRA.
2417 SamOEMhash(ctr->info.id25->pass, sess_key, 532);
2419 dump_data(100, (char *)ctr->info.id25->pass, 532);
2421 if (!set_user_info_pw(ctr->info.id25->pass, rid))
2422 return NT_STATUS_ACCESS_DENIED;
2425 return NT_STATUS_INVALID_INFO_CLASS;
2428 SamOEMhash(ctr->info.id23->pass, sess_key, 516);
2430 dump_data(100, (char *)ctr->info.id23->pass, 516);
2432 if (!set_user_info_23(ctr->info.id23, rid))
2433 return NT_STATUS_ACCESS_DENIED;
2437 return NT_STATUS_INVALID_INFO_CLASS;
2443 /*******************************************************************
2444 samr_reply_set_userinfo2
2445 ********************************************************************/
2447 uint32 _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
2451 SAM_USERINFO_CTR *ctr = q_u->ctr;
2452 POLICY_HND *pol = &q_u->pol;
2453 uint16 switch_value = q_u->switch_value;
2455 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
2457 r_u->status = NT_STATUS_NOPROBLEMO;
2459 /* find the policy handle. open a policy on it. */
2460 if (!get_lsa_policy_samr_sid(p, pol, &sid))
2461 return NT_STATUS_INVALID_HANDLE;
2463 sid_split_rid(&sid, &rid);
2465 DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid));
2468 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
2469 return NT_STATUS_INVALID_INFO_CLASS;
2472 switch_value=ctr->switch_value;
2474 /* ok! user info levels (lots: see MSDEV help), off we go... */
2475 switch (switch_value) {
2477 if (!set_user_info_21(ctr->info.id21, rid))
2478 return NT_STATUS_ACCESS_DENIED;
2481 if (!set_user_info_10(ctr->info.id10, rid))
2482 return NT_STATUS_ACCESS_DENIED;
2485 /* Used by AS/U JRA. */
2486 if (!set_user_info_12(ctr->info.id12, rid))
2487 return NT_STATUS_ACCESS_DENIED;
2490 return NT_STATUS_INVALID_INFO_CLASS;
2496 /*********************************************************************
2497 _samr_query_aliasmem
2498 *********************************************************************/
2500 uint32 _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
2506 rid=(uint32 *)talloc(p->mem_ctx, num_rids*sizeof(uint32));
2508 return NT_STATUS_NO_MEMORY;
2510 /* until i see a real useraliases query, we fack one up */
2512 rid[0] = BUILTIN_ALIAS_RID_USERS;
2514 init_samr_r_query_useraliases(r_u, num_rids, rid, NT_STATUS_NO_PROBLEMO);
2516 return NT_STATUS_NO_PROBLEMO;
2520 /*********************************************************************
2521 _samr_query_aliasmem
2522 *********************************************************************/
2524 uint32 _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
2536 fstring alias_sid_str;
2540 /* find the policy handle. open a policy on it. */
2541 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid))
2542 return NT_STATUS_INVALID_HANDLE;
2544 sid_copy(&als_sid, &alias_sid);
2545 sid_to_string(alias_sid_str, &alias_sid);
2546 sid_split_rid(&alias_sid, &alias_rid);
2548 DEBUG(10, ("sid is %s\n", alias_sid_str));
2550 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
2551 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
2552 if(!get_builtin_group_from_sid(als_sid, &map))
2553 return NT_STATUS_NO_SUCH_ALIAS;
2555 if (sid_equal(&alias_sid, &global_sam_sid)) {
2556 DEBUG(10, ("lookup on Server SID\n"));
2557 if(!get_local_group_from_sid(als_sid, &map))
2558 return NT_STATUS_NO_SUCH_ALIAS;
2562 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
2563 return NT_STATUS_NO_SUCH_ALIAS;
2565 DEBUG(10, ("sid is %s\n", alias_sid_str));
2566 sid = (DOM_SID2 *)talloc(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
2567 if (num_uids!=0 && sid == NULL)
2568 return NT_STATUS_NO_MEMORY;
2570 for (i = 0; i < num_uids; i++) {
2571 sid_copy(&temp_sid, &global_sam_sid);
2572 sid_append_rid(&temp_sid, pdb_uid_to_user_rid(uid[i]));
2574 init_dom_sid2(&sid[i], &temp_sid);
2577 DEBUG(10, ("sid is %s\n", alias_sid_str));
2578 init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_NO_PROBLEMO);
2580 return NT_STATUS_NOPROBLEMO;
2583 /*********************************************************************
2584 _samr_query_groupmem
2585 *********************************************************************/
2587 uint32 _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
2593 fstring group_sid_str;
2602 /* find the policy handle. open a policy on it. */
2603 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid))
2604 return NT_STATUS_INVALID_HANDLE;
2606 /* todo: change to use sid_compare_front */
2608 sid_split_rid(&group_sid, &group_rid);
2609 sid_to_string(group_sid_str, &group_sid);
2610 DEBUG(10, ("sid is %s\n", group_sid_str));
2612 /* can we get a query for an SID outside our domain ? */
2613 if (!sid_equal(&group_sid, &global_sam_sid))
2614 return NT_STATUS_NO_SUCH_GROUP;
2616 sid_append_rid(&group_sid, group_rid);
2617 DEBUG(10, ("lookup on Domain SID\n"));
2619 if(!get_domain_group_from_sid(group_sid, &map))
2620 return NT_STATUS_NO_SUCH_GROUP;
2622 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
2623 return NT_STATUS_NO_SUCH_GROUP;
2625 rid=talloc(p->mem_ctx, sizeof(uint32)*num_uids);
2626 attr=talloc(p->mem_ctx, sizeof(uint32)*num_uids);
2628 if (num_uids!=0 && (rid==NULL || attr==NULL))
2629 return NT_STATUS_NO_MEMORY;
2631 for (i=0; i<num_uids; i++) {
2632 rid[i]=pdb_uid_to_user_rid(uid[i]);
2633 attr[i] = SID_NAME_USER;
2636 init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_NOPROBLEMO);
2638 return NT_STATUS_NOPROBLEMO;
2641 /*********************************************************************
2643 *********************************************************************/
2645 uint32 _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
2648 fstring alias_sid_str;
2656 /* Find the policy handle. Open a policy on it. */
2657 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid))
2658 return NT_STATUS_INVALID_HANDLE;
2660 sid_to_string(alias_sid_str, &alias_sid);
2661 DEBUG(10, ("sid is %s\n", alias_sid_str));
2663 if (sid_compare(&alias_sid, &global_sam_sid)>0) {
2664 DEBUG(10, ("adding member on Server SID\n"));
2665 if(!get_local_group_from_sid(alias_sid, &map))
2666 return NT_STATUS_NO_SUCH_ALIAS;
2669 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
2670 DEBUG(10, ("adding member on BUILTIN SID\n"));
2671 if( !get_builtin_group_from_sid(alias_sid, &map))
2672 return NT_STATUS_NO_SUCH_ALIAS;
2675 return NT_STATUS_NO_SUCH_ALIAS;
2678 sid_split_rid(&q_u->sid.sid, &rid);
2679 uid=pdb_user_rid_to_uid(rid);
2681 if ((pwd=getpwuid(uid)) == NULL)
2682 return NT_STATUS_NO_SUCH_USER;
2684 if ((grp=getgrgid(map.gid)) == NULL)
2685 return NT_STATUS_NO_SUCH_ALIAS;
2687 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
2688 fstrcpy(grp_name, grp->gr_name);
2690 /* if the user is already in the group */
2691 if(user_in_group_list(pwd->pw_name, grp_name))
2692 return NT_STATUS_MEMBER_IN_ALIAS;
2695 * ok, the group exist, the user exist, the user is not in the group,
2696 * we can (finally) add it to the group !
2698 smb_add_user_group(grp_name, pwd->pw_name);
2700 /* check if the user has been added then ... */
2701 if(!user_in_group_list(pwd->pw_name, grp_name))
2702 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
2704 return NT_STATUS_NOPROBLEMO;
2707 /*********************************************************************
2709 *********************************************************************/
2711 uint32 _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
2713 DEBUG(0,("_samr_del_aliasmem: Not yet implemented.\n"));
2717 /*********************************************************************
2719 *********************************************************************/
2721 uint32 _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
2724 fstring group_sid_str;
2730 /* Find the policy handle. Open a policy on it. */
2731 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid))
2732 return NT_STATUS_INVALID_HANDLE;
2734 sid_to_string(group_sid_str, &group_sid);
2735 DEBUG(10, ("sid is %s\n", group_sid_str));
2737 if (sid_compare(&group_sid, &global_sam_sid)<=0)
2738 return NT_STATUS_NO_SUCH_GROUP;
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 ((pwd=getpwuid(pdb_user_rid_to_uid(q_u->rid))) ==NULL)
2746 return NT_STATUS_NO_SUCH_USER;
2748 if ((grp=getgrgid(map.gid)) == NULL)
2749 return NT_STATUS_NO_SUCH_GROUP;
2751 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
2752 fstrcpy(grp_name, grp->gr_name);
2754 /* if the user is already in the group */
2755 if(user_in_group_list(pwd->pw_name, grp_name))
2756 return NT_STATUS_MEMBER_IN_GROUP;
2759 * ok, the group exist, the user exist, the user is not in the group,
2761 * we can (finally) add it to the group !
2764 smb_add_user_group(grp_name, pwd->pw_name);
2766 /* check if the user has been added then ... */
2767 if(!user_in_group_list(pwd->pw_name, grp_name))
2768 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
2770 return NT_STATUS_NOPROBLEMO;
2773 /*********************************************************************
2775 *********************************************************************/
2777 uint32 _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
2779 DEBUG(0,("_samr_del_groupmem: Not yet implemented.\n"));
2783 /*********************************************************************
2784 _samr_delete_dom_user
2785 *********************************************************************/
2787 uint32 _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
2789 DEBUG(0,("_samr_delete_dom_user: Not yet implemented.\n"));
2793 /*********************************************************************
2794 _samr_delete_dom_group
2795 *********************************************************************/
2797 uint32 _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
2799 DEBUG(0,("_samr_delete_dom_group: Not yet implemented.\n"));
2803 /*********************************************************************
2804 _samr_delete_dom_alias
2805 *********************************************************************/
2807 uint32 _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
2809 DEBUG(0,("_samr_delete_dom_alias: Not yet implemented.\n"));
2813 /*********************************************************************
2814 _samr_create_dom_group
2815 *********************************************************************/
2817 uint32 _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
2824 struct samr_info *info;
2826 /* Find the policy handle. Open a policy on it. */
2827 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid))
2828 return NT_STATUS_INVALID_HANDLE;
2830 if (!sid_equal(&dom_sid, &global_sam_sid))
2831 return NT_STATUS_ACCESS_DENIED;
2833 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
2835 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
2837 /* check if group already exist */
2838 if ((grp=getgrnam(name)) != NULL)
2839 return NT_STATUS_GROUP_EXISTS;
2841 /* we can create the UNIX group */
2842 smb_create_group(name);
2844 /* check if the group has been successfully created */
2845 if ((grp=getgrnam(name)) == NULL)
2846 return NT_STATUS_ACCESS_DENIED;
2848 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
2850 /* add the group to the mapping table */
2851 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL, SE_PRIV_NONE))
2852 return NT_STATUS_ACCESS_DENIED;
2854 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
2855 return NT_STATUS_NO_MEMORY;
2859 sid_copy(&info_sid, &global_sam_sid);
2860 sid_append_rid(&info->sid, r_u->rid);
2861 sid_to_string(sid_string, &info->sid);
2863 /* get a (unique) handle. open a policy on it. */
2864 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
2865 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2867 return NT_STATUS_NOPROBLEMO;
2870 /*********************************************************************
2871 _samr_create_dom_alias
2872 *********************************************************************/
2874 uint32 _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
2880 struct samr_info *info;
2882 /* Find the policy handle. Open a policy on it. */
2883 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid))
2884 return NT_STATUS_INVALID_HANDLE;
2886 if (!sid_equal(&dom_sid, &global_sam_sid))
2887 return NT_STATUS_ACCESS_DENIED;
2889 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
2891 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
2893 /* check if group already exists */
2894 if ( (grp=getgrnam(name)) != NULL)
2895 return NT_STATUS_GROUP_EXISTS;
2897 /* we can create the UNIX group */
2898 smb_create_group(name);
2900 /* check if the group has been successfully created */
2901 if ((grp=getgrnam(name)) == NULL)
2902 return NT_STATUS_ACCESS_DENIED;
2904 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
2906 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
2907 return NT_STATUS_NO_MEMORY;
2911 sid_copy(&info->sid, &global_sam_sid);
2912 sid_append_rid(&info->sid, r_u->rid);
2913 sid_to_string(sid_string, &info->sid);
2915 /* add the group to the mapping table */
2916 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL, SE_PRIV_NONE))
2917 return NT_STATUS_ACCESS_DENIED;
2919 /* get a (unique) handle. open a policy on it. */
2920 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
2921 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2923 return NT_STATUS_NOPROBLEMO;
2926 /*********************************************************************
2927 _samr_query_groupinfo
2929 sends the name/comment pair of a domain group
2930 level 1 send also the number of users of that group
2931 *********************************************************************/
2933 uint32 _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
2939 GROUP_INFO_CTR *ctr;
2941 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid))
2942 return NT_STATUS_INVALID_HANDLE;
2944 if (!get_domain_group_from_sid(group_sid, &map))
2945 return NT_STATUS_INVALID_HANDLE;
2947 ctr=(GROUP_INFO_CTR *)talloc(p->mem_ctx, sizeof(GROUP_INFO_CTR));
2949 return NT_STATUS_NO_MEMORY;
2951 switch (q_u->switch_level) {
2953 ctr->switch_value1 = 1;
2954 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
2955 return NT_STATUS_NO_SUCH_GROUP;
2956 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
2960 ctr->switch_value1 = 4;
2961 init_samr_group_info4(&ctr->group.info4, map.comment);
2964 return NT_STATUS_INVALID_INFO_CLASS;
2967 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_NO_PROBLEMO);
2969 return NT_STATUS_NO_PROBLEMO;
2972 /*********************************************************************
2975 update a domain group's comment.
2976 *********************************************************************/
2978 uint32 _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
2982 GROUP_INFO_CTR *ctr;
2984 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid))
2985 return NT_STATUS_INVALID_HANDLE;
2987 if (!get_domain_group_from_sid(group_sid, &map))
2988 return NT_STATUS_NO_SUCH_GROUP;
2992 switch (ctr->switch_value1) {
2994 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
2997 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
3000 return NT_STATUS_INVALID_INFO_CLASS;
3003 if(!add_mapping_entry(&map, TDB_REPLACE))
3004 return NT_STATUS_NO_SUCH_GROUP;
3006 return NT_STATUS_NO_PROBLEMO;
3009 /*********************************************************************
3012 update a domain group's comment.
3013 *********************************************************************/
3015 uint32 _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
3019 ALIAS_INFO_CTR *ctr;
3021 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid))
3022 return NT_STATUS_INVALID_HANDLE;
3024 if (!get_local_group_from_sid(group_sid, &map))
3025 return NT_STATUS_NO_SUCH_GROUP;
3029 switch (ctr->switch_value1) {
3031 unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
3034 return NT_STATUS_INVALID_INFO_CLASS;
3037 if(!add_mapping_entry(&map, TDB_REPLACE))
3038 return NT_STATUS_NO_SUCH_GROUP;
3040 return NT_STATUS_NO_PROBLEMO;
3043 /*********************************************************************
3044 _samr_get_dom_pwinfo
3045 *********************************************************************/
3047 uint32 _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
3049 /* Actually, returning zeros here works quite well :-). */
3050 return NT_STATUS_NOPROBLEMO;
3053 /*********************************************************************
3055 *********************************************************************/
3057 uint32 _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
3061 struct samr_info *info;
3064 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid))
3065 return NT_STATUS_INVALID_HANDLE;
3067 /* this should not be hard-coded like this */
3068 if (!sid_equal(&sid, &global_sam_sid))
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, q_u->rid_group);
3078 sid_to_string(sid_string, &info->sid);
3080 DEBUG(10, ("Opening SID: %s\n", sid_string));
3082 /* check if that group really exists */
3083 if (!get_domain_group_from_sid(info->sid, &map))
3084 return NT_STATUS_NO_SUCH_USER;
3086 /* get a (unique) handle. open a policy on it. */
3087 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3088 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3090 return NT_STATUS_NO_PROBLEMO;
3093 /*********************************************************************
3095 *********************************************************************/
3097 uint32 _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
3099 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));